UNPKG

@coinbase/cdp-sdk

Version:

SDK for interacting with the Coinbase Developer Platform Wallet API

293 lines (267 loc) 9.1 kB
import { type TransactionSerializable, type TypedDataDefinition, type TypedData, type HashTypedDataParameters, getTypesForEIP712Domain, serializeTransaction, } from "viem"; import { toNetworkScopedEvmServerAccount } from "./toNetworkScopedEvmServerAccount.js"; import { EvmFundOptions, fund } from "../../actions/evm/fund/fund.js"; import { EvmQuoteFundOptions, quoteFund } from "../../actions/evm/fund/quoteFund.js"; import { listTokenBalances, type ListTokenBalancesResult, type ListTokenBalancesOptions, } from "../../actions/evm/listTokenBalances.js"; import { requestFaucet, type RequestFaucetOptions, type RequestFaucetResult, } from "../../actions/evm/requestFaucet.js"; import { sendTransaction } from "../../actions/evm/sendTransaction.js"; import { useSpendPermission } from "../../actions/evm/spend-permissions/account.use.js"; import { UseSpendPermissionOptions } from "../../actions/evm/spend-permissions/types.js"; import { createSwapQuote } from "../../actions/evm/swap/createSwapQuote.js"; import { sendSwapTransaction } from "../../actions/evm/swap/sendSwapTransaction.js"; import { accountTransferStrategy } from "../../actions/evm/transfer/accountTransferStrategy.js"; import { transfer } from "../../actions/evm/transfer/transfer.js"; import { EvmQuote } from "../../actions/Quote.js"; import { FundOperationResult } from "../../actions/types.js"; import { WaitForFundOperationOptions, WaitForFundOperationResult, waitForFundOperationReceipt, } from "../../actions/waitForFundOperationReceipt.js"; import { Analytics } from "../../analytics.js"; import type { EvmServerAccount, NetworkOrRpcUrl } from "./types.js"; import type { SendTransactionOptions, TransactionResult, } from "../../actions/evm/sendTransaction.js"; import type { AccountSwapOptions, AccountSwapResult, AccountQuoteSwapOptions, AccountQuoteSwapResult, } from "../../actions/evm/swap/types.js"; import type { CdpOpenApiClientType, EvmAccount } from "../../openapi-client/index.js"; import type { Address, EIP712Domain, Hash, Hex } from "../../types/misc.js"; /** * Options for converting a pre-existing EvmAccount to a EvmServerAccount. */ export type ToEvmServerAccountOptions = { /** The EvmAccount that was previously created. */ account: EvmAccount; }; /** * Creates a Server-managed EvmAccount instance from an existing EvmAccount. * Use this to interact with previously deployed EvmAccounts, rather than creating new ones. * * @param {CdpOpenApiClientType} apiClient - The API client. * @param {ToEvmServerAccountOptions} options - Configuration options. * @param {EvmAccount} options.account - The EvmAccount that was previously created. * @returns {EvmServerAccount} A configured EvmAccount instance ready for signing. */ export function toEvmServerAccount( apiClient: CdpOpenApiClientType, options: ToEvmServerAccountOptions, ): EvmServerAccount { const account: EvmServerAccount = { address: options.account.address as Address, async signMessage({ message }) { Analytics.trackAction({ action: "sign_message", accountType: "evm_server", }); const result = await apiClient.signEvmMessage(options.account.address, { message: message.toString(), }); return result.signature as Hex; }, async sign(parameters: { hash: Hash }) { Analytics.trackAction({ action: "sign", accountType: "evm_server", }); const result = await apiClient.signEvmHash(options.account.address, { hash: parameters.hash, }); return result.signature as Hex; }, async signTransaction(transaction: TransactionSerializable) { Analytics.trackAction({ action: "sign_transaction", accountType: "evm_server", }); const result = await apiClient.signEvmTransaction(options.account.address, { transaction: serializeTransaction(transaction), }); return result.signedTransaction as Hex; }, async signTypedData< const typedData extends TypedData | Record<string, unknown>, primaryType extends keyof typedData | "EIP712Domain" = keyof typedData, >(parameters: TypedDataDefinition<typedData, primaryType>) { Analytics.trackAction({ action: "sign_typed_data", accountType: "evm_server", }); const { domain = {}, message, primaryType } = parameters as HashTypedDataParameters; const types = { EIP712Domain: getTypesForEIP712Domain({ domain }), ...parameters.types, }; const openApiMessage = { domain: domain as EIP712Domain, types, primaryType, message, }; const result = await apiClient.signEvmTypedData(options.account.address, openApiMessage); return result.signature as Hex; }, async transfer(transferArgs): Promise<TransactionResult> { Analytics.trackAction({ action: "transfer", accountType: "evm_server", properties: { network: transferArgs.network, }, }); return transfer(apiClient, account, transferArgs, accountTransferStrategy); }, async listTokenBalances( options: Omit<ListTokenBalancesOptions, "address">, ): Promise<ListTokenBalancesResult> { Analytics.trackAction({ action: "list_token_balances", accountType: "evm_server", properties: { network: options.network, }, }); return listTokenBalances(apiClient, { ...options, address: this.address, }); }, async requestFaucet( options: Omit<RequestFaucetOptions, "address">, ): Promise<RequestFaucetResult> { Analytics.trackAction({ action: "request_faucet", accountType: "evm_server", properties: { network: options.network, }, }); return requestFaucet(apiClient, { ...options, address: this.address, }); }, async sendTransaction(options: Omit<SendTransactionOptions, "address">) { Analytics.trackAction({ action: "send_transaction", accountType: "evm_server", properties: { network: options.network, }, }); return sendTransaction(apiClient, { ...options, address: this.address, }); }, async quoteFund(options: Omit<EvmQuoteFundOptions, "address">): Promise<EvmQuote> { Analytics.trackAction({ action: "quote_fund", accountType: "evm_server", properties: { network: options.network, }, }); return quoteFund(apiClient, { ...options, address: this.address, }); }, async fund(options: Omit<EvmFundOptions, "address">): Promise<FundOperationResult> { Analytics.trackAction({ action: "fund", accountType: "evm_server", properties: { network: options.network, }, }); return fund(apiClient, { ...options, address: this.address, }); }, async waitForFundOperationReceipt( options: WaitForFundOperationOptions, ): Promise<WaitForFundOperationResult> { Analytics.trackAction({ action: "wait_for_fund_operation_receipt", accountType: "evm_server", }); return waitForFundOperationReceipt(apiClient, options); }, async quoteSwap(options: AccountQuoteSwapOptions): Promise<AccountQuoteSwapResult> { Analytics.trackAction({ action: "quote_swap", accountType: "evm_server", properties: { network: options.network, }, }); return createSwapQuote(apiClient, { ...options, taker: this.address, }); }, async swap(options: AccountSwapOptions): Promise<AccountSwapResult> { Analytics.trackAction({ action: "swap", accountType: "evm_server", properties: { network: "network" in options ? options.network : undefined, }, }); return sendSwapTransaction(apiClient, { ...options, address: this.address, taker: this.address, // Always use account's address as taker }); }, async useSpendPermission(options: UseSpendPermissionOptions): Promise<TransactionResult> { Analytics.trackAction({ action: "use_spend_permission", accountType: "evm_server", properties: { network: options.network, }, }); return useSpendPermission(apiClient, this.address, options); }, name: options.account.name, type: "evm-server", policies: options.account.policies, useNetwork: async <Network extends NetworkOrRpcUrl>(networkOrRpcUrl: Network) => { Analytics.trackAction({ action: "use_network", accountType: "evm_server", properties: { network: networkOrRpcUrl, }, }); return toNetworkScopedEvmServerAccount({ account, network: networkOrRpcUrl, }); }, }; return account; }