@coinbase/cdp-sdk 1.20.0 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +8 -0
  3. package/_cjs/accounts/evm/chainToNetworkMapper.js +33 -0
  4. package/_cjs/accounts/evm/chainToNetworkMapper.js.map +1 -0
  5. package/_cjs/accounts/evm/getBaseNodeRpcUrl.js +38 -0
  6. package/_cjs/accounts/evm/getBaseNodeRpcUrl.js.map +1 -0
  7. package/_cjs/accounts/evm/networkCapabilities.js +91 -0
  8. package/_cjs/accounts/evm/networkCapabilities.js.map +1 -0
  9. package/_cjs/accounts/evm/resolveViemClients.js +2 -35
  10. package/_cjs/accounts/evm/resolveViemClients.js.map +1 -1
  11. package/_cjs/accounts/evm/toEvmServerAccount.js +1 -1
  12. package/_cjs/accounts/evm/toEvmServerAccount.js.map +1 -1
  13. package/_cjs/accounts/evm/toEvmSmartAccount.js +2 -2
  14. package/_cjs/accounts/evm/toEvmSmartAccount.js.map +1 -1
  15. package/_cjs/accounts/evm/toNetworkScopedEvmServerAccount.js +86 -32
  16. package/_cjs/accounts/evm/toNetworkScopedEvmServerAccount.js.map +1 -1
  17. package/_cjs/accounts/evm/toNetworkScopedEvmSmartAccount.js +126 -2
  18. package/_cjs/accounts/evm/toNetworkScopedEvmSmartAccount.js.map +1 -1
  19. package/_cjs/actions/evm/sendUserOperation.js +8 -1
  20. package/_cjs/actions/evm/sendUserOperation.js.map +1 -1
  21. package/_cjs/actions/evm/transfer/transferWithViem.js +2 -1
  22. package/_cjs/actions/evm/transfer/transferWithViem.js.map +1 -1
  23. package/_cjs/client/evm/evm.js +2 -2
  24. package/_cjs/client/evm/evm.js.map +1 -1
  25. package/_cjs/client/solana/solana.js +74 -0
  26. package/_cjs/client/solana/solana.js.map +1 -1
  27. package/_cjs/constants.js +18 -1
  28. package/_cjs/constants.js.map +1 -1
  29. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js +10 -1
  30. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
  31. package/_cjs/version.js +1 -1
  32. package/_esm/accounts/evm/chainToNetworkMapper.js +30 -0
  33. package/_esm/accounts/evm/chainToNetworkMapper.js.map +1 -0
  34. package/_esm/accounts/evm/getBaseNodeRpcUrl.js +35 -0
  35. package/_esm/accounts/evm/getBaseNodeRpcUrl.js.map +1 -0
  36. package/_esm/accounts/evm/networkCapabilities.js +86 -0
  37. package/_esm/accounts/evm/networkCapabilities.js.map +1 -0
  38. package/_esm/accounts/evm/resolveViemClients.js +1 -34
  39. package/_esm/accounts/evm/resolveViemClients.js.map +1 -1
  40. package/_esm/accounts/evm/toEvmServerAccount.js +1 -1
  41. package/_esm/accounts/evm/toEvmServerAccount.js.map +1 -1
  42. package/_esm/accounts/evm/toEvmSmartAccount.js +2 -2
  43. package/_esm/accounts/evm/toEvmSmartAccount.js.map +1 -1
  44. package/_esm/accounts/evm/toNetworkScopedEvmServerAccount.js +87 -33
  45. package/_esm/accounts/evm/toNetworkScopedEvmServerAccount.js.map +1 -1
  46. package/_esm/accounts/evm/toNetworkScopedEvmSmartAccount.js +126 -2
  47. package/_esm/accounts/evm/toNetworkScopedEvmSmartAccount.js.map +1 -1
  48. package/_esm/actions/evm/sendUserOperation.js +8 -1
  49. package/_esm/actions/evm/sendUserOperation.js.map +1 -1
  50. package/_esm/actions/evm/transfer/transferWithViem.js +2 -1
  51. package/_esm/actions/evm/transfer/transferWithViem.js.map +1 -1
  52. package/_esm/client/evm/evm.js +2 -2
  53. package/_esm/client/evm/evm.js.map +1 -1
  54. package/_esm/client/solana/solana.js +71 -0
  55. package/_esm/client/solana/solana.js.map +1 -1
  56. package/_esm/constants.js +17 -0
  57. package/_esm/constants.js.map +1 -1
  58. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js +8 -0
  59. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
  60. package/_esm/version.js +1 -1
  61. package/_types/accounts/evm/chainToNetworkMapper.d.ts +11 -0
  62. package/_types/accounts/evm/chainToNetworkMapper.d.ts.map +1 -0
  63. package/_types/accounts/evm/getBaseNodeRpcUrl.d.ts +8 -0
  64. package/_types/accounts/evm/getBaseNodeRpcUrl.d.ts.map +1 -0
  65. package/_types/accounts/evm/networkCapabilities.d.ts +103 -0
  66. package/_types/accounts/evm/networkCapabilities.d.ts.map +1 -0
  67. package/_types/accounts/evm/resolveViemClients.d.ts.map +1 -1
  68. package/_types/accounts/evm/toEvmServerAccount.d.ts.map +1 -1
  69. package/_types/accounts/evm/toEvmSmartAccount.d.ts.map +1 -1
  70. package/_types/accounts/evm/toNetworkScopedEvmServerAccount.d.ts +3 -3
  71. package/_types/accounts/evm/toNetworkScopedEvmServerAccount.d.ts.map +1 -1
  72. package/_types/accounts/evm/toNetworkScopedEvmSmartAccount.d.ts +9 -6
  73. package/_types/accounts/evm/toNetworkScopedEvmSmartAccount.d.ts.map +1 -1
  74. package/_types/accounts/evm/types.d.ts +109 -14
  75. package/_types/accounts/evm/types.d.ts.map +1 -1
  76. package/_types/actions/evm/sendUserOperation.d.ts.map +1 -1
  77. package/_types/actions/evm/transfer/transferWithViem.d.ts +1 -1
  78. package/_types/actions/evm/transfer/transferWithViem.d.ts.map +1 -1
  79. package/_types/client/evm/evm.d.ts.map +1 -1
  80. package/_types/client/evm/evm.types.d.ts +1 -1
  81. package/_types/client/evm/evm.types.d.ts.map +1 -1
  82. package/_types/client/solana/solana.d.ts +40 -1
  83. package/_types/client/solana/solana.d.ts.map +1 -1
  84. package/_types/client/solana/solana.types.d.ts +15 -1
  85. package/_types/client/solana/solana.types.d.ts.map +1 -1
  86. package/_types/constants.d.ts +4 -0
  87. package/_types/constants.d.ts.map +1 -1
  88. package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts +5 -0
  89. package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts.map +1 -1
  90. package/_types/openapi-client/index.d.ts +10 -0
  91. package/_types/openapi-client/index.d.ts.map +1 -1
  92. package/_types/version.d.ts +1 -1
  93. package/accounts/evm/chainToNetworkMapper.ts +37 -0
  94. package/accounts/evm/getBaseNodeRpcUrl.ts +40 -0
  95. package/accounts/evm/networkCapabilities.ts +117 -0
  96. package/accounts/evm/resolveViemClients.ts +1 -38
  97. package/accounts/evm/toEvmServerAccount.ts +3 -3
  98. package/accounts/evm/toEvmSmartAccount.ts +3 -3
  99. package/accounts/evm/toNetworkScopedEvmServerAccount.ts +116 -44
  100. package/accounts/evm/toNetworkScopedEvmSmartAccount.ts +178 -11
  101. package/accounts/evm/types.ts +253 -25
  102. package/actions/evm/sendUserOperation.ts +9 -1
  103. package/actions/evm/transfer/transferWithViem.ts +4 -3
  104. package/client/evm/evm.ts +2 -2
  105. package/client/evm/evm.types.ts +1 -1
  106. package/client/solana/solana.ts +89 -0
  107. package/client/solana/solana.types.ts +16 -0
  108. package/constants.ts +18 -0
  109. package/openapi-client/generated/solana-accounts/solana-accounts.ts +20 -0
  110. package/package.json +1 -1
  111. package/version.ts +1 -1
  112. package/_cjs/client/evm/constants.js +0 -21
  113. package/_cjs/client/evm/constants.js.map +0 -1
  114. package/_esm/client/evm/constants.js +0 -18
  115. package/_esm/client/evm/constants.js.map +0 -1
  116. package/_types/client/evm/constants.d.ts +0 -5
  117. package/_types/client/evm/constants.d.ts.map +0 -1
  118. package/client/evm/constants.ts +0 -17
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Centralized configuration for network capabilities.
3
+ * This defines which methods are available on which networks.
4
+ */
5
+
6
+ /**
7
+ * Network capabilities configuration.
8
+ * Each network has a set of boolean flags indicating which methods are supported.
9
+ */
10
+ export const NETWORK_CAPABILITIES = {
11
+ base: {
12
+ listTokenBalances: true,
13
+ requestFaucet: false,
14
+ quoteFund: true,
15
+ fund: true,
16
+ waitForFundOperationReceipt: true,
17
+ transfer: true,
18
+ sendTransaction: true,
19
+ quoteSwap: true,
20
+ swap: true,
21
+ },
22
+ "base-sepolia": {
23
+ listTokenBalances: true,
24
+ requestFaucet: true,
25
+ quoteFund: false,
26
+ fund: false,
27
+ waitForFundOperationReceipt: false,
28
+ transfer: true,
29
+ sendTransaction: true,
30
+ quoteSwap: false,
31
+ swap: false,
32
+ },
33
+ ethereum: {
34
+ listTokenBalances: true,
35
+ requestFaucet: false,
36
+ quoteFund: false, // Only base is supported for quoteFund
37
+ fund: false, // Only base is supported for fund
38
+ waitForFundOperationReceipt: false,
39
+ transfer: true,
40
+ sendTransaction: true,
41
+ quoteSwap: true,
42
+ swap: true,
43
+ },
44
+ "ethereum-sepolia": {
45
+ listTokenBalances: false,
46
+ requestFaucet: true,
47
+ quoteFund: false,
48
+ fund: false,
49
+ waitForFundOperationReceipt: false,
50
+ transfer: true,
51
+ sendTransaction: true,
52
+ quoteSwap: false,
53
+ swap: false,
54
+ },
55
+ "ethereum-hoodi": {
56
+ listTokenBalances: false,
57
+ requestFaucet: true,
58
+ quoteFund: false,
59
+ fund: false,
60
+ waitForFundOperationReceipt: false,
61
+ transfer: false,
62
+ sendTransaction: true, // Always available (uses wallet client for non-base networks)
63
+ quoteSwap: false,
64
+ swap: false,
65
+ },
66
+ } as const;
67
+
68
+ /**
69
+ * Type for a network name from the capabilities configuration
70
+ */
71
+ export type NetworkName = keyof typeof NETWORK_CAPABILITIES;
72
+
73
+ /**
74
+ * Type for method names
75
+ */
76
+ export type MethodName = keyof (typeof NETWORK_CAPABILITIES)[NetworkName];
77
+
78
+ /**
79
+ * Helper to get networks that support a specific method
80
+ *
81
+ * @param method - The method name to check support for
82
+ * @returns An array of network names that support the method
83
+ */
84
+ export function getNetworksSupportingMethod(method: MethodName): NetworkName[] {
85
+ return (Object.keys(NETWORK_CAPABILITIES) as NetworkName[]).filter(
86
+ network => NETWORK_CAPABILITIES[network][method],
87
+ );
88
+ }
89
+
90
+ /**
91
+ * Helper to check if a network supports a method
92
+ *
93
+ * @param method - The method name to check
94
+ * @param network - The network name to check
95
+ * @returns True if the network supports the method, false otherwise
96
+ */
97
+ export function isMethodSupportedOnNetwork(method: MethodName, network: string): boolean {
98
+ const networkConfig = NETWORK_CAPABILITIES[network as NetworkName];
99
+ return networkConfig ? networkConfig[method] : false;
100
+ }
101
+
102
+ /**
103
+ * Type helper to extract networks supporting a specific method
104
+ */
105
+ export type NetworksSupporting<M extends MethodName> = {
106
+ [N in NetworkName]: (typeof NETWORK_CAPABILITIES)[N][M] extends true ? N : never;
107
+ }[NetworkName];
108
+
109
+ // Export specific network types for each method
110
+ export type ListTokenBalancesNetworks = NetworksSupporting<"listTokenBalances">;
111
+ export type RequestFaucetNetworks = NetworksSupporting<"requestFaucet">;
112
+ export type QuoteFundNetworks = NetworksSupporting<"quoteFund">;
113
+ export type FundNetworks = NetworksSupporting<"fund">;
114
+ export type TransferNetworks = NetworksSupporting<"transfer">;
115
+ export type SendTransactionNetworks = NetworksSupporting<"sendTransaction">;
116
+ export type QuoteSwapNetworks = NetworksSupporting<"quoteSwap">;
117
+ export type SwapNetworks = NetworksSupporting<"swap">;
@@ -11,8 +11,7 @@ import {
11
11
  import { toAccount } from "viem/accounts";
12
12
  import * as chains from "viem/chains";
13
13
 
14
- import { generateJwt } from "../../auth/utils/jwt.js";
15
- import { config } from "../../openapi-client/cdpApiClient.js";
14
+ import { getBaseNodeRpcUrl } from "./getBaseNodeRpcUrl.js";
16
15
 
17
16
  import type { EvmAccount } from "./types.js";
18
17
 
@@ -135,42 +134,6 @@ export type ResolvedViemClients = {
135
134
  walletClient: WalletClient<Transport, Chain, Account>;
136
135
  };
137
136
 
138
- /**
139
- * Get the base node RPC URL for a given network
140
- *
141
- * @param network - The network identifier
142
- * @returns The base node RPC URL or undefined if the network is not supported
143
- */
144
- async function getBaseNodeRpcUrl(network: "base" | "base-sepolia"): Promise<string | undefined> {
145
- if (!config) {
146
- return;
147
- }
148
-
149
- try {
150
- const basePath = config.basePath?.replace("/platform", "");
151
-
152
- const jwt = await generateJwt({
153
- apiKeyId: config.apiKeyId,
154
- apiKeySecret: config.apiKeySecret,
155
- requestMethod: "GET",
156
- requestHost: basePath.replace("https://", ""),
157
- requestPath: "/apikeys/v1/tokens/active",
158
- });
159
-
160
- const response = await fetch(`${basePath}/apikeys/v1/tokens/active`, {
161
- headers: {
162
- Authorization: `Bearer ${jwt}`,
163
- "Content-Type": "application/json",
164
- },
165
- });
166
-
167
- const json = await response.json();
168
- return `${basePath}/rpc/v1/${network}/${json.id}`;
169
- } catch {
170
- return;
171
- }
172
- }
173
-
174
137
  /**
175
138
  * Resolves viem clients based on a network identifier or Node URL.
176
139
  *
@@ -33,7 +33,7 @@ import { sendSwapTransaction } from "../../actions/evm/swap/sendSwapTransaction.
33
33
  import { accountTransferStrategy } from "../../actions/evm/transfer/accountTransferStrategy.js";
34
34
  import { transfer } from "../../actions/evm/transfer/transfer.js";
35
35
 
36
- import type { EvmServerAccount } from "./types.js";
36
+ import type { EvmServerAccount, NetworkOrRpcUrl } from "./types.js";
37
37
  import type {
38
38
  SendTransactionOptions,
39
39
  TransactionResult,
@@ -169,8 +169,8 @@ export function toEvmServerAccount(
169
169
  name: options.account.name,
170
170
  type: "evm-server",
171
171
  policies: options.account.policies,
172
- useNetwork: async (networkOrRpcUrl: string) => {
173
- return toNetworkScopedEvmServerAccount(apiClient, {
172
+ useNetwork: async <Network extends NetworkOrRpcUrl>(networkOrRpcUrl: Network) => {
173
+ return toNetworkScopedEvmServerAccount({
174
174
  account,
175
175
  network: networkOrRpcUrl,
176
176
  });
@@ -35,7 +35,7 @@ import {
35
35
  } from "../../actions/evm/waitForUserOperation.js";
36
36
  import { GetUserOperationOptions, UserOperation } from "../../client/evm/evm.types.js";
37
37
 
38
- import type { EvmAccount, EvmSmartAccount } from "./types.js";
38
+ import type { EvmAccount, EvmSmartAccount, KnownEvmNetworks } from "./types.js";
39
39
  import type {
40
40
  SmartAccountQuoteSwapOptions,
41
41
  SmartAccountQuoteSwapResult,
@@ -156,11 +156,11 @@ export function toEvmSmartAccount(
156
156
 
157
157
  name: options.smartAccount.name,
158
158
  type: "evm-smart",
159
- __experimental_useNetwork: async (networkOrRpcUrl: string) => {
159
+ useNetwork: async <Network extends KnownEvmNetworks>(network: Network) => {
160
160
  return toNetworkScopedEvmSmartAccount(apiClient, {
161
161
  smartAccount: account,
162
162
  owner: options.owner,
163
- network: networkOrRpcUrl,
163
+ network,
164
164
  });
165
165
  },
166
166
  };
@@ -1,14 +1,27 @@
1
1
  import { WaitForTransactionReceiptParameters } from "viem";
2
- import { base, baseSepolia, sepolia } from "viem/chains";
2
+ import { base, baseSepolia, mainnet, sepolia } from "viem/chains";
3
3
 
4
+ import { mapChainToNetwork } from "./chainToNetworkMapper.js";
5
+ import { isMethodSupportedOnNetwork } from "./networkCapabilities.js";
4
6
  import { resolveViemClients } from "./resolveViemClients.js";
5
- import { RequestFaucetOptions } from "../../actions/evm/requestFaucet.js";
6
- import { TransactionResult } from "../../actions/evm/sendTransaction.js";
7
7
  import { transferWithViem } from "../../actions/evm/transfer/transferWithViem.js";
8
8
 
9
9
  import type { EvmServerAccount, NetworkScopedEvmServerAccount } from "./types.js";
10
- import type { Network } from "../../actions/evm/transfer/types.js";
11
- import type { CdpOpenApiClientType } from "../../openapi-client/index.js";
10
+ import type { FundOptions } from "../../actions/evm/fund/fund.js";
11
+ import type { QuoteFundOptions } from "../../actions/evm/fund/quoteFund.js";
12
+ import type { WaitForFundOperationOptions } from "../../actions/evm/fund/waitForFundOperationReceipt.js";
13
+ import type { ListTokenBalancesOptions } from "../../actions/evm/listTokenBalances.js";
14
+ import type { RequestFaucetOptions } from "../../actions/evm/requestFaucet.js";
15
+ import type {
16
+ SendTransactionOptions,
17
+ TransactionResult,
18
+ } from "../../actions/evm/sendTransaction.js";
19
+ import type { AccountQuoteSwapOptions, AccountSwapOptions } from "../../actions/evm/swap/types.js";
20
+ import type { TransferOptions } from "../../actions/evm/transfer/types.js";
21
+ import type {
22
+ ListEvmTokenBalancesNetwork,
23
+ SendEvmTransactionBodyNetwork,
24
+ } from "../../openapi-client/index.js";
12
25
  import type { Address, TransactionRequestEIP1559 } from "../../types/misc.js";
13
26
 
14
27
  /**
@@ -25,24 +38,26 @@ export type ToNetworkScopedEvmServerAccountOptions = {
25
38
  * Creates a Network-scoped Server-managed EvmAccount instance from an existing EvmAccount.
26
39
  * Use this to interact with previously deployed EvmAccounts on a specific network.
27
40
  *
28
- * @param {CdpOpenApiClientType} apiClient - The API client.
29
41
  * @param {ToNetworkScopedEvmServerAccountOptions} options - Configuration options.
30
42
  * @param {EvmServerAccount} options.account - The EvmServerAccount that was previously created.
31
43
  * @param {string} options.network - The network to scope the account to.
32
44
  * @returns {NetworkScopedEvmServerAccount} A configured NetworkScopedEvmServerAccount instance ready for signing.
33
45
  */
34
- export async function toNetworkScopedEvmServerAccount(
35
- apiClient: CdpOpenApiClientType,
36
- options: ToNetworkScopedEvmServerAccountOptions,
37
- ): Promise<NetworkScopedEvmServerAccount> {
46
+ export async function toNetworkScopedEvmServerAccount<Network extends string>(
47
+ options: ToNetworkScopedEvmServerAccountOptions & { network: Network },
48
+ ): Promise<NetworkScopedEvmServerAccount<Network>> {
38
49
  const { publicClient, walletClient, chain } = await resolveViemClients({
39
50
  networkOrNodeUrl: options.network,
40
51
  account: options.account,
41
52
  });
42
53
 
43
- const shouldUseApi = chain.id === base.id || chain.id === baseSepolia.id;
54
+ const shouldUseApiForSends =
55
+ chain.id === base.id ||
56
+ chain.id === baseSepolia.id ||
57
+ chain.id === mainnet.id ||
58
+ chain.id === sepolia.id;
44
59
 
45
- const account: NetworkScopedEvmServerAccount = {
60
+ const account = {
46
61
  address: options.account.address as Address,
47
62
  network: options.network,
48
63
  signMessage: options.account.signMessage,
@@ -52,35 +67,11 @@ export async function toNetworkScopedEvmServerAccount(
52
67
  name: options.account.name,
53
68
  type: "evm-server",
54
69
  policies: options.account.policies,
55
- requestFaucet: async (faucetOptions: Omit<RequestFaucetOptions, "address" | "network">) => {
56
- if (chain.id !== baseSepolia.id && chain.id !== sepolia.id) {
57
- throw new Error(
58
- "Requesting a faucet is supported only on base-sepolia or ethereum-sepolia",
59
- );
60
- }
61
- return options.account.requestFaucet({
62
- ...faucetOptions,
63
- network: chain.id === baseSepolia.id ? "base-sepolia" : "ethereum-sepolia",
64
- });
65
- },
66
- transfer: async transferArgs => {
67
- if (shouldUseApi) {
68
- return options.account.transfer({
69
- ...transferArgs,
70
- network: (chain.id === base.id ? "base" : "base-sepolia") as Network,
71
- });
72
- } else {
73
- return transferWithViem(walletClient, account, {
74
- ...transferArgs,
75
- network: options.network as Network,
76
- });
77
- }
78
- },
79
- sendTransaction: async txOpts => {
80
- if (shouldUseApi) {
70
+ sendTransaction: async (txOpts: Omit<SendTransactionOptions, "address" | "network">) => {
71
+ if (shouldUseApiForSends) {
81
72
  return options.account.sendTransaction({
82
73
  ...txOpts,
83
- network: chain.id === base.id ? "base" : "base-sepolia",
74
+ network: mapChainToNetwork(chain) as SendEvmTransactionBodyNetwork,
84
75
  });
85
76
  } else {
86
77
  const hash = await walletClient.sendTransaction(
@@ -89,17 +80,98 @@ export async function toNetworkScopedEvmServerAccount(
89
80
  return { transactionHash: hash };
90
81
  }
91
82
  },
83
+ transfer: async (transferArgs: Omit<TransferOptions, "address" | "network">) => {
84
+ if (shouldUseApiForSends) {
85
+ return options.account.transfer({
86
+ ...transferArgs,
87
+ network: mapChainToNetwork(chain) as SendEvmTransactionBodyNetwork,
88
+ });
89
+ } else {
90
+ return transferWithViem(walletClient, account, transferArgs);
91
+ }
92
+ },
92
93
  waitForTransactionReceipt: async (
93
- options: WaitForTransactionReceiptParameters | TransactionResult,
94
+ waitOptions: WaitForTransactionReceiptParameters | TransactionResult,
94
95
  ) => {
95
- if ("transactionHash" in options) {
96
+ if ("transactionHash" in waitOptions) {
96
97
  return publicClient.waitForTransactionReceipt({
97
- hash: options.transactionHash,
98
+ hash: waitOptions.transactionHash,
98
99
  });
99
100
  }
100
- return publicClient.waitForTransactionReceipt(options);
101
+ return publicClient.waitForTransactionReceipt(waitOptions);
101
102
  },
102
- };
103
+ } as NetworkScopedEvmServerAccount<Network>;
104
+
105
+ if (isMethodSupportedOnNetwork("listTokenBalances", options.network)) {
106
+ Object.assign(account, {
107
+ listTokenBalances: async (
108
+ listTokenBalancesOptions: Omit<ListTokenBalancesOptions, "address" | "network">,
109
+ ) => {
110
+ return options.account.listTokenBalances({
111
+ ...listTokenBalancesOptions,
112
+ network: options.network as ListEvmTokenBalancesNetwork,
113
+ });
114
+ },
115
+ });
116
+ }
117
+
118
+ if (isMethodSupportedOnNetwork("requestFaucet", options.network)) {
119
+ Object.assign(account, {
120
+ requestFaucet: async (faucetOptions: Omit<RequestFaucetOptions, "address" | "network">) => {
121
+ return options.account.requestFaucet({
122
+ ...faucetOptions,
123
+ network: chain.id === baseSepolia.id ? "base-sepolia" : "ethereum-sepolia",
124
+ });
125
+ },
126
+ });
127
+ }
128
+
129
+ if (isMethodSupportedOnNetwork("quoteFund", options.network)) {
130
+ Object.assign(account, {
131
+ quoteFund: async (quoteFundOptions: Omit<QuoteFundOptions, "address">) => {
132
+ return options.account.quoteFund({
133
+ ...quoteFundOptions,
134
+ });
135
+ },
136
+ });
137
+ }
138
+
139
+ if (isMethodSupportedOnNetwork("fund", options.network)) {
140
+ Object.assign(account, {
141
+ fund: async (fundOptions: Omit<FundOptions, "address">) => {
142
+ return options.account.fund({
143
+ ...fundOptions,
144
+ });
145
+ },
146
+ waitForFundOperationReceipt: async (waitOptions: WaitForFundOperationOptions) => {
147
+ return options.account.waitForFundOperationReceipt(waitOptions);
148
+ },
149
+ });
150
+ }
151
+
152
+ if (isMethodSupportedOnNetwork("transfer", options.network)) {
153
+ Object.assign(account, {
154
+ transfer: async (transferOptions: TransferOptions) => {
155
+ return options.account.transfer(transferOptions);
156
+ },
157
+ });
158
+ }
159
+
160
+ if (isMethodSupportedOnNetwork("quoteSwap", options.network)) {
161
+ Object.assign(account, {
162
+ quoteSwap: async (quoteSwapOptions: AccountQuoteSwapOptions) => {
163
+ return options.account.quoteSwap(quoteSwapOptions);
164
+ },
165
+ });
166
+ }
167
+
168
+ if (isMethodSupportedOnNetwork("swap", options.network)) {
169
+ Object.assign(account, {
170
+ swap: async (swapOptions: AccountSwapOptions) => {
171
+ return options.account.swap(swapOptions);
172
+ },
173
+ });
174
+ }
103
175
 
104
176
  return account;
105
177
  }
@@ -1,14 +1,52 @@
1
- import type { EvmAccount, EvmSmartAccount, NetworkScopedEvmSmartAccount } from "./types.js";
2
- import type { CdpOpenApiClientType } from "../../openapi-client/index.js";
1
+ import { getBaseNodeRpcUrl } from "./getBaseNodeRpcUrl.js";
2
+ import { isMethodSupportedOnNetwork } from "./networkCapabilities.js";
3
+ import { fund } from "../../actions/evm/fund/fund.js";
4
+ import { quoteFund } from "../../actions/evm/fund/quoteFund.js";
5
+ import { waitForFundOperationReceipt } from "../../actions/evm/fund/waitForFundOperationReceipt.js";
6
+ import { getUserOperation } from "../../actions/evm/getUserOperation.js";
7
+ import { listTokenBalances } from "../../actions/evm/listTokenBalances.js";
8
+ import { requestFaucet } from "../../actions/evm/requestFaucet.js";
9
+ import { sendUserOperation } from "../../actions/evm/sendUserOperation.js";
10
+ import { createSwapQuote } from "../../actions/evm/swap/createSwapQuote.js";
11
+ import { sendSwapOperation } from "../../actions/evm/swap/sendSwapOperation.js";
12
+ import { smartAccountTransferStrategy } from "../../actions/evm/transfer/smartAccountTransferStrategy.js";
13
+ import { transfer } from "../../actions/evm/transfer/transfer.js";
14
+ import { waitForUserOperation } from "../../actions/evm/waitForUserOperation.js";
15
+
16
+ import type {
17
+ EvmAccount,
18
+ EvmSmartAccount,
19
+ KnownEvmNetworks,
20
+ NetworkScopedEvmSmartAccount,
21
+ } from "./types.js";
22
+ import type { FundOptions } from "../../actions/evm/fund/fund.js";
23
+ import type { QuoteFundOptions } from "../../actions/evm/fund/quoteFund.js";
24
+ import type { WaitForFundOperationOptions } from "../../actions/evm/fund/waitForFundOperationReceipt.js";
25
+ import type { ListTokenBalancesOptions } from "../../actions/evm/listTokenBalances.js";
26
+ import type { RequestFaucetOptions } from "../../actions/evm/requestFaucet.js";
27
+ import type { SendUserOperationOptions } from "../../actions/evm/sendUserOperation.js";
28
+ import type {
29
+ SmartAccountQuoteSwapOptions,
30
+ SmartAccountSwapNetwork,
31
+ SmartAccountSwapOptions,
32
+ } from "../../actions/evm/swap/types.js";
33
+ import type { SmartAccountTransferOptions } from "../../actions/evm/transfer/types.js";
34
+ import type { WaitForUserOperationOptions } from "../../actions/evm/waitForUserOperation.js";
35
+ import type { GetUserOperationOptions } from "../../client/evm/evm.types.js";
36
+ import type {
37
+ CdpOpenApiClientType,
38
+ EvmUserOperationNetwork,
39
+ ListEvmTokenBalancesNetwork,
40
+ } from "../../openapi-client/index.js";
3
41
 
4
42
  /**
5
- * Options for converting a pre-existing EvmSmartAccount and owner to a EvmSmartAccount
43
+ * Options for converting a pre-existing EvmSmartAccount and owner to a NetworkScopedEvmSmartAccount
6
44
  */
7
- export type ToEvmSmartAccountOptions = {
45
+ export type ToNetworkScopedEvmSmartAccountOptions = {
8
46
  /** The pre-existing EvmSmartAccount. */
9
47
  smartAccount: EvmSmartAccount;
10
48
  /** The network to scope the smart account object to. */
11
- network: string;
49
+ network: KnownEvmNetworks;
12
50
  /** The owner of the smart account. */
13
51
  owner: EvmAccount;
14
52
  };
@@ -20,22 +58,151 @@ export type ToEvmSmartAccountOptions = {
20
58
  * The owner must be the original owner of the evm smart account.
21
59
  *
22
60
  * @param {CdpOpenApiClientType} apiClient - The API client.
23
- * @param {ToEvmSmartAccountOptions} options - Configuration options.
61
+ * @param {ToNetworkScopedEvmSmartAccountOptions} options - Configuration options.
24
62
  * @param {EvmSmartAccount} options.smartAccount - The deployed evm smart account.
25
63
  * @param {EvmAccount} options.owner - The owner which signs for the smart account.
64
+ * @param {KnownEvmNetworks} options.network - The network to scope the smart account to.
26
65
  * @returns {NetworkScopedEvmSmartAccount} A configured NetworkScopedEvmSmartAccount instance ready for user operation submission.
27
66
  */
28
- export function toNetworkScopedEvmSmartAccount(
67
+ export async function toNetworkScopedEvmSmartAccount<Network extends KnownEvmNetworks>(
29
68
  apiClient: CdpOpenApiClientType,
30
- options: ToEvmSmartAccountOptions,
31
- ): NetworkScopedEvmSmartAccount {
32
- const account: NetworkScopedEvmSmartAccount = {
69
+ options: ToNetworkScopedEvmSmartAccountOptions & { network: Network },
70
+ ): Promise<NetworkScopedEvmSmartAccount<Network>> {
71
+ const paymasterUrl = await (async () => {
72
+ if (options.network === "base") {
73
+ return getBaseNodeRpcUrl(options.network);
74
+ }
75
+ return undefined;
76
+ })();
77
+
78
+ const account = {
33
79
  address: options.smartAccount.address,
34
80
  network: options.network,
35
81
  owners: [options.owner],
36
82
  name: options.smartAccount.name,
37
83
  type: "evm-smart",
38
- };
84
+ sendUserOperation: async (
85
+ userOpOptions: Omit<SendUserOperationOptions<unknown[]>, "smartAccount" | "network">,
86
+ ) => {
87
+ return sendUserOperation(apiClient, {
88
+ ...userOpOptions,
89
+ smartAccount: options.smartAccount,
90
+ network: options.network as EvmUserOperationNetwork,
91
+ paymasterUrl: userOpOptions.paymasterUrl ?? paymasterUrl,
92
+ });
93
+ },
94
+ waitForUserOperation: async (
95
+ waitOptions: Omit<WaitForUserOperationOptions, "smartAccountAddress">,
96
+ ) => {
97
+ return waitForUserOperation(apiClient, {
98
+ ...waitOptions,
99
+ smartAccountAddress: options.smartAccount.address,
100
+ });
101
+ },
102
+ getUserOperation: async (getOptions: Omit<GetUserOperationOptions, "smartAccount">) => {
103
+ return getUserOperation(apiClient, {
104
+ ...getOptions,
105
+ smartAccount: options.smartAccount,
106
+ });
107
+ },
108
+ } as NetworkScopedEvmSmartAccount<Network>;
109
+
110
+ if (isMethodSupportedOnNetwork("transfer", options.network)) {
111
+ Object.assign(account, {
112
+ transfer: async (transferOptions: Omit<SmartAccountTransferOptions, "network">) => {
113
+ return transfer(
114
+ apiClient,
115
+ options.smartAccount,
116
+ {
117
+ ...transferOptions,
118
+ network: options.network as EvmUserOperationNetwork,
119
+ paymasterUrl: transferOptions.paymasterUrl ?? paymasterUrl,
120
+ },
121
+ smartAccountTransferStrategy,
122
+ );
123
+ },
124
+ });
125
+ }
126
+
127
+ if (isMethodSupportedOnNetwork("listTokenBalances", options.network)) {
128
+ Object.assign(account, {
129
+ listTokenBalances: async (
130
+ listOptions: Omit<ListTokenBalancesOptions, "address" | "network">,
131
+ ) => {
132
+ return listTokenBalances(apiClient, {
133
+ ...listOptions,
134
+ address: options.smartAccount.address,
135
+ network: options.network as ListEvmTokenBalancesNetwork,
136
+ });
137
+ },
138
+ });
139
+ }
140
+
141
+ if (isMethodSupportedOnNetwork("requestFaucet", options.network)) {
142
+ Object.assign(account, {
143
+ requestFaucet: async (faucetOptions: Omit<RequestFaucetOptions, "address" | "network">) => {
144
+ return requestFaucet(apiClient, {
145
+ ...faucetOptions,
146
+ address: options.smartAccount.address,
147
+ network: options.network as "base-sepolia" | "ethereum-sepolia",
148
+ });
149
+ },
150
+ });
151
+ }
152
+
153
+ if (isMethodSupportedOnNetwork("quoteFund", options.network)) {
154
+ Object.assign(account, {
155
+ quoteFund: async (quoteOptions: Omit<QuoteFundOptions, "address">) => {
156
+ return quoteFund(apiClient, {
157
+ ...quoteOptions,
158
+ address: options.smartAccount.address,
159
+ });
160
+ },
161
+ });
162
+ }
163
+
164
+ if (isMethodSupportedOnNetwork("fund", options.network)) {
165
+ Object.assign(account, {
166
+ fund: async (fundOptions: Omit<FundOptions, "address">) => {
167
+ return fund(apiClient, {
168
+ ...fundOptions,
169
+ address: options.smartAccount.address,
170
+ });
171
+ },
172
+ waitForFundOperationReceipt: async (waitOptions: WaitForFundOperationOptions) => {
173
+ return waitForFundOperationReceipt(apiClient, waitOptions);
174
+ },
175
+ });
176
+ }
177
+
178
+ if (isMethodSupportedOnNetwork("quoteSwap", options.network)) {
179
+ Object.assign(account, {
180
+ quoteSwap: async (quoteSwapOptions: SmartAccountQuoteSwapOptions) => {
181
+ return createSwapQuote(apiClient, {
182
+ ...quoteSwapOptions,
183
+ taker: options.smartAccount.address,
184
+ signerAddress: options.owner.address,
185
+ smartAccount: options.smartAccount,
186
+ network: options.network as SmartAccountSwapNetwork,
187
+ });
188
+ },
189
+ });
190
+ }
191
+
192
+ if (isMethodSupportedOnNetwork("swap", options.network)) {
193
+ Object.assign(account, {
194
+ swap: async (swapOptions: SmartAccountSwapOptions) => {
195
+ return sendSwapOperation(apiClient, {
196
+ ...swapOptions,
197
+ smartAccount: options.smartAccount,
198
+ taker: options.smartAccount.address,
199
+ signerAddress: options.owner.address,
200
+ network: options.network as SmartAccountSwapNetwork,
201
+ paymasterUrl: swapOptions.paymasterUrl ?? paymasterUrl,
202
+ });
203
+ },
204
+ });
205
+ }
39
206
 
40
207
  return account;
41
208
  }