From a8c7022169c0dc22c641b30b56773fd595a57016 Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 11:13:53 -0400 Subject: [PATCH 01/12] interfaces --- src/coinbase/address.ts | 40 +++++++++++++++++- src/coinbase/address/external_address.ts | 25 ++++++++++- src/coinbase/address/wallet_address.ts | 54 +++++++++++++++++++++--- src/coinbase/asset.ts | 29 +++++++++---- src/coinbase/authenticator.ts | 10 ++++- src/coinbase/balance.ts | 8 +++- src/coinbase/balance_map.ts | 6 +-- src/coinbase/contract_event.ts | 19 ++++++++- src/coinbase/contract_invocation.ts | 29 ++++++++++++- src/coinbase/faucet_transaction.ts | 7 ++- src/coinbase/payload_signature.ts | 13 +++++- src/coinbase/server_signer.ts | 7 ++- src/coinbase/smart_contract.ts | 17 +++++++- src/coinbase/sponsored_send.ts | 16 ++++++- src/coinbase/staking_balance.ts | 16 +++++-- src/coinbase/staking_operation.ts | 13 +++++- src/coinbase/staking_reward.ts | 11 ++++- src/coinbase/trade.ts | 20 ++++++++- src/coinbase/transaction.ts | 13 +++++- src/coinbase/transfer.ts | 19 ++++++++- src/coinbase/validator.ts | 6 ++- src/coinbase/wallet.ts | 42 ++++++++++++++++-- src/coinbase/webhook.ts | 15 ++++++- 23 files changed, 387 insertions(+), 48 deletions(-) diff --git a/src/coinbase/address.ts b/src/coinbase/address.ts index 15ffc4ea..5065b6be 100644 --- a/src/coinbase/address.ts +++ b/src/coinbase/address.ts @@ -19,10 +19,48 @@ import { StakingReward } from "./staking_reward"; import { StakingBalance } from "./staking_balance"; import { Transaction } from "./transaction"; +export interface IAddress { + getNetworkId(): string; + getId(): string; + listBalances(): Promise; + getBalance(assetId: string): Promise; + listHistoricalBalances( + options: ListHistoricalBalancesOptions, + ): Promise; + listTransactions(options: ListTransactionsOptions): Promise; + stakingRewards( + assetId: string, + startTime: string, + endTime: string, + format: StakingRewardFormat, + ): Promise; + historicalStakingBalances( + assetId: string, + startTime: string, + endTime: string, + ): Promise; + stakeableBalance( + assetId: string, + mode: StakeOptionsMode, + options: { [key: string]: string }, + ): Promise; + unstakeableBalance( + assetId: string, + mode: StakeOptionsMode, + options: { [key: string]: string }, + ): Promise; + claimableBalance( + assetId: string, + mode: StakeOptionsMode, + options: { [key: string]: string }, + ): Promise; + faucet(assetId?: string): Promise; +} + /** * A representation of a blockchain address, which is a user-controlled account on a network. */ -export class Address { +export class Address implements IAddress { private static MAX_HISTORICAL_BALANCE = 1000; protected networkId: string; diff --git a/src/coinbase/address/external_address.ts b/src/coinbase/address/external_address.ts index 2b83d046..b7e5e2ec 100644 --- a/src/coinbase/address/external_address.ts +++ b/src/coinbase/address/external_address.ts @@ -1,16 +1,37 @@ -import { Address } from "../address"; +import { Address, IAddress } from "../address"; import { Amount, StakeOptionsMode } from "../types"; import { Coinbase } from "../coinbase"; import Decimal from "decimal.js"; import { Asset } from "../asset"; import { StakingOperation } from "../staking_operation"; +export interface IExternalAddress extends IAddress { + buildStakeOperation( + amount: Amount, + assetId: string, + mode: StakeOptionsMode, + options: { [key: string]: string }, + ): Promise; + buildUnstakeOperation( + amount: Amount, + assetId: string, + mode: StakeOptionsMode, + options: { [key: string]: string }, + ): Promise; + buildClaimStakeOperation( + amount: Amount, + assetId: string, + mode: StakeOptionsMode, + options: { [key: string]: string }, + ): Promise; +} + /** * A representation of a blockchain Address, which is a user-controlled account on a Network. Addresses are used to * send and receive Assets. An ExternalAddress is an Address that is not controlled by the developer, but is instead * controlled by the user. */ -export class ExternalAddress extends Address { +export class ExternalAddress extends Address implements IExternalAddress { /** * Builds a stake operation for the supplied asset. The stake operation * may take a few minutes to complete in the case when infrastructure is spun up. diff --git a/src/coinbase/address/wallet_address.ts b/src/coinbase/address/wallet_address.ts index 022f1c65..3a6e966a 100644 --- a/src/coinbase/address/wallet_address.ts +++ b/src/coinbase/address/wallet_address.ts @@ -1,12 +1,12 @@ import { Decimal } from "decimal.js"; import { ethers } from "ethers"; import { Address as AddressModel, SmartContractType } from "../../client"; -import { Address } from "../address"; +import { Address, IAddress } from "../address"; import { Asset } from "../asset"; import { Coinbase } from "../coinbase"; import { ArgumentError } from "../errors"; import { Trade } from "../trade"; -import { Transfer } from "../transfer"; +import { ITransfer, Transfer } from "../transfer"; import { ContractInvocation } from "../contract_invocation"; import { Amount, @@ -25,10 +25,52 @@ import { StakingOperation } from "../staking_operation"; import { PayloadSignature } from "../payload_signature"; import { SmartContract } from "../smart_contract"; +export interface IWalletAddress extends IAddress { + getWalletId(): string; + setKey(key: ethers.Wallet): void; + export(): string; + canSign(): boolean; + listTrades(): Promise; + listTransfers(): Promise; + createTransfer(options: CreateTransferOptions): Promise; + createTrade(options: CreateTradeOptions): Promise; + invokeContract(options: CreateContractInvocationOptions): Promise; + deployToken(options: CreateERC20Options): Promise; + deployNFT(options: CreateERC721Options): Promise; + deployMultiToken(options: CreateERC1155Options): Promise; + createStake( + amount: Amount, + assetId: string, + mode: StakeOptionsMode, + options: { [key: string]: string }, + timeoutSeconds: number, + intervalSeconds: number, + ): Promise; + createUnstake( + amount: Amount, + assetId: string, + mode: StakeOptionsMode, + options: { [key: string]: string }, + timeoutSeconds: number, + intervalSeconds: number, + ): Promise; + createClaimStake( + amount: Amount, + assetId: string, + mode: StakeOptionsMode, + options: { [key: string]: string }, + timeoutSeconds: number, + intervalSeconds: number, + ): Promise; + createPayloadSignature(payload: string): Promise; + getPayloadSignature(signatureId: string): Promise; + listPayloadSignatures(): Promise; +} + /** * A representation of a blockchain address, which is a wallet-controlled account on a network. */ -export class WalletAddress extends Address { +export class WalletAddress extends Address implements IWalletAddress { private model: AddressModel; private key?: ethers.Wallet; @@ -139,8 +181,8 @@ export class WalletAddress extends Address { * * @returns The list of transfers. */ - public async listTransfers(): Promise { - const transfers: Transfer[] = []; + public async listTransfers(): Promise { + const transfers: ITransfer[] = []; const queue: string[] = [""]; while (queue.length > 0) { @@ -186,7 +228,7 @@ export class WalletAddress extends Address { assetId, destination, gasless = false, - }: CreateTransferOptions): Promise { + }: CreateTransferOptions): Promise { if (!Coinbase.useServerSigner && !this.key) { throw new Error("Cannot transfer from address without private key loaded"); } diff --git a/src/coinbase/asset.ts b/src/coinbase/asset.ts index 18b41abb..5aea1959 100644 --- a/src/coinbase/asset.ts +++ b/src/coinbase/asset.ts @@ -4,8 +4,19 @@ import { Coinbase } from "./coinbase"; import { GWEI_DECIMALS } from "./constants"; import { ArgumentError } from "./errors"; +export interface IAsset { + networkId: string; + assetId: string; + contractAddress: string; + decimals: number; + primaryDenomination(): string; + toAtomicAmount(wholeAmount: Decimal): bigint; + fromAtomicAmount(atomicAmount: Decimal): Decimal; + getAssetId(): string; +} + /** A representation of an Asset. */ -export class Asset { +export class Asset implements IAsset { public readonly networkId: string; public readonly assetId: string; public readonly contractAddress: string; @@ -128,20 +139,20 @@ export class Asset { } /** - * Returns a string representation of the Asset. + * Returns the Asset ID. * - * @returns a string representation of the Asset + * @returns The Asset ID. */ - toString(): string { - return `Asset{ networkId: ${this.networkId}, assetId: ${this.assetId}, contractAddress: ${this.contractAddress}, decimals: ${this.decimals} }`; + getAssetId(): string { + return this.assetId; } /** - * Returns the Asset ID. + * Returns a string representation of the Asset. * - * @returns The Asset ID. + * @returns a string representation of the Asset */ - getAssetId(): string { - return this.assetId; + toString(): string { + return `Asset{ networkId: ${this.networkId}, assetId: ${this.assetId}, contractAddress: ${this.contractAddress}, decimals: ${this.decimals} }`; } } diff --git a/src/coinbase/authenticator.ts b/src/coinbase/authenticator.ts index 9a84ad40..2a5bb951 100644 --- a/src/coinbase/authenticator.ts +++ b/src/coinbase/authenticator.ts @@ -6,10 +6,18 @@ import { version } from "../../package.json"; const pemHeader = "-----BEGIN EC PRIVATE KEY-----"; const pemFooter = "-----END EC PRIVATE KEY-----"; +export interface IAuthenticator { + authenticateRequest( + config: InternalAxiosRequestConfig, + debugging?: boolean, + ): Promise; + buildJWT(url: string, method?: string): Promise; +} + /** * A class that builds JWTs for authenticating with the Coinbase Platform APIs. */ -export class CoinbaseAuthenticator { +export class CoinbaseAuthenticator implements IAuthenticator { private apiKey: string; private privateKey: string; diff --git a/src/coinbase/balance.ts b/src/coinbase/balance.ts index 3aac5e03..b984c442 100644 --- a/src/coinbase/balance.ts +++ b/src/coinbase/balance.ts @@ -2,8 +2,14 @@ import Decimal from "decimal.js"; import { Balance as BalanceModel } from "../client"; import { Asset } from "./asset"; +export interface IBalance { + amount: Decimal; + assetId: string; + asset?: Asset; +} + /** A representation of a balance. */ -export class Balance { +export class Balance implements IBalance { public readonly amount: Decimal; public readonly assetId: string; public readonly asset?: Asset; diff --git a/src/coinbase/balance_map.ts b/src/coinbase/balance_map.ts index 62931352..afa0859b 100644 --- a/src/coinbase/balance_map.ts +++ b/src/coinbase/balance_map.ts @@ -1,4 +1,4 @@ -import { Balance } from "./balance"; +import { Balance, IBalance } from "./balance"; import { Balance as BalanceModel } from "../client"; import { Decimal } from "decimal.js"; @@ -24,9 +24,9 @@ export class BalanceMap extends Map { /** * Adds a balance to the map. * - * @param {Balance} balance - The balance to add to the map. + * @param {IBalance} balance - The balance to add to the map. */ - public add(balance: Balance): void { + public add(balance: IBalance): void { if (!(balance instanceof Balance)) { throw new Error("balance must be a Balance"); } diff --git a/src/coinbase/contract_event.ts b/src/coinbase/contract_event.ts index 3f1a19d0..af133a97 100644 --- a/src/coinbase/contract_event.ts +++ b/src/coinbase/contract_event.ts @@ -1,8 +1,25 @@ import { ContractEvent as ContractEventModel } from "../client"; + +export interface IContractEvent { + networkId(): string; + protocolName(): string; + contractName(): string; + eventName(): string; + sig(): string; + fourBytes(): string; + contractAddress(): string; + blockTime(): Date; + blockHeight(): number; + txHash(): string; + txIndex(): number; + eventIndex(): number; + data(): string; +} + /** * A representation of a single contract event. */ -export class ContractEvent { +export class ContractEvent implements IContractEvent { private model: ContractEventModel; /** diff --git a/src/coinbase/contract_invocation.ts b/src/coinbase/contract_invocation.ts index 1f10b264..8d8eb838 100644 --- a/src/coinbase/contract_invocation.ts +++ b/src/coinbase/contract_invocation.ts @@ -7,11 +7,38 @@ import { ethers } from "ethers"; import { delay } from "./utils"; import { TimeoutError } from "./errors"; +export interface IContractInvocation { + getId(): string; + getNetworkId(): string; + getWalletId(): string; + getFromAddressId(): string; + getContractAddressId(): string; + getMethod(): string; + getArgs(): object; + getAbi(): object | undefined; + getAmount(): Decimal; + getTransactionHash(): string | undefined; + getRawTransaction(): ethers.Transaction; + sign(key: ethers.Wallet): Promise; + getStatus(): TransactionStatus | undefined; + getTransaction(): Transaction; + getTransactionLink(): string; + broadcast(): Promise; + wait({ + intervalSeconds, + timeoutSeconds, + }: { + intervalSeconds: number; + timeoutSeconds: number; + }): Promise; + reload(): Promise; +} + /** * A representation of a ContractInvocation, which calls a smart contract method * onchain. The fee is assumed to be paid in the native Asset of the Network. */ -export class ContractInvocation { +export class ContractInvocation implements IContractInvocation { private model: ContractInvocationModel; /** diff --git a/src/coinbase/faucet_transaction.ts b/src/coinbase/faucet_transaction.ts index b18b0b0b..1446a2a2 100644 --- a/src/coinbase/faucet_transaction.ts +++ b/src/coinbase/faucet_transaction.ts @@ -1,9 +1,14 @@ import { FaucetTransaction as FaucetTransactionModel } from "../client"; +export interface IFaucetTransaction { + getTransactionHash(): string; + getTransactionLink(): string; +} + /** * Represents a transaction from a faucet. */ -export class FaucetTransaction { +export class FaucetTransaction implements IFaucetTransaction { private model: FaucetTransactionModel; /** diff --git a/src/coinbase/payload_signature.ts b/src/coinbase/payload_signature.ts index 9556d045..94088ab2 100644 --- a/src/coinbase/payload_signature.ts +++ b/src/coinbase/payload_signature.ts @@ -4,10 +4,21 @@ import { delay } from "./utils"; import { TimeoutError } from "./errors"; import { Coinbase } from "./coinbase"; +export interface IPayloadSignature { + getId(): string; + getWalletId(): string; + getAddressId(): string; + getUnsignedPayload(): string; + getSignature(): string | undefined; + getStatus(): PayloadSignatureStatus | undefined; + isTerminalState(): boolean; + wait(): Promise; +} + /** * A representation of a Payload Signature. */ -export class PayloadSignature { +export class PayloadSignature implements IPayloadSignature { private model: PayloadSignatureModel; /** diff --git a/src/coinbase/server_signer.ts b/src/coinbase/server_signer.ts index d0e37824..cd0eb39a 100644 --- a/src/coinbase/server_signer.ts +++ b/src/coinbase/server_signer.ts @@ -1,10 +1,15 @@ import { Coinbase } from "./coinbase"; import { ServerSigner as ServerSignerModel } from "../client/api"; +export interface IServerSigner { + getId(): string; + getWallets(): string[] | undefined; +} + /** * A representation of a Server-Signer. Server-Signers are assigned to sign transactions for a Wallet. */ -export class ServerSigner { +export class ServerSigner implements IServerSigner { private model: ServerSignerModel; /** diff --git a/src/coinbase/smart_contract.ts b/src/coinbase/smart_contract.ts index fe124d9d..ecc44ef1 100644 --- a/src/coinbase/smart_contract.ts +++ b/src/coinbase/smart_contract.ts @@ -7,7 +7,7 @@ import { TokenContractOptions as TokenContractOptionsModel, NFTContractOptions as NFTContractOptionsModel, } from "../client/api"; -import { Transaction } from "./transaction"; +import { ITransaction, Transaction } from "./transaction"; import { SmartContractOptions, SmartContractType, @@ -21,10 +21,23 @@ import { delay } from "./utils"; import { TimeoutError } from "./errors"; import { ContractEvent } from "./contract_event"; +export interface ISmartContract { + getId(): string; + getNetworkId(): string; + getWalletId(): string; + getContractAddress(): string; + getDeployerAddress(): string; + getType(): SmartContractType; + getOptions(): SmartContractOptions; + getAbi(): object; + getTransaction(): ITransaction; + sign(key: ethers.Wallet): Promise; + broadcast(): Promise; +} /** * A representation of a SmartContract on the blockchain. */ -export class SmartContract { +export class SmartContract implements ISmartContract { private model: SmartContractModel; /** diff --git a/src/coinbase/sponsored_send.ts b/src/coinbase/sponsored_send.ts index 8b1c2b9a..e6deea57 100644 --- a/src/coinbase/sponsored_send.ts +++ b/src/coinbase/sponsored_send.ts @@ -2,10 +2,24 @@ import { ethers } from "ethers"; import { SponsoredSend as SponsoredSendModel } from "../client/api"; import { SponsoredSendStatus } from "./types"; +/** + * Interface representing a Sponsored Send. + */ +export interface ISponsoredSend { + getTypedDataHash(): string; + getSignature(): string | undefined; + sign(key: ethers.Wallet): Promise; + isSigned(): boolean; + getStatus(): SponsoredSendStatus | undefined; + isTerminalState(): boolean; + getTransactionHash(): string | undefined; + getTransactionLink(): string | undefined; +} + /** * A representation of an onchain Sponsored Send. */ -export class SponsoredSend { +export class SponsoredSend implements ISponsoredSend { private model: SponsoredSendModel; /** diff --git a/src/coinbase/staking_balance.ts b/src/coinbase/staking_balance.ts index e56367be..434044bb 100644 --- a/src/coinbase/staking_balance.ts +++ b/src/coinbase/staking_balance.ts @@ -1,11 +1,19 @@ import { StakingBalance as StakingBalanceModel } from "../client"; -import { Balance } from "./balance"; +import { Balance, IBalance } from "./balance"; import { Coinbase } from "./coinbase"; +export interface IStakingBalance { + bondedStake(): IBalance; + unbondedBalance(): IBalance; + participantType(): string; + date(): Date; + address(): string; +} + /** * A representation of the staking balance for a given asset on a specific date. */ -export class StakingBalance { +export class StakingBalance implements IStakingBalance { private model: StakingBalanceModel; /** @@ -69,7 +77,7 @@ export class StakingBalance { * * @returns The Balance. */ - public bondedStake(): Balance { + public bondedStake(): IBalance { return Balance.fromModel(this.model.bonded_stake); } @@ -78,7 +86,7 @@ export class StakingBalance { * * @returns The Balance. */ - public unbondedBalance(): Balance { + public unbondedBalance(): IBalance { return Balance.fromModel(this.model.unbonded_balance); } diff --git a/src/coinbase/staking_operation.ts b/src/coinbase/staking_operation.ts index 0954a58f..d3da20bf 100644 --- a/src/coinbase/staking_operation.ts +++ b/src/coinbase/staking_operation.ts @@ -7,11 +7,22 @@ import { Transaction } from "./transaction"; import { Coinbase } from "./coinbase"; import { delay } from "./utils"; +export interface IStakingOperation { + getID(): string; + getStatus(): StakingOperationStatusEnum; + getWalletID(): string | undefined; + getAddressID(): string; + getNetworkID(): string; + isTerminalState(): boolean; + isFailedState(): boolean; + isCompleteState(): boolean; +} + /** * A representation of a staking operation (stake, unstake, claim stake, etc.). It * may have multiple steps with some being transactions to sign, and others to wait. */ -export class StakingOperation { +export class StakingOperation implements IStakingOperation { private model: StakingOperationModel; private readonly transactions: Transaction[]; diff --git a/src/coinbase/staking_reward.ts b/src/coinbase/staking_reward.ts index db2e0800..9f144246 100644 --- a/src/coinbase/staking_reward.ts +++ b/src/coinbase/staking_reward.ts @@ -4,10 +4,19 @@ import { Coinbase } from "./coinbase"; import { Asset } from "./asset"; import { Amount, StakingRewardFormat } from "./types"; +export interface IStakingReward { + date(): Date; + amount(): Amount; + addressId(): string; + usdValue(): Amount; + conversionPrice(): Amount; + conversionTime(): Date; +} + /** * A representation of a staking reward earned on a network for a given asset. */ -export class StakingReward { +export class StakingReward implements IStakingReward { private model: StakingRewardModel; private asset: Asset; private readonly format: StakingRewardFormat; diff --git a/src/coinbase/trade.ts b/src/coinbase/trade.ts index e2833da9..606f02f2 100644 --- a/src/coinbase/trade.ts +++ b/src/coinbase/trade.ts @@ -7,11 +7,29 @@ import { Transaction } from "./transaction"; import { TransactionStatus } from "./types"; import { delay } from "./utils"; +export interface ITrade { + getId(): string; + getNetworkId(): string; + getWalletId(): string; + getAddressId(): string; + getFromAssetId(): string; + getFromAmount(): Decimal; + getToAssetId(): string; + getToAmount(): Decimal; + getTransaction(): Transaction; + getApproveTransaction(): Transaction | undefined; + sign(key: ethers.Wallet): Promise; + broadcast(): Promise; + getStatus(): TransactionStatus | undefined; + wait(options: { intervalSeconds: number; timeoutSeconds: number }): Promise; + reload(): Promise; +} + /** * A representation of a Trade, which trades an amount of an Asset to another Asset on a Network. * The fee is assumed to be paid in the native Asset of the Network. */ -export class Trade { +export class Trade implements ITrade { private model: CoinbaseTrade; private transaction?: Transaction; private approveTransaction?: Transaction; diff --git a/src/coinbase/transaction.ts b/src/coinbase/transaction.ts index d7c6d3e3..41076c21 100644 --- a/src/coinbase/transaction.ts +++ b/src/coinbase/transaction.ts @@ -3,10 +3,21 @@ import { Transaction as TransactionModel, EthereumTransaction } from "../client/ import { TransactionStatus } from "./types"; import { parseUnsignedPayload } from "./utils"; +export interface ITransaction { + getUnsignedPayload(): string; + getSignedPayload(): string | undefined; + getTransactionHash(): string | undefined; + getStatus(): TransactionStatus | undefined; + fromAddressId(): string; + toAddressId(): string | undefined; + blockHeight(): string | undefined; + blockHash(): string | undefined; + content(): EthereumTransaction | undefined; +} /** * A representation of an onchain Transaction. */ -export class Transaction { +export class Transaction implements ITransaction { private model: TransactionModel; private raw?: ethers.Transaction; diff --git a/src/coinbase/transfer.ts b/src/coinbase/transfer.ts index 80b9cbab..270af6a1 100644 --- a/src/coinbase/transfer.ts +++ b/src/coinbase/transfer.ts @@ -8,12 +8,27 @@ import { ethers } from "ethers"; import { delay } from "./utils"; import { TimeoutError } from "./errors"; +export interface ITransfer { + getTransactionHash(): string | undefined; + getTransactionLink(): string | undefined; + getStatus(): TransferStatus | undefined; + getTransaction(): Transaction | undefined; + getSponsoredSend(): SponsoredSend | undefined; + getSendTransactionDelegate(): Transaction | SponsoredSend | undefined; + getId(): string; + getNetworkId(): string; + sign(key: ethers.Wallet): Promise; + broadcast(): Promise; + wait(options?: { intervalSeconds?: number; timeoutSeconds?: number }): Promise; + reload(): Promise; +} + /** * A representation of a Transfer, which moves an Amount of an Asset from * a user-controlled Wallet to another Address. The fee is assumed to be paid * in the native Asset of the Network. */ -export class Transfer { +export class Transfer implements ITransfer { private model: TransferModel; /** @@ -209,7 +224,7 @@ export class Transfer { * @returns The Transfer object * @throws {APIError} if the API request to broadcast a Transfer fails. */ - public async broadcast(): Promise { + public async broadcast(): Promise { if (!this.getSendTransactionDelegate()?.isSigned()) throw new Error("Cannot broadcast unsigned Transfer"); diff --git a/src/coinbase/validator.ts b/src/coinbase/validator.ts index 621e7244..a6bc79cb 100644 --- a/src/coinbase/validator.ts +++ b/src/coinbase/validator.ts @@ -2,10 +2,14 @@ import { Coinbase } from "./coinbase"; import { Validator as ValidatorModel, ValidatorStatus as APIValidatorStatus } from "../client/api"; import { ValidatorStatus } from "./types"; +export interface IValidator { + getValidatorId(): string; + getStatus(): string; +} /** * A representation of a validator onchain. */ -export class Validator { +export class Validator implements IValidator { private model: ValidatorModel; /** diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index bd9c1baf..c1150819 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -14,7 +14,7 @@ import { Coinbase } from "./coinbase"; import { ArgumentError } from "./errors"; import { FaucetTransaction } from "./faucet_transaction"; import { Trade } from "./trade"; -import { Transfer } from "./transfer"; +import { ITransfer, Transfer } from "./transfer"; import { Amount, StakingRewardFormat, @@ -41,6 +41,40 @@ import { ContractInvocation } from "../coinbase/contract_invocation"; import { SmartContract } from "./smart_contract"; import { Webhook } from "./webhook"; +export interface IWallet { + createAddress(): Promise
; + createTrade(options: CreateTradeOptions): Promise; + stakeableBalance( + asset_id: string, + mode?: StakeOptionsMode, + options?: { [key: string]: string }, + ): Promise; + unstakeableBalance( + asset_id: string, + mode?: StakeOptionsMode, + options?: { [key: string]: string }, + ): Promise; + claimableBalance( + asset_id: string, + mode?: StakeOptionsMode, + options?: { [key: string]: string }, + ): Promise; + stakingRewards( + assetId: string, + startTime?: string, + endTime?: string, + format?: StakingRewardFormat, + ): Promise; + historicalStakingBalances( + assetId: string, + startTime?: string, + endTime?: string, + ): Promise; + listHistoricalBalances( + options: ListHistoricalBalancesOptions, + ): Promise; +} + /** * A representation of a Wallet. Wallets come with a single default Address, but can expand to have a set of Addresses, * each of which can hold a balance of one or more Assets. Wallets can create new Addresses, list their addresses, @@ -49,7 +83,7 @@ import { Webhook } from "./webhook"; * Existing wallets can be imported with a seed using `Wallet.import`. * Wallets backed by a Server Signer can be fetched with `Wallet.fetch` and used for signing operations immediately. */ -export class Wallet { +export class Wallet implements IWallet { static MAX_ADDRESSES = 20; private model: WalletModel; @@ -79,7 +113,7 @@ export class Wallet { * * @returns The list of Wallets. */ - public static async listWallets(): Promise { + public static async listWallets(): Promise { const walletList: Wallet[] = []; const queue: string[] = [""]; @@ -735,7 +769,7 @@ export class Wallet { * @throws {APIError} if the API request to create a Transfer fails. * @throws {APIError} if the API request to broadcast a Transfer fails. */ - public async createTransfer(options: CreateTransferOptions): Promise { + public async createTransfer(options: CreateTransferOptions): Promise { return (await this.getDefaultAddress()).createTransfer(options); } diff --git a/src/coinbase/webhook.ts b/src/coinbase/webhook.ts index bbaf1252..331563fe 100644 --- a/src/coinbase/webhook.ts +++ b/src/coinbase/webhook.ts @@ -7,11 +7,22 @@ import { import { Coinbase } from "./coinbase"; import { CreateWebhookOptions } from "./types"; +export interface IWebhook { + getId(): string | undefined; + getNetworkId(): string | undefined; + getNotificationURI(): string | undefined; + getEventType(): WebhookEventType | undefined; + getEventTypeFilter(): WebhookEventTypeFilter | undefined; + getEventFilters(): Array | undefined; + getSignatureHeader(): string | undefined; + update(notificationUri: string): Promise; + delete(): Promise; +} /** * A representation of a Webhook, * which provides methods to create, list, update, and delete webhooks that are used to receive notifications of specific events. */ -export class Webhook { +export class Webhook implements IWebhook { private model: WebhookModel | null; /** @@ -168,7 +179,7 @@ export class Webhook { * @param notificationUri - The new URI for webhook notifications. * @returns A promise that resolves to the updated Webhook object. */ - public async update(notificationUri: string): Promise { + public async update(notificationUri: string): Promise { const result = await Coinbase.apiClients.webhook!.updateWebhook(this.getId()!, { notification_uri: notificationUri, event_filters: this.getEventFilters()!, From 80553d787d8bf415c52832f5b396357b8c2b33c6 Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 11:20:04 -0400 Subject: [PATCH 02/12] lint --- src/coinbase/wallet.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index c1150819..bac33bf6 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -14,7 +14,7 @@ import { Coinbase } from "./coinbase"; import { ArgumentError } from "./errors"; import { FaucetTransaction } from "./faucet_transaction"; import { Trade } from "./trade"; -import { ITransfer, Transfer } from "./transfer"; +import { ITransfer } from "./transfer"; import { Amount, StakingRewardFormat, From c2837b5817d70528156eb1d8e8239707f4ae299e Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 11:48:13 -0400 Subject: [PATCH 03/12] Cleanup --- src/coinbase/wallet.ts | 16 ++++++++++------ src/tests/e2e.ts | 1 - 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index bac33bf6..f71233f7 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -6,7 +6,7 @@ import * as fs from "fs"; import * as secp256k1 from "secp256k1"; import { Address as AddressModel, Wallet as WalletModel } from "../client"; import { Address } from "./address"; -import { WalletAddress } from "./address/wallet_address"; +import { IWalletAddress, WalletAddress } from "./address/wallet_address"; import { Asset } from "./asset"; import { Balance } from "./balance"; import { BalanceMap } from "./balance_map"; @@ -42,6 +42,10 @@ import { SmartContract } from "./smart_contract"; import { Webhook } from "./webhook"; export interface IWallet { + getId(): string; + getDefaultAddress(): Promise; + listAddresses(): Promise; + getAddress(addressId: string): Promise; createAddress(): Promise
; createTrade(options: CreateTradeOptions): Promise; stakeableBalance( @@ -114,7 +118,7 @@ export class Wallet implements IWallet { * @returns The list of Wallets. */ public static async listWallets(): Promise { - const walletList: Wallet[] = []; + const walletList: IWallet[] = []; const queue: string[] = [""]; while (queue.length > 0) { @@ -143,7 +147,7 @@ export class Wallet implements IWallet { * @param wallet_id - The ID of the Wallet to fetch * @returns The fetched Wallet */ - public static async fetch(wallet_id: string): Promise { + public static async fetch(wallet_id: string): Promise { const response = await Coinbase.apiClients.wallet!.getWallet(wallet_id); return Wallet.init(response.data!, ""); } @@ -159,7 +163,7 @@ export class Wallet implements IWallet { * @throws {ArgumentError} If the seed is not provided. * @throws {APIError} If the request fails. */ - public static async import(data: WalletData): Promise { + public static async import(data: WalletData): Promise { if (!data.walletId) { throw new ArgumentError("Wallet ID must be provided"); } @@ -609,7 +613,7 @@ export class Wallet implements IWallet { * * @returns The wallet ID. */ - public getId(): string | undefined { + public getId(): string { return this.model.id; } @@ -719,7 +723,7 @@ export class Wallet implements IWallet { * * @returns The default address */ - public async getDefaultAddress(): Promise { + public async getDefaultAddress(): Promise { if (this.model.default_address === undefined) { throw new Error("WalletModel default address not set"); } diff --git a/src/tests/e2e.ts b/src/tests/e2e.ts index f0b36c3e..eb8357ac 100644 --- a/src/tests/e2e.ts +++ b/src/tests/e2e.ts @@ -31,7 +31,6 @@ describe("Coinbase SDK E2E Test", () => { console.log("Creating new wallet..."); const wallet = await Wallet.create(); - expect(wallet.toString()).toBeDefined(); expect(wallet?.getId()).toBeDefined(); console.log( `Created new wallet with ID: ${wallet.getId()}, default address: ${wallet.getDefaultAddress()}`, From 735bc3735ec07fca21e5c5df0c501273e42ad8aa Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 11:49:25 -0400 Subject: [PATCH 04/12] Fix --- src/coinbase/wallet.ts | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index f71233f7..391402a8 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -77,6 +77,40 @@ export interface IWallet { listHistoricalBalances( options: ListHistoricalBalancesOptions, ): Promise; + listBalances(): Promise; + getBalance(assetId: string): Promise; + getNetworkId(): string; + getServerSignerStatus(): ServerSignerStatus | undefined; + saveSeed(filePath: string, encrypt?: boolean): string; + loadSeed(filePath: string): Promise; + canSign(): boolean; + faucet(assetId?: string): Promise; + createTransfer(options: CreateTransferOptions): Promise; + createStake( + amount: Amount, + assetId: string, + mode?: StakeOptionsMode, + options?: { [key: string]: string }, + timeoutSeconds?: number, + intervalSeconds?: number, + ): Promise; + createUnstake( + amount: Amount, + assetId: string, + mode?: StakeOptionsMode, + options?: { [key: string]: string }, + timeoutSeconds?: number, + intervalSeconds?: number, + ): Promise; + createClaimStake( + amount: Amount, + assetId: string, + mode?: StakeOptionsMode, + options?: { [key: string]: string }, + timeoutSeconds?: number, + intervalSeconds?: number, + ): Promise; + invokeContract(options: CreateContractInvocationOptions): Promise; } /** From 68fb04f180da6b0c1092a8ac0fda2f6b2576b581 Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 11:57:07 -0400 Subject: [PATCH 05/12] More fixes --- src/coinbase/address/wallet_address.ts | 12 ++++++++---- src/coinbase/types.ts | 6 +++--- src/coinbase/wallet.ts | 3 ++- src/tests/e2e.ts | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/coinbase/address/wallet_address.ts b/src/coinbase/address/wallet_address.ts index 3a6e966a..b56a838e 100644 --- a/src/coinbase/address/wallet_address.ts +++ b/src/coinbase/address/wallet_address.ts @@ -769,13 +769,17 @@ export class WalletAddress extends Address implements IWalletAddress { if (typeof destination !== "string" && destination.getNetworkId() !== this.getNetworkId()) { throw new ArgumentError("Transfer must be on the same Network"); } - if (destination instanceof WalletClass) { - return [(await destination.getDefaultAddress()).getId(), destination.getNetworkId()]; + if (typeof destination === 'string') { + return [destination, this.getNetworkId()]; } - if (destination instanceof Address) { + if ('getDefaultAddress' in destination) { + const defaultAddress = await destination.getDefaultAddress(); + return [defaultAddress.getId(), destination.getNetworkId()]; + } + if ('getId' in destination) { return [destination.getId(), destination.getNetworkId()]; } - return [destination, this.getNetworkId()]; + throw new ArgumentError('Invalid destination type'); } /** diff --git a/src/coinbase/types.ts b/src/coinbase/types.ts index abf830db..38fd5938 100644 --- a/src/coinbase/types.ts +++ b/src/coinbase/types.ts @@ -55,8 +55,8 @@ import { WebhookEventTypeFilter, CreateWalletWebhookRequest, } from "./../client/api"; -import { Address } from "./address"; -import { Wallet } from "./wallet"; +import { Address, IAddress } from "./address"; +import { IWallet, Wallet } from "./wallet"; import { HistoricalBalance } from "./historical_balance"; import { Transaction } from "./transaction"; @@ -810,7 +810,7 @@ export type Amount = number | bigint | Decimal; /** * Destination type definition. */ -export type Destination = string | Address | Wallet; +export type Destination = string | IAddress | IWallet; /** * ServerSigner status type definition. diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index 391402a8..56024001 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -111,6 +111,7 @@ export interface IWallet { intervalSeconds?: number, ): Promise; invokeContract(options: CreateContractInvocationOptions): Promise; + export(): WalletData; } /** @@ -227,7 +228,7 @@ export class Wallet implements IWallet { networkId = Coinbase.networks.BaseSepolia, timeoutSeconds = 20, intervalSeconds = 0.2, - }: WalletCreateOptions = {}): Promise { + }: WalletCreateOptions = {}): Promise { const result = await Coinbase.apiClients.wallet!.createWallet({ wallet: { network_id: networkId, diff --git a/src/tests/e2e.ts b/src/tests/e2e.ts index eb8357ac..426469ff 100644 --- a/src/tests/e2e.ts +++ b/src/tests/e2e.ts @@ -31,7 +31,7 @@ describe("Coinbase SDK E2E Test", () => { console.log("Creating new wallet..."); const wallet = await Wallet.create(); - expect(wallet?.getId()).toBeDefined(); + expect(wallet.getId()).toBeDefined(); console.log( `Created new wallet with ID: ${wallet.getId()}, default address: ${wallet.getDefaultAddress()}`, ); From 433fe74cb84c44486fdd51b0e529af7852a944e7 Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 12:08:27 -0400 Subject: [PATCH 06/12] Fix --- src/coinbase/wallet.ts | 6 ++++++ src/tests/wallet_test.ts | 10 +++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index 56024001..da7e90da 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -31,6 +31,7 @@ import { CreateERC20Options, CreateERC721Options, CreateERC1155Options, + CreateWebhookOptions, } from "./types"; import { convertStringToHex, delay, formatDate, getWeekBackDate } from "./utils"; import { StakingOperation } from "./staking_operation"; @@ -112,6 +113,11 @@ export interface IWallet { ): Promise; invokeContract(options: CreateContractInvocationOptions): Promise; export(): WalletData; + createWebhook(notificationUri: string): Promise; + deployToken(options: CreateERC20Options): Promise; + deployNFT(options: CreateERC721Options): Promise; + deployMultiToken(options: CreateERC1155Options): Promise; + createPayloadSignature(unsignedPayload: string): Promise } /** diff --git a/src/tests/wallet_test.ts b/src/tests/wallet_test.ts index 82ce573d..bd4610b5 100644 --- a/src/tests/wallet_test.ts +++ b/src/tests/wallet_test.ts @@ -5,7 +5,7 @@ import { ethers } from "ethers"; import { APIError } from "../coinbase/api_error"; import { Coinbase } from "../coinbase/coinbase"; import { ArgumentError } from "../coinbase/errors"; -import { Wallet } from "../coinbase/wallet"; +import { IWallet, Wallet } from "../coinbase/wallet"; import { Transfer } from "../coinbase/transfer"; import { ServerSignerStatus, StakeOptionsMode, TransferStatus } from "../coinbase/types"; import { @@ -70,7 +70,7 @@ import { SmartContract } from "../coinbase/smart_contract"; import { Webhook } from "../coinbase/webhook"; describe("Wallet Class", () => { - let wallet: Wallet; + let wallet: IWallet; let walletModel: WalletModel; let walletId: string; const apiResponses = {}; @@ -801,7 +801,7 @@ describe("Wallet Class", () => { describe("when using a server signer", () => { const walletId = crypto.randomUUID(); - let wallet: Wallet; + let wallet: IWallet; beforeEach(async () => { jest.clearAllMocks(); Coinbase.useServerSigner = true; @@ -844,7 +844,7 @@ describe("Wallet Class", () => { }); describe(".init", () => { - let wallet: Wallet; + let wallet: IWallet; let addressList: AddressModel[]; let walletModel: WalletModel; const existingSeed = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"; @@ -1339,7 +1339,7 @@ describe("Wallet Class", () => { }); describe("#createWebhook", () => { - let wallet: Wallet; + let wallet: IWallet; let addressList: AddressModel[]; let walletModel: WalletModel; const existingSeed = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"; From 4a77ec39660a063eb7084e1fd8d2e48deacf19d0 Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 12:26:00 -0400 Subject: [PATCH 07/12] Lint --- src/coinbase/address/wallet_address.ts | 8 ++++---- src/coinbase/wallet.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/coinbase/address/wallet_address.ts b/src/coinbase/address/wallet_address.ts index b56a838e..18bb1303 100644 --- a/src/coinbase/address/wallet_address.ts +++ b/src/coinbase/address/wallet_address.ts @@ -769,17 +769,17 @@ export class WalletAddress extends Address implements IWalletAddress { if (typeof destination !== "string" && destination.getNetworkId() !== this.getNetworkId()) { throw new ArgumentError("Transfer must be on the same Network"); } - if (typeof destination === 'string') { + if (typeof destination === "string") { return [destination, this.getNetworkId()]; } - if ('getDefaultAddress' in destination) { + if ("getDefaultAddress" in destination) { const defaultAddress = await destination.getDefaultAddress(); return [defaultAddress.getId(), destination.getNetworkId()]; } - if ('getId' in destination) { + if ("getId" in destination) { return [destination.getId(), destination.getNetworkId()]; } - throw new ArgumentError('Invalid destination type'); + throw new ArgumentError("Invalid destination type"); } /** diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index da7e90da..beb8233c 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -117,7 +117,7 @@ export interface IWallet { deployToken(options: CreateERC20Options): Promise; deployNFT(options: CreateERC721Options): Promise; deployMultiToken(options: CreateERC1155Options): Promise; - createPayloadSignature(unsignedPayload: string): Promise + createPayloadSignature(unsignedPayload: string): Promise; } /** From 83d22b35949054d025032aa76ba842e98a59e0d8 Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 12:28:25 -0400 Subject: [PATCH 08/12] Format --- src/coinbase/types.ts | 4 ++-- src/coinbase/wallet.ts | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/coinbase/types.ts b/src/coinbase/types.ts index 38fd5938..a03c3c85 100644 --- a/src/coinbase/types.ts +++ b/src/coinbase/types.ts @@ -55,8 +55,8 @@ import { WebhookEventTypeFilter, CreateWalletWebhookRequest, } from "./../client/api"; -import { Address, IAddress } from "./address"; -import { IWallet, Wallet } from "./wallet"; +import { IAddress } from "./address"; +import { IWallet } from "./wallet"; import { HistoricalBalance } from "./historical_balance"; import { Transaction } from "./transaction"; diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index beb8233c..b76e416e 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -31,7 +31,6 @@ import { CreateERC20Options, CreateERC721Options, CreateERC1155Options, - CreateWebhookOptions, } from "./types"; import { convertStringToHex, delay, formatDate, getWeekBackDate } from "./utils"; import { StakingOperation } from "./staking_operation"; From 2b240ab24fc1e635d1ebd9ecc560f548f8d748c2 Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 16:03:02 -0400 Subject: [PATCH 09/12] more cleanup --- src/coinbase/address/external_address.ts | 8 +-- src/coinbase/address/wallet_address.ts | 34 ++++++------- src/coinbase/contract_invocation.ts | 6 +-- src/coinbase/staking_operation.ts | 11 +++++ src/coinbase/wallet.ts | 63 ++++++++++++------------ src/coinbase/webhook.ts | 2 +- 6 files changed, 68 insertions(+), 56 deletions(-) diff --git a/src/coinbase/address/external_address.ts b/src/coinbase/address/external_address.ts index b7e5e2ec..87f4e980 100644 --- a/src/coinbase/address/external_address.ts +++ b/src/coinbase/address/external_address.ts @@ -3,7 +3,7 @@ import { Amount, StakeOptionsMode } from "../types"; import { Coinbase } from "../coinbase"; import Decimal from "decimal.js"; import { Asset } from "../asset"; -import { StakingOperation } from "../staking_operation"; +import { IStakingOperation, StakingOperation } from "../staking_operation"; export interface IExternalAddress extends IAddress { buildStakeOperation( @@ -11,19 +11,19 @@ export interface IExternalAddress extends IAddress { assetId: string, mode: StakeOptionsMode, options: { [key: string]: string }, - ): Promise; + ): Promise; buildUnstakeOperation( amount: Amount, assetId: string, mode: StakeOptionsMode, options: { [key: string]: string }, - ): Promise; + ): Promise; buildClaimStakeOperation( amount: Amount, assetId: string, mode: StakeOptionsMode, options: { [key: string]: string }, - ): Promise; + ): Promise; } /** diff --git a/src/coinbase/address/wallet_address.ts b/src/coinbase/address/wallet_address.ts index 18bb1303..d9e56989 100644 --- a/src/coinbase/address/wallet_address.ts +++ b/src/coinbase/address/wallet_address.ts @@ -5,9 +5,9 @@ import { Address, IAddress } from "../address"; import { Asset } from "../asset"; import { Coinbase } from "../coinbase"; import { ArgumentError } from "../errors"; -import { Trade } from "../trade"; +import { ITrade, Trade } from "../trade"; import { ITransfer, Transfer } from "../transfer"; -import { ContractInvocation } from "../contract_invocation"; +import { ContractInvocation, IContractInvocation } from "../contract_invocation"; import { Amount, CreateTransferOptions, @@ -21,23 +21,23 @@ import { } from "../types"; import { delay } from "../utils"; import { Wallet as WalletClass } from "../wallet"; -import { StakingOperation } from "../staking_operation"; -import { PayloadSignature } from "../payload_signature"; -import { SmartContract } from "../smart_contract"; +import { IStakingOperation, StakingOperation } from "../staking_operation"; +import { IPayloadSignature, PayloadSignature } from "../payload_signature"; +import { ISmartContract, SmartContract } from "../smart_contract"; export interface IWalletAddress extends IAddress { getWalletId(): string; setKey(key: ethers.Wallet): void; export(): string; canSign(): boolean; - listTrades(): Promise; + listTrades(): Promise; listTransfers(): Promise; createTransfer(options: CreateTransferOptions): Promise; - createTrade(options: CreateTradeOptions): Promise; - invokeContract(options: CreateContractInvocationOptions): Promise; - deployToken(options: CreateERC20Options): Promise; - deployNFT(options: CreateERC721Options): Promise; - deployMultiToken(options: CreateERC1155Options): Promise; + createTrade(options: CreateTradeOptions): Promise; + invokeContract(options: CreateContractInvocationOptions): Promise; + deployToken(options: CreateERC20Options): Promise; + deployNFT(options: CreateERC721Options): Promise; + deployMultiToken(options: CreateERC1155Options): Promise; createStake( amount: Amount, assetId: string, @@ -45,7 +45,7 @@ export interface IWalletAddress extends IAddress { options: { [key: string]: string }, timeoutSeconds: number, intervalSeconds: number, - ): Promise; + ): Promise; createUnstake( amount: Amount, assetId: string, @@ -53,7 +53,7 @@ export interface IWalletAddress extends IAddress { options: { [key: string]: string }, timeoutSeconds: number, intervalSeconds: number, - ): Promise; + ): Promise; createClaimStake( amount: Amount, assetId: string, @@ -61,10 +61,10 @@ export interface IWalletAddress extends IAddress { options: { [key: string]: string }, timeoutSeconds: number, intervalSeconds: number, - ): Promise; - createPayloadSignature(payload: string): Promise; - getPayloadSignature(signatureId: string): Promise; - listPayloadSignatures(): Promise; + ): Promise; + createPayloadSignature(payload: string): Promise; + getPayloadSignature(signatureId: string): Promise; + listPayloadSignatures(): Promise; } /** diff --git a/src/coinbase/contract_invocation.ts b/src/coinbase/contract_invocation.ts index 8d8eb838..d7d28df7 100644 --- a/src/coinbase/contract_invocation.ts +++ b/src/coinbase/contract_invocation.ts @@ -1,6 +1,6 @@ import { Decimal } from "decimal.js"; import { TransactionStatus } from "./types"; -import { Transaction } from "./transaction"; +import { ITransaction, Transaction } from "./transaction"; import { Coinbase } from "./coinbase"; import { ContractInvocation as ContractInvocationModel } from "../client/api"; import { ethers } from "ethers"; @@ -21,9 +21,9 @@ export interface IContractInvocation { getRawTransaction(): ethers.Transaction; sign(key: ethers.Wallet): Promise; getStatus(): TransactionStatus | undefined; - getTransaction(): Transaction; + getTransaction(): ITransaction; getTransactionLink(): string; - broadcast(): Promise; + broadcast(): Promise; wait({ intervalSeconds, timeoutSeconds, diff --git a/src/coinbase/staking_operation.ts b/src/coinbase/staking_operation.ts index d3da20bf..1651394a 100644 --- a/src/coinbase/staking_operation.ts +++ b/src/coinbase/staking_operation.ts @@ -16,6 +16,17 @@ export interface IStakingOperation { isTerminalState(): boolean; isFailedState(): boolean; isCompleteState(): boolean; + getTransactions(): Transaction[]; + getSignedVoluntaryExitMessages(): string[]; + reload(): Promise; + wait({ + intervalSeconds, + timeoutSeconds, + }: { + intervalSeconds: number; + timeoutSeconds: number; + }): Promise; + sign(key: ethers.Wallet): Promise; } /** diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index b76e416e..a9370dc5 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -5,15 +5,15 @@ import { ethers } from "ethers"; import * as fs from "fs"; import * as secp256k1 from "secp256k1"; import { Address as AddressModel, Wallet as WalletModel } from "../client"; -import { Address } from "./address"; +import { Address, IAddress } from "./address"; import { IWalletAddress, WalletAddress } from "./address/wallet_address"; import { Asset } from "./asset"; import { Balance } from "./balance"; import { BalanceMap } from "./balance_map"; import { Coinbase } from "./coinbase"; import { ArgumentError } from "./errors"; -import { FaucetTransaction } from "./faucet_transaction"; -import { Trade } from "./trade"; +import { FaucetTransaction, IFaucetTransaction } from "./faucet_transaction"; +import { ITrade, Trade } from "./trade"; import { ITransfer } from "./transfer"; import { Amount, @@ -33,21 +33,22 @@ import { CreateERC1155Options, } from "./types"; import { convertStringToHex, delay, formatDate, getWeekBackDate } from "./utils"; -import { StakingOperation } from "./staking_operation"; +import { IStakingOperation, StakingOperation } from "./staking_operation"; import { StakingReward } from "./staking_reward"; import { StakingBalance } from "./staking_balance"; -import { PayloadSignature } from "./payload_signature"; -import { ContractInvocation } from "../coinbase/contract_invocation"; -import { SmartContract } from "./smart_contract"; -import { Webhook } from "./webhook"; +import { IPayloadSignature, PayloadSignature } from "./payload_signature"; +import { ContractInvocation, IContractInvocation } from "../coinbase/contract_invocation"; +import { ISmartContract, SmartContract } from "./smart_contract"; +import { IWebhook, Webhook } from "./webhook"; export interface IWallet { getId(): string; getDefaultAddress(): Promise; listAddresses(): Promise; getAddress(addressId: string): Promise; - createAddress(): Promise
; - createTrade(options: CreateTradeOptions): Promise; + createAddress(): Promise; + setSeed(seed: string): void; + createTrade(options: CreateTradeOptions): Promise; stakeableBalance( asset_id: string, mode?: StakeOptionsMode, @@ -84,7 +85,7 @@ export interface IWallet { saveSeed(filePath: string, encrypt?: boolean): string; loadSeed(filePath: string): Promise; canSign(): boolean; - faucet(assetId?: string): Promise; + faucet(assetId?: string): Promise; createTransfer(options: CreateTransferOptions): Promise; createStake( amount: Amount, @@ -93,7 +94,7 @@ export interface IWallet { options?: { [key: string]: string }, timeoutSeconds?: number, intervalSeconds?: number, - ): Promise; + ): Promise; createUnstake( amount: Amount, assetId: string, @@ -101,7 +102,7 @@ export interface IWallet { options?: { [key: string]: string }, timeoutSeconds?: number, intervalSeconds?: number, - ): Promise; + ): Promise; createClaimStake( amount: Amount, assetId: string, @@ -109,14 +110,14 @@ export interface IWallet { options?: { [key: string]: string }, timeoutSeconds?: number, intervalSeconds?: number, - ): Promise; - invokeContract(options: CreateContractInvocationOptions): Promise; + ): Promise; + invokeContract(options: CreateContractInvocationOptions): Promise; export(): WalletData; - createWebhook(notificationUri: string): Promise; - deployToken(options: CreateERC20Options): Promise; - deployNFT(options: CreateERC721Options): Promise; - deployMultiToken(options: CreateERC1155Options): Promise; - createPayloadSignature(unsignedPayload: string): Promise; + createWebhook(notificationUri: string): Promise; + deployToken(options: CreateERC20Options): Promise; + deployNFT(options: CreateERC721Options): Promise; + deployMultiToken(options: CreateERC1155Options): Promise; + createPayloadSignature(unsignedPayload: string): Promise; } /** @@ -293,7 +294,7 @@ export class Wallet implements IWallet { * @returns The new Address. * @throws {APIError} - If the address creation fails. */ - public async createAddress(): Promise
{ + public async createAddress(): Promise { let payload, key; if (!Coinbase.useServerSigner) { // TODO: Coordinate this value with concurrent calls to createAddress. @@ -395,7 +396,7 @@ export class Wallet implements IWallet { * @throws {Error} If the private key is not loaded, or if the asset IDs are unsupported, or if there are insufficient funds. * @returns The created Trade object. */ - public async createTrade(options: CreateTradeOptions): Promise { + public async createTrade(options: CreateTradeOptions): Promise { return (await this.getDefaultAddress()).createTrade(options); } @@ -526,7 +527,7 @@ export class Wallet implements IWallet { options: { [key: string]: string } = {}, timeoutSeconds = 60, intervalSeconds = 0.2, - ): Promise { + ): Promise { return (await this.getDefaultAddress()).createStake( amount, assetId, @@ -556,7 +557,7 @@ export class Wallet implements IWallet { options: { [key: string]: string } = {}, timeoutSeconds = 60, intervalSeconds = 0.2, - ): Promise { + ): Promise { return (await this.getDefaultAddress()).createUnstake( amount, assetId, @@ -586,7 +587,7 @@ export class Wallet implements IWallet { options: { [key: string]: string } = {}, timeoutSeconds = 60, intervalSeconds = 0.2, - ): Promise { + ): Promise { return (await this.getDefaultAddress()).createClaimStake( amount, assetId, @@ -825,7 +826,7 @@ export class Wallet implements IWallet { * @throws {APIError} if the API request to create a Payload Signature fails. * @throws {Error} if the default address is not found. */ - public async createPayloadSignature(unsignedPayload: string): Promise { + public async createPayloadSignature(unsignedPayload: string): Promise { return (await this.getDefaultAddress()).createPayloadSignature(unsignedPayload); } @@ -836,7 +837,7 @@ export class Wallet implements IWallet { * * @returns The newly created webhook instance. */ - public async createWebhook(notificationUri: string): Promise { + public async createWebhook(notificationUri: string): Promise { const result = await Coinbase.apiClients.webhook!.createWalletWebhook(this.getId(), { notification_uri: notificationUri, }); @@ -861,7 +862,7 @@ export class Wallet implements IWallet { */ public async invokeContract( options: CreateContractInvocationOptions, - ): Promise { + ): Promise { return (await this.getDefaultAddress()).invokeContract(options); } @@ -875,7 +876,7 @@ export class Wallet implements IWallet { * @returns A Promise that resolves to the deployed SmartContract object. * @throws {Error} If the private key is not loaded when not using server signer. */ - public async deployToken(options: CreateERC20Options): Promise { + public async deployToken(options: CreateERC20Options): Promise { return (await this.getDefaultAddress()).deployToken(options); } @@ -889,7 +890,7 @@ export class Wallet implements IWallet { * @returns A Promise that resolves to the deployed SmartContract object. * @throws {Error} If the private key is not loaded when not using server signer. */ - public async deployNFT(options: CreateERC721Options): Promise { + public async deployNFT(options: CreateERC721Options): Promise { return (await this.getDefaultAddress()).deployNFT(options); } @@ -903,7 +904,7 @@ export class Wallet implements IWallet { * @returns A Promise that resolves to the deployed SmartContract object. * @throws {Error} If the private key is not loaded when not using server signer. */ - public async deployMultiToken(options: CreateERC1155Options): Promise { + public async deployMultiToken(options: CreateERC1155Options): Promise { return (await this.getDefaultAddress()).deployMultiToken(options); } diff --git a/src/coinbase/webhook.ts b/src/coinbase/webhook.ts index 331563fe..8a7bc54b 100644 --- a/src/coinbase/webhook.ts +++ b/src/coinbase/webhook.ts @@ -21,7 +21,7 @@ export interface IWebhook { /** * A representation of a Webhook, * which provides methods to create, list, update, and delete webhooks that are used to receive notifications of specific events. - */ + */ export class Webhook implements IWebhook { private model: WebhookModel | null; From 6584c17ac9d65073db9f60a5fd0357153fd19b7f Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 16:07:10 -0400 Subject: [PATCH 10/12] Fix --- src/coinbase/wallet.ts | 26 +++++++++++++------------- src/coinbase/webhook.ts | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index a9370dc5..88b952ef 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -5,7 +5,8 @@ import { ethers } from "ethers"; import * as fs from "fs"; import * as secp256k1 from "secp256k1"; import { Address as AddressModel, Wallet as WalletModel } from "../client"; -import { Address, IAddress } from "./address"; +import { IContractInvocation } from "../coinbase/contract_invocation"; +import { IAddress } from "./address"; import { IWalletAddress, WalletAddress } from "./address/wallet_address"; import { Asset } from "./asset"; import { Balance } from "./balance"; @@ -13,32 +14,31 @@ import { BalanceMap } from "./balance_map"; import { Coinbase } from "./coinbase"; import { ArgumentError } from "./errors"; import { FaucetTransaction, IFaucetTransaction } from "./faucet_transaction"; -import { ITrade, Trade } from "./trade"; +import { IPayloadSignature } from "./payload_signature"; +import { ISmartContract } from "./smart_contract"; +import { StakingBalance } from "./staking_balance"; +import { IStakingOperation } from "./staking_operation"; +import { StakingReward } from "./staking_reward"; +import { ITrade } from "./trade"; import { ITransfer } from "./transfer"; import { Amount, - StakingRewardFormat, CreateContractInvocationOptions, - CreateTransferOptions, + CreateERC1155Options, + CreateERC20Options, + CreateERC721Options, CreateTradeOptions, + CreateTransferOptions, ListHistoricalBalancesOptions, ListHistoricalBalancesResult, SeedData, ServerSignerStatus, StakeOptionsMode, + StakingRewardFormat, WalletCreateOptions, WalletData, - CreateERC20Options, - CreateERC721Options, - CreateERC1155Options, } from "./types"; import { convertStringToHex, delay, formatDate, getWeekBackDate } from "./utils"; -import { IStakingOperation, StakingOperation } from "./staking_operation"; -import { StakingReward } from "./staking_reward"; -import { StakingBalance } from "./staking_balance"; -import { IPayloadSignature, PayloadSignature } from "./payload_signature"; -import { ContractInvocation, IContractInvocation } from "../coinbase/contract_invocation"; -import { ISmartContract, SmartContract } from "./smart_contract"; import { IWebhook, Webhook } from "./webhook"; export interface IWallet { diff --git a/src/coinbase/webhook.ts b/src/coinbase/webhook.ts index 8a7bc54b..331563fe 100644 --- a/src/coinbase/webhook.ts +++ b/src/coinbase/webhook.ts @@ -21,7 +21,7 @@ export interface IWebhook { /** * A representation of a Webhook, * which provides methods to create, list, update, and delete webhooks that are used to receive notifications of specific events. - */ + */ export class Webhook implements IWebhook { private model: WebhookModel | null; From e1a85d94bf0f013f21219c3c63c12bbd560661a0 Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 19:34:18 -0400 Subject: [PATCH 11/12] Fix --- src/coinbase/staking_operation.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/coinbase/staking_operation.ts b/src/coinbase/staking_operation.ts index 1651394a..fe94875a 100644 --- a/src/coinbase/staking_operation.ts +++ b/src/coinbase/staking_operation.ts @@ -19,12 +19,9 @@ export interface IStakingOperation { getTransactions(): Transaction[]; getSignedVoluntaryExitMessages(): string[]; reload(): Promise; - wait({ - intervalSeconds, - timeoutSeconds, - }: { - intervalSeconds: number; - timeoutSeconds: number; + wait(options?: { + intervalSeconds?: number; + timeoutSeconds?: number; }): Promise; sign(key: ethers.Wallet): Promise; } From 6d1bbf893bccc6b55fb9f3a3f5f19e8b8ef616df Mon Sep 17 00:00:00 2001 From: Rohan Agarwal Date: Fri, 27 Sep 2024 19:38:23 -0400 Subject: [PATCH 12/12] Fix --- src/coinbase/staking_operation.ts | 4 ++-- src/coinbase/wallet.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/coinbase/staking_operation.ts b/src/coinbase/staking_operation.ts index fe94875a..4e289e65 100644 --- a/src/coinbase/staking_operation.ts +++ b/src/coinbase/staking_operation.ts @@ -3,7 +3,7 @@ import { StakingOperation as StakingOperationModel, StakingOperationStatusEnum, } from "../client/api"; -import { Transaction } from "./transaction"; +import { ITransaction, Transaction } from "./transaction"; import { Coinbase } from "./coinbase"; import { delay } from "./utils"; @@ -16,7 +16,7 @@ export interface IStakingOperation { isTerminalState(): boolean; isFailedState(): boolean; isCompleteState(): boolean; - getTransactions(): Transaction[]; + getTransactions(): ITransaction[]; getSignedVoluntaryExitMessages(): string[]; reload(): Promise; wait(options?: { diff --git a/src/coinbase/wallet.ts b/src/coinbase/wallet.ts index 88b952ef..af220e82 100644 --- a/src/coinbase/wallet.ts +++ b/src/coinbase/wallet.ts @@ -16,9 +16,9 @@ import { ArgumentError } from "./errors"; import { FaucetTransaction, IFaucetTransaction } from "./faucet_transaction"; import { IPayloadSignature } from "./payload_signature"; import { ISmartContract } from "./smart_contract"; -import { StakingBalance } from "./staking_balance"; +import { IStakingBalance, StakingBalance } from "./staking_balance"; import { IStakingOperation } from "./staking_operation"; -import { StakingReward } from "./staking_reward"; +import { IStakingReward, StakingReward } from "./staking_reward"; import { ITrade } from "./trade"; import { ITransfer } from "./transfer"; import { @@ -69,12 +69,12 @@ export interface IWallet { startTime?: string, endTime?: string, format?: StakingRewardFormat, - ): Promise; + ): Promise; historicalStakingBalances( assetId: string, startTime?: string, endTime?: string, - ): Promise; + ): Promise; listHistoricalBalances( options: ListHistoricalBalancesOptions, ): Promise;