@coinbase/cdp-sdk 1.20.0 → 1.22.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.
- package/CHANGELOG.md +32 -0
- package/README.md +8 -0
- package/_cjs/accounts/evm/chainToNetworkMapper.js +33 -0
- package/_cjs/accounts/evm/chainToNetworkMapper.js.map +1 -0
- package/_cjs/accounts/evm/getBaseNodeRpcUrl.js +38 -0
- package/_cjs/accounts/evm/getBaseNodeRpcUrl.js.map +1 -0
- package/_cjs/accounts/evm/networkCapabilities.js +91 -0
- package/_cjs/accounts/evm/networkCapabilities.js.map +1 -0
- package/_cjs/accounts/evm/resolveViemClients.js +2 -35
- package/_cjs/accounts/evm/resolveViemClients.js.map +1 -1
- package/_cjs/accounts/evm/toEvmServerAccount.js +1 -1
- package/_cjs/accounts/evm/toEvmServerAccount.js.map +1 -1
- package/_cjs/accounts/evm/toEvmSmartAccount.js +2 -2
- package/_cjs/accounts/evm/toEvmSmartAccount.js.map +1 -1
- package/_cjs/accounts/evm/toNetworkScopedEvmServerAccount.js +86 -32
- package/_cjs/accounts/evm/toNetworkScopedEvmServerAccount.js.map +1 -1
- package/_cjs/accounts/evm/toNetworkScopedEvmSmartAccount.js +126 -2
- package/_cjs/accounts/evm/toNetworkScopedEvmSmartAccount.js.map +1 -1
- package/_cjs/actions/evm/sendUserOperation.js +8 -1
- package/_cjs/actions/evm/sendUserOperation.js.map +1 -1
- package/_cjs/actions/evm/transfer/transferWithViem.js +2 -1
- package/_cjs/actions/evm/transfer/transferWithViem.js.map +1 -1
- package/_cjs/auth/utils/hash.js +17 -0
- package/_cjs/auth/utils/hash.js.map +1 -0
- package/_cjs/auth/utils/jwt.js +20 -55
- package/_cjs/auth/utils/jwt.js.map +1 -1
- package/_cjs/client/cdp.js +6 -0
- package/_cjs/client/cdp.js.map +1 -1
- package/_cjs/client/evm/evm.js +2 -2
- package/_cjs/client/evm/evm.js.map +1 -1
- package/_cjs/client/solana/solana.js +74 -0
- package/_cjs/client/solana/solana.js.map +1 -1
- package/_cjs/constants.js +18 -1
- package/_cjs/constants.js.map +1 -1
- package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js +10 -1
- package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
- package/_cjs/version.js +1 -1
- package/_esm/accounts/evm/chainToNetworkMapper.js +30 -0
- package/_esm/accounts/evm/chainToNetworkMapper.js.map +1 -0
- package/_esm/accounts/evm/getBaseNodeRpcUrl.js +35 -0
- package/_esm/accounts/evm/getBaseNodeRpcUrl.js.map +1 -0
- package/_esm/accounts/evm/networkCapabilities.js +86 -0
- package/_esm/accounts/evm/networkCapabilities.js.map +1 -0
- package/_esm/accounts/evm/resolveViemClients.js +1 -34
- package/_esm/accounts/evm/resolveViemClients.js.map +1 -1
- package/_esm/accounts/evm/toEvmServerAccount.js +1 -1
- package/_esm/accounts/evm/toEvmServerAccount.js.map +1 -1
- package/_esm/accounts/evm/toEvmSmartAccount.js +2 -2
- package/_esm/accounts/evm/toEvmSmartAccount.js.map +1 -1
- package/_esm/accounts/evm/toNetworkScopedEvmServerAccount.js +87 -33
- package/_esm/accounts/evm/toNetworkScopedEvmServerAccount.js.map +1 -1
- package/_esm/accounts/evm/toNetworkScopedEvmSmartAccount.js +126 -2
- package/_esm/accounts/evm/toNetworkScopedEvmSmartAccount.js.map +1 -1
- package/_esm/actions/evm/sendUserOperation.js +8 -1
- package/_esm/actions/evm/sendUserOperation.js.map +1 -1
- package/_esm/actions/evm/transfer/transferWithViem.js +2 -1
- package/_esm/actions/evm/transfer/transferWithViem.js.map +1 -1
- package/_esm/auth/utils/hash.js +13 -0
- package/_esm/auth/utils/hash.js.map +1 -0
- package/_esm/auth/utils/jwt.js +20 -22
- package/_esm/auth/utils/jwt.js.map +1 -1
- package/_esm/client/cdp.js +6 -0
- package/_esm/client/cdp.js.map +1 -1
- package/_esm/client/evm/evm.js +2 -2
- package/_esm/client/evm/evm.js.map +1 -1
- package/_esm/client/solana/solana.js +71 -0
- package/_esm/client/solana/solana.js.map +1 -1
- package/_esm/constants.js +17 -0
- package/_esm/constants.js.map +1 -1
- package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js +8 -0
- package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
- package/_esm/version.js +1 -1
- package/_types/accounts/evm/chainToNetworkMapper.d.ts +11 -0
- package/_types/accounts/evm/chainToNetworkMapper.d.ts.map +1 -0
- package/_types/accounts/evm/getBaseNodeRpcUrl.d.ts +8 -0
- package/_types/accounts/evm/getBaseNodeRpcUrl.d.ts.map +1 -0
- package/_types/accounts/evm/networkCapabilities.d.ts +103 -0
- package/_types/accounts/evm/networkCapabilities.d.ts.map +1 -0
- package/_types/accounts/evm/resolveViemClients.d.ts.map +1 -1
- package/_types/accounts/evm/toEvmServerAccount.d.ts.map +1 -1
- package/_types/accounts/evm/toEvmSmartAccount.d.ts.map +1 -1
- package/_types/accounts/evm/toNetworkScopedEvmServerAccount.d.ts +3 -3
- package/_types/accounts/evm/toNetworkScopedEvmServerAccount.d.ts.map +1 -1
- package/_types/accounts/evm/toNetworkScopedEvmSmartAccount.d.ts +9 -6
- package/_types/accounts/evm/toNetworkScopedEvmSmartAccount.d.ts.map +1 -1
- package/_types/accounts/evm/types.d.ts +109 -14
- package/_types/accounts/evm/types.d.ts.map +1 -1
- package/_types/actions/evm/fund/fund.d.ts +1 -1
- package/_types/actions/evm/fund/fund.d.ts.map +1 -1
- package/_types/actions/evm/fund/quoteFund.d.ts +1 -1
- package/_types/actions/evm/fund/quoteFund.d.ts.map +1 -1
- package/_types/actions/evm/sendUserOperation.d.ts.map +1 -1
- package/_types/actions/evm/transfer/transferWithViem.d.ts +1 -1
- package/_types/actions/evm/transfer/transferWithViem.d.ts.map +1 -1
- package/_types/auth/utils/hash.d.ts +9 -0
- package/_types/auth/utils/hash.d.ts.map +1 -0
- package/_types/auth/utils/jwt.d.ts.map +1 -1
- package/_types/client/cdp.d.ts.map +1 -1
- package/_types/client/evm/evm.d.ts.map +1 -1
- package/_types/client/evm/evm.types.d.ts +1 -1
- package/_types/client/evm/evm.types.d.ts.map +1 -1
- package/_types/client/solana/solana.d.ts +40 -1
- package/_types/client/solana/solana.d.ts.map +1 -1
- package/_types/client/solana/solana.types.d.ts +15 -1
- package/_types/client/solana/solana.types.d.ts.map +1 -1
- package/_types/constants.d.ts +4 -0
- package/_types/constants.d.ts.map +1 -1
- package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts +5 -0
- package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts.map +1 -1
- package/_types/openapi-client/index.d.ts +10 -0
- package/_types/openapi-client/index.d.ts.map +1 -1
- package/_types/policies/schema.d.ts +24 -24
- package/_types/version.d.ts +1 -1
- package/accounts/evm/chainToNetworkMapper.ts +37 -0
- package/accounts/evm/getBaseNodeRpcUrl.ts +40 -0
- package/accounts/evm/networkCapabilities.ts +117 -0
- package/accounts/evm/resolveViemClients.ts +1 -38
- package/accounts/evm/toEvmServerAccount.ts +3 -3
- package/accounts/evm/toEvmSmartAccount.ts +3 -3
- package/accounts/evm/toNetworkScopedEvmServerAccount.ts +116 -44
- package/accounts/evm/toNetworkScopedEvmSmartAccount.ts +178 -11
- package/accounts/evm/types.ts +253 -25
- package/actions/evm/fund/fund.ts +1 -1
- package/actions/evm/fund/quoteFund.ts +1 -1
- package/actions/evm/sendUserOperation.ts +9 -1
- package/actions/evm/transfer/transferWithViem.ts +4 -3
- package/auth/utils/hash.ts +13 -0
- package/auth/utils/jwt.ts +21 -24
- package/client/cdp.ts +9 -0
- package/client/evm/evm.ts +2 -2
- package/client/evm/evm.types.ts +1 -1
- package/client/solana/solana.ts +89 -0
- package/client/solana/solana.types.ts +16 -0
- package/constants.ts +18 -0
- package/openapi-client/generated/solana-accounts/solana-accounts.ts +20 -0
- package/package.json +2 -1
- package/version.ts +1 -1
- package/_cjs/client/evm/constants.js +0 -21
- package/_cjs/client/evm/constants.js.map +0 -1
- package/_esm/client/evm/constants.js +0 -18
- package/_esm/client/evm/constants.js.map +0 -1
- package/_types/client/evm/constants.d.ts +0 -5
- package/_types/client/evm/constants.d.ts.map +0 -1
- package/client/evm/constants.ts +0 -17
package/accounts/evm/types.ts
CHANGED
|
@@ -1,7 +1,50 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ListTokenBalancesNetworks,
|
|
3
|
+
RequestFaucetNetworks,
|
|
4
|
+
QuoteFundNetworks,
|
|
5
|
+
FundNetworks,
|
|
6
|
+
TransferNetworks,
|
|
7
|
+
QuoteSwapNetworks,
|
|
8
|
+
SwapNetworks,
|
|
9
|
+
} from "./networkCapabilities.js";
|
|
10
|
+
import { FundOptions } from "../../actions/evm/fund/fund.js";
|
|
11
|
+
import { Quote } from "../../actions/evm/fund/Quote.js";
|
|
12
|
+
import { QuoteFundOptions } from "../../actions/evm/fund/quoteFund.js";
|
|
13
|
+
import { FundOperationResult } from "../../actions/evm/fund/types.js";
|
|
14
|
+
import {
|
|
15
|
+
WaitForFundOperationOptions,
|
|
16
|
+
WaitForFundOperationResult,
|
|
17
|
+
} from "../../actions/evm/fund/waitForFundOperationReceipt.js";
|
|
18
|
+
import {
|
|
19
|
+
ListTokenBalancesOptions,
|
|
20
|
+
ListTokenBalancesResult,
|
|
21
|
+
} from "../../actions/evm/listTokenBalances.js";
|
|
1
22
|
import { RequestFaucetOptions, RequestFaucetResult } from "../../actions/evm/requestFaucet.js";
|
|
2
23
|
import { TransactionResult, SendTransactionOptions } from "../../actions/evm/sendTransaction.js";
|
|
3
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
SendUserOperationOptions,
|
|
26
|
+
SendUserOperationReturnType,
|
|
27
|
+
} from "../../actions/evm/sendUserOperation.js";
|
|
28
|
+
import {
|
|
29
|
+
AccountQuoteSwapOptions,
|
|
30
|
+
AccountQuoteSwapResult,
|
|
31
|
+
AccountSwapOptions,
|
|
32
|
+
AccountSwapResult,
|
|
33
|
+
SmartAccountQuoteSwapOptions,
|
|
34
|
+
SmartAccountQuoteSwapResult,
|
|
35
|
+
SmartAccountSwapOptions,
|
|
36
|
+
SmartAccountSwapResult,
|
|
37
|
+
} from "../../actions/evm/swap/types.js";
|
|
38
|
+
import {
|
|
39
|
+
WaitForUserOperationOptions,
|
|
40
|
+
WaitForUserOperationReturnType,
|
|
41
|
+
} from "../../actions/evm/waitForUserOperation.js";
|
|
42
|
+
import { GetUserOperationOptions, UserOperation } from "../../client/evm/evm.types.js";
|
|
4
43
|
|
|
44
|
+
import type {
|
|
45
|
+
SmartAccountTransferOptions,
|
|
46
|
+
TransferOptions,
|
|
47
|
+
} from "../../actions/evm/transfer/types.js";
|
|
5
48
|
import type { AccountActions, SmartAccountActions } from "../../actions/evm/types.js";
|
|
6
49
|
import type { Address, Hash, Hex } from "../../types/misc.js";
|
|
7
50
|
import type { Prettify } from "../../types/utils.js";
|
|
@@ -38,6 +81,27 @@ export type EvmAccount = {
|
|
|
38
81
|
policies?: string[];
|
|
39
82
|
};
|
|
40
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Known EVM networks supported by the SDK.
|
|
86
|
+
*/
|
|
87
|
+
export type KnownEvmNetworks =
|
|
88
|
+
| "base"
|
|
89
|
+
| "base-sepolia"
|
|
90
|
+
| "ethereum"
|
|
91
|
+
| "ethereum-sepolia"
|
|
92
|
+
| "ethereum-hoodi"
|
|
93
|
+
| "polygon"
|
|
94
|
+
| "polygon-mumbai"
|
|
95
|
+
| "arbitrum"
|
|
96
|
+
| "arbitrum-sepolia"
|
|
97
|
+
| "optimism"
|
|
98
|
+
| "optimism-sepolia";
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Network input that accepts known networks or RPC URLs
|
|
102
|
+
*/
|
|
103
|
+
export type NetworkOrRpcUrl = KnownEvmNetworks | (string & {});
|
|
104
|
+
|
|
41
105
|
/**
|
|
42
106
|
* Server-managed ethereum account
|
|
43
107
|
*/
|
|
@@ -48,8 +112,23 @@ export type EvmServerAccount = Prettify<
|
|
|
48
112
|
name?: string;
|
|
49
113
|
/** Indicates this is a server-managed account. */
|
|
50
114
|
type: "evm-server";
|
|
51
|
-
/**
|
|
52
|
-
|
|
115
|
+
/**
|
|
116
|
+
* A function that returns a network-scoped server-managed account.
|
|
117
|
+
*
|
|
118
|
+
* @param network - The network name or RPC URL
|
|
119
|
+
* @example
|
|
120
|
+
* // For known networks, type is inferred automatically:
|
|
121
|
+
* const baseAccount = await account.useNetwork("base");
|
|
122
|
+
*
|
|
123
|
+
* // For custom RPC URLs with type hints (requires casting):
|
|
124
|
+
* const typedAccount = await account.useNetwork<"base">("https://mainnet.base.org" as "base");
|
|
125
|
+
*
|
|
126
|
+
* // For custom RPC URLs without type hints (only sendTransaction and waitForTransactionReceipt methods available):
|
|
127
|
+
* const customAccount = await account.useNetwork("https://mainnet.base.org");
|
|
128
|
+
*/
|
|
129
|
+
useNetwork: <Network extends NetworkOrRpcUrl>(
|
|
130
|
+
network: Network,
|
|
131
|
+
) => Promise<NetworkScopedEvmServerAccount<Network>>;
|
|
53
132
|
}
|
|
54
133
|
>;
|
|
55
134
|
|
|
@@ -62,8 +141,23 @@ type EvmSmartAccountProperties = {
|
|
|
62
141
|
owners: EvmAccount[];
|
|
63
142
|
/** Identifier for the smart account type. */
|
|
64
143
|
type: "evm-smart";
|
|
65
|
-
/**
|
|
66
|
-
|
|
144
|
+
/**
|
|
145
|
+
* A function that returns a network-scoped smart account.
|
|
146
|
+
*
|
|
147
|
+
* @param network - The network name or RPC URL
|
|
148
|
+
* @example
|
|
149
|
+
* // For known networks, type is inferred automatically:
|
|
150
|
+
* const baseAccount = await smartAccount.useNetwork("base");
|
|
151
|
+
*
|
|
152
|
+
* // For custom RPC URLs with type hints (requires casting):
|
|
153
|
+
* const typedAccount = await smartAccount.useNetwork<"base">("https://mainnet.base.org" as "base");
|
|
154
|
+
*
|
|
155
|
+
* // For custom RPC URLs without type hints (only sendTransaction, transfer and waitForTransactionReceipt methods available):
|
|
156
|
+
* const customAccount = await smartAccount.useNetwork("https://mainnet.base.org");
|
|
157
|
+
*/
|
|
158
|
+
useNetwork: <Network extends KnownEvmNetworks>(
|
|
159
|
+
network: Network,
|
|
160
|
+
) => Promise<NetworkScopedEvmSmartAccount<Network>>;
|
|
67
161
|
};
|
|
68
162
|
|
|
69
163
|
/**
|
|
@@ -71,33 +165,167 @@ type EvmSmartAccountProperties = {
|
|
|
71
165
|
*/
|
|
72
166
|
export type EvmSmartAccount = Prettify<EvmSmartAccountProperties & SmartAccountActions>;
|
|
73
167
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
168
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
169
|
+
type DistributedOmit<T, K extends PropertyKey> = T extends any ? Omit<T, K> : never;
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Helper type for network-specific smart account actions
|
|
173
|
+
*/
|
|
174
|
+
type NetworkSpecificSmartAccountActions<Network extends string> = Prettify<
|
|
175
|
+
// Always include sendUserOperation, waitForUserOperation and getUserOperation
|
|
176
|
+
{
|
|
177
|
+
sendUserOperation: <const callData extends unknown[]>(
|
|
178
|
+
options: Omit<SendUserOperationOptions<callData>, "smartAccount" | "network">,
|
|
179
|
+
) => Promise<SendUserOperationReturnType>;
|
|
180
|
+
waitForUserOperation: (
|
|
181
|
+
options: Omit<WaitForUserOperationOptions, "smartAccountAddress" | "network">,
|
|
182
|
+
) => Promise<WaitForUserOperationReturnType>;
|
|
183
|
+
getUserOperation: (
|
|
184
|
+
options: Omit<GetUserOperationOptions, "smartAccount" | "network">,
|
|
185
|
+
) => Promise<UserOperation>;
|
|
186
|
+
} & (Network extends TransferNetworks
|
|
187
|
+
? {
|
|
188
|
+
transfer: (
|
|
189
|
+
options: Omit<SmartAccountTransferOptions, "network">,
|
|
190
|
+
) => Promise<SendUserOperationReturnType>;
|
|
191
|
+
}
|
|
192
|
+
: EmptyObject) &
|
|
193
|
+
// Conditionally include listTokenBalances
|
|
194
|
+
(Network extends ListTokenBalancesNetworks
|
|
195
|
+
? {
|
|
196
|
+
listTokenBalances: (
|
|
197
|
+
options: Omit<ListTokenBalancesOptions, "address" | "network">,
|
|
198
|
+
) => Promise<ListTokenBalancesResult>;
|
|
199
|
+
}
|
|
200
|
+
: EmptyObject) &
|
|
201
|
+
// Conditionally include requestFaucet
|
|
202
|
+
(Network extends RequestFaucetNetworks
|
|
203
|
+
? {
|
|
204
|
+
requestFaucet: (
|
|
205
|
+
options: Omit<RequestFaucetOptions, "address" | "network">,
|
|
206
|
+
) => Promise<RequestFaucetResult>;
|
|
207
|
+
}
|
|
208
|
+
: EmptyObject) &
|
|
209
|
+
// Conditionally include quoteFund
|
|
210
|
+
(Network extends QuoteFundNetworks
|
|
211
|
+
? {
|
|
212
|
+
quoteFund: (options: Omit<QuoteFundOptions, "address" | "network">) => Promise<Quote>;
|
|
213
|
+
}
|
|
214
|
+
: EmptyObject) &
|
|
215
|
+
// Conditionally include fund
|
|
216
|
+
(Network extends FundNetworks
|
|
217
|
+
? {
|
|
218
|
+
fund: (options: Omit<FundOptions, "address" | "network">) => Promise<FundOperationResult>;
|
|
219
|
+
waitForFundOperationReceipt: (
|
|
220
|
+
options: Omit<WaitForFundOperationOptions, "network">,
|
|
221
|
+
) => Promise<WaitForFundOperationResult>;
|
|
222
|
+
}
|
|
223
|
+
: EmptyObject) &
|
|
224
|
+
// Conditionally include quoteSwap
|
|
225
|
+
(Network extends QuoteSwapNetworks
|
|
226
|
+
? {
|
|
227
|
+
quoteSwap: (
|
|
228
|
+
options: Omit<SmartAccountQuoteSwapOptions, "network">,
|
|
229
|
+
) => Promise<SmartAccountQuoteSwapResult>;
|
|
230
|
+
}
|
|
231
|
+
: EmptyObject) &
|
|
232
|
+
// Conditionally include swap
|
|
233
|
+
(Network extends SwapNetworks
|
|
234
|
+
? {
|
|
235
|
+
swap: (
|
|
236
|
+
options: DistributedOmit<SmartAccountSwapOptions, "network">,
|
|
237
|
+
) => Promise<SmartAccountSwapResult>;
|
|
238
|
+
}
|
|
239
|
+
: EmptyObject)
|
|
240
|
+
>;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* A network-scoped smart account
|
|
244
|
+
*/
|
|
245
|
+
export type NetworkScopedEvmSmartAccount<Network extends string = string> = Prettify<
|
|
246
|
+
Omit<EvmSmartAccountProperties, "useNetwork"> &
|
|
247
|
+
NetworkSpecificSmartAccountActions<Network> & {
|
|
248
|
+
/** The network this account is scoped to */
|
|
249
|
+
network: Network;
|
|
250
|
+
}
|
|
79
251
|
>;
|
|
80
252
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
253
|
+
/**
|
|
254
|
+
* Helper type to surface a TypeError when calling a method that doesn't exist based on the network
|
|
255
|
+
*/
|
|
256
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
257
|
+
type EmptyObject = {};
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Conditional account actions based on network
|
|
261
|
+
*/
|
|
262
|
+
type NetworkSpecificAccountActions<Network extends string> = Prettify<
|
|
263
|
+
// Always include sendTransaction, transfer and waitForTransactionReceipt
|
|
264
|
+
{
|
|
265
|
+
sendTransaction: (
|
|
266
|
+
options: Omit<SendTransactionOptions, "address" | "network">,
|
|
267
|
+
) => Promise<TransactionResult>;
|
|
268
|
+
transfer: (options: Omit<TransferOptions, "address" | "network">) => Promise<TransactionResult>;
|
|
269
|
+
waitForTransactionReceipt: (
|
|
270
|
+
options: WaitForTransactionReceiptParameters | TransactionResult,
|
|
271
|
+
) => Promise<TransactionReceipt>;
|
|
272
|
+
} & (Network extends ListTokenBalancesNetworks // Conditionally include listTokenBalances
|
|
273
|
+
? {
|
|
274
|
+
listTokenBalances: (
|
|
275
|
+
options: Omit<ListTokenBalancesOptions, "address" | "network">,
|
|
276
|
+
) => Promise<ListTokenBalancesResult>;
|
|
277
|
+
}
|
|
278
|
+
: EmptyObject) &
|
|
279
|
+
// Conditionally include requestFaucet
|
|
280
|
+
(Network extends RequestFaucetNetworks
|
|
281
|
+
? {
|
|
282
|
+
requestFaucet: (
|
|
283
|
+
options: Omit<RequestFaucetOptions, "address" | "network">,
|
|
284
|
+
) => Promise<RequestFaucetResult>;
|
|
285
|
+
}
|
|
286
|
+
: EmptyObject) &
|
|
287
|
+
// Conditionally include quoteFund
|
|
288
|
+
(Network extends QuoteFundNetworks
|
|
289
|
+
? {
|
|
290
|
+
quoteFund: (options: Omit<QuoteFundOptions, "address">) => Promise<Quote>;
|
|
291
|
+
}
|
|
292
|
+
: EmptyObject) &
|
|
293
|
+
// Conditionally include fund
|
|
294
|
+
(Network extends FundNetworks
|
|
295
|
+
? {
|
|
296
|
+
fund: (options: Omit<FundOptions, "address">) => Promise<FundOperationResult>;
|
|
297
|
+
waitForFundOperationReceipt: (
|
|
298
|
+
options: WaitForFundOperationOptions,
|
|
299
|
+
) => Promise<WaitForFundOperationResult>;
|
|
300
|
+
}
|
|
301
|
+
: EmptyObject) &
|
|
302
|
+
// Conditionally include transfer
|
|
303
|
+
(Network extends TransferNetworks
|
|
304
|
+
? {
|
|
305
|
+
transfer: (options: TransferOptions) => Promise<{ transactionHash: Hex }>;
|
|
306
|
+
}
|
|
307
|
+
: EmptyObject) &
|
|
308
|
+
// Conditionally include quoteSwap
|
|
309
|
+
(Network extends QuoteSwapNetworks
|
|
310
|
+
? {
|
|
311
|
+
quoteSwap: (options: AccountQuoteSwapOptions) => Promise<AccountQuoteSwapResult>;
|
|
312
|
+
}
|
|
313
|
+
: EmptyObject) &
|
|
314
|
+
// Conditionally include swap
|
|
315
|
+
(Network extends SwapNetworks
|
|
316
|
+
? {
|
|
317
|
+
swap: (options: AccountSwapOptions) => Promise<AccountSwapResult>;
|
|
318
|
+
}
|
|
319
|
+
: EmptyObject)
|
|
320
|
+
>;
|
|
93
321
|
|
|
94
322
|
/**
|
|
95
323
|
* A network-scoped server-managed ethereum account
|
|
96
324
|
*/
|
|
97
|
-
export type NetworkScopedEvmServerAccount = Prettify<
|
|
325
|
+
export type NetworkScopedEvmServerAccount<Network extends string = string> = Prettify<
|
|
98
326
|
Omit<EvmServerAccount, keyof AccountActions | "useNetwork"> &
|
|
99
|
-
|
|
327
|
+
NetworkSpecificAccountActions<Network> & {
|
|
100
328
|
/** The network this account is scoped to */
|
|
101
|
-
network:
|
|
329
|
+
network: Network;
|
|
102
330
|
}
|
|
103
331
|
>;
|
package/actions/evm/fund/fund.ts
CHANGED
|
@@ -14,7 +14,7 @@ export interface FundOptions {
|
|
|
14
14
|
/** The address of the account. */
|
|
15
15
|
address: string;
|
|
16
16
|
/** The network to request funds from. */
|
|
17
|
-
network: "base";
|
|
17
|
+
network: "base" | "ethereum";
|
|
18
18
|
/** The amount to fund the account with, in atomic units (wei) of the token. */
|
|
19
19
|
amount: bigint;
|
|
20
20
|
/** The token to request funds for. */
|
|
@@ -14,7 +14,7 @@ export interface QuoteFundOptions {
|
|
|
14
14
|
/** The address of the account. */
|
|
15
15
|
address: string;
|
|
16
16
|
/** The network to request funds from. */
|
|
17
|
-
network: "base";
|
|
17
|
+
network: "base" | "ethereum";
|
|
18
18
|
/** The amount to fund the account with, in atomic units (wei) of the token. */
|
|
19
19
|
amount: bigint;
|
|
20
20
|
/** The token to request funds for. */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { encodeFunctionData } from "viem";
|
|
2
2
|
|
|
3
|
+
import { getBaseNodeRpcUrl } from "../../accounts/evm/getBaseNodeRpcUrl.js";
|
|
3
4
|
import {
|
|
4
5
|
EvmUserOperationNetwork,
|
|
5
6
|
EvmUserOperationStatus,
|
|
@@ -106,7 +107,14 @@ export async function sendUserOperation<T extends readonly unknown[]>(
|
|
|
106
107
|
client: CdpOpenApiClientType,
|
|
107
108
|
options: SendUserOperationOptions<T>,
|
|
108
109
|
): Promise<SendUserOperationReturnType> {
|
|
109
|
-
const { calls, network, paymasterUrl } = options;
|
|
110
|
+
const { calls, network, paymasterUrl: _paymasterUrl } = options;
|
|
111
|
+
|
|
112
|
+
const paymasterUrl = await (async () => {
|
|
113
|
+
if (!_paymasterUrl && network === "base") {
|
|
114
|
+
return getBaseNodeRpcUrl("base");
|
|
115
|
+
}
|
|
116
|
+
return _paymasterUrl;
|
|
117
|
+
})();
|
|
110
118
|
|
|
111
119
|
if (calls.length === 0) {
|
|
112
120
|
throw new Error("Calls array is empty");
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { encodeFunctionData, erc20Abi } from "viem";
|
|
2
2
|
|
|
3
3
|
import { getErc20Address } from "./utils.js";
|
|
4
|
+
import { mapChainToNetwork } from "../../../accounts/evm/chainToNetworkMapper.js";
|
|
4
5
|
|
|
5
6
|
import type { Network, TransferOptions } from "./types.js";
|
|
6
7
|
import type { EvmAccount } from "../../../accounts/evm/types.js";
|
|
@@ -21,12 +22,11 @@ import type { Account, Chain, Transport, WalletClient } from "viem";
|
|
|
21
22
|
export async function transferWithViem<T extends EvmAccount>(
|
|
22
23
|
walletClient: WalletClient<Transport, Chain, Account>,
|
|
23
24
|
from: T,
|
|
24
|
-
transferArgs: TransferOptions,
|
|
25
|
+
transferArgs: Omit<TransferOptions, "address" | "network">,
|
|
25
26
|
): Promise<TransactionResult> {
|
|
26
27
|
const token = transferArgs.token;
|
|
27
28
|
const to = typeof transferArgs.to === "string" ? transferArgs.to : transferArgs.to.address;
|
|
28
29
|
const value = transferArgs.amount;
|
|
29
|
-
const network = transferArgs.network;
|
|
30
30
|
|
|
31
31
|
if (token === "eth") {
|
|
32
32
|
const hash = await walletClient.sendTransaction({
|
|
@@ -37,7 +37,8 @@ export async function transferWithViem<T extends EvmAccount>(
|
|
|
37
37
|
return { transactionHash: hash as Hex };
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
const
|
|
40
|
+
const network = mapChainToNetwork(walletClient.chain) as Network;
|
|
41
|
+
const erc20Address = getErc20Address(token, network);
|
|
41
42
|
|
|
42
43
|
// First approve the transfer
|
|
43
44
|
await walletClient.sendTransaction({
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { subtle } from "uncrypto";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Auth-specific hash function using uncrypto for Edge runtime compatibility.
|
|
5
|
+
* Computes SHA-256 hash of the given data.
|
|
6
|
+
*
|
|
7
|
+
* @param data - The data to hash
|
|
8
|
+
* @returns Promise that resolves to the hex-encoded hash
|
|
9
|
+
*/
|
|
10
|
+
export const authHash = async (data: Buffer): Promise<string> => {
|
|
11
|
+
const hashBuffer = await subtle.digest("SHA-256", data);
|
|
12
|
+
return Buffer.from(hashBuffer).toString("hex");
|
|
13
|
+
};
|
package/auth/utils/jwt.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import * as crypto from "crypto";
|
|
2
|
-
import { createPrivateKey } from "crypto";
|
|
3
|
-
|
|
4
1
|
import { SignJWT, importPKCS8, importJWK, JWTPayload } from "jose";
|
|
2
|
+
import { getRandomValues } from "uncrypto";
|
|
5
3
|
|
|
6
|
-
import {
|
|
4
|
+
import { authHash } from "./hash.js";
|
|
7
5
|
import { sortKeys } from "../../utils/sortKeys.js";
|
|
8
6
|
import { InvalidWalletSecretFormatError, UndefinedWalletSecretError } from "../errors.js";
|
|
9
7
|
|
|
@@ -147,7 +145,7 @@ export async function generateJwt(options: JwtOptions): Promise<string> {
|
|
|
147
145
|
const randomNonce = nonce();
|
|
148
146
|
|
|
149
147
|
// Determine if we're using EC or Edwards key based on the key format
|
|
150
|
-
if (isValidECKey(options.apiKeySecret)) {
|
|
148
|
+
if (await isValidECKey(options.apiKeySecret)) {
|
|
151
149
|
return await buildECJWT(
|
|
152
150
|
options.apiKeySecret,
|
|
153
151
|
options.apiKeyId,
|
|
@@ -193,16 +191,18 @@ export async function generateWalletJwt(options: WalletJwtOptions): Promise<stri
|
|
|
193
191
|
|
|
194
192
|
if (Object.keys(options.requestData).length > 0) {
|
|
195
193
|
const sortedData = sortKeys(options.requestData);
|
|
196
|
-
claims.reqHash =
|
|
194
|
+
claims.reqHash = await authHash(Buffer.from(JSON.stringify(sortedData)));
|
|
197
195
|
}
|
|
198
196
|
|
|
199
197
|
try {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
198
|
+
// Convert base64 DER to PEM format for jose
|
|
199
|
+
const derBuffer = Buffer.from(options.walletSecret, "base64");
|
|
200
|
+
const pemKey = `-----BEGIN PRIVATE KEY-----\n${derBuffer
|
|
201
|
+
.toString("base64")
|
|
202
|
+
.match(/.{1,64}/g)
|
|
203
|
+
?.join("\n")}\n-----END PRIVATE KEY-----`;
|
|
204
|
+
|
|
205
|
+
const ecKey = await importPKCS8(pemKey, "ES256");
|
|
206
206
|
|
|
207
207
|
return await new SignJWT(claims)
|
|
208
208
|
.setProtectedHeader({ alg: "ES256", typ: "JWT" })
|
|
@@ -236,12 +236,11 @@ function isValidEd25519Key(str: string): boolean {
|
|
|
236
236
|
* @param str - The string to test
|
|
237
237
|
* @returns True if the string is a valid EC private key in PEM format
|
|
238
238
|
*/
|
|
239
|
-
function isValidECKey(str: string): boolean {
|
|
239
|
+
async function isValidECKey(str: string): Promise<boolean> {
|
|
240
240
|
try {
|
|
241
|
-
//
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
return key.asymmetricKeyType === "ec";
|
|
241
|
+
// Try to import the key with jose - if it works, it's a valid EC key
|
|
242
|
+
await importPKCS8(str, "ES256");
|
|
243
|
+
return true;
|
|
245
244
|
} catch {
|
|
246
245
|
return false;
|
|
247
246
|
}
|
|
@@ -268,12 +267,8 @@ async function buildECJWT(
|
|
|
268
267
|
nonce: string,
|
|
269
268
|
): Promise<string> {
|
|
270
269
|
try {
|
|
271
|
-
//
|
|
272
|
-
const
|
|
273
|
-
const pkcs8Key = keyObj.export({ type: "pkcs8", format: "pem" }).toString();
|
|
274
|
-
|
|
275
|
-
// Import the key for signing
|
|
276
|
-
const ecKey = await importPKCS8(pkcs8Key, "ES256");
|
|
270
|
+
// Import the key directly with jose
|
|
271
|
+
const ecKey = await importPKCS8(privateKey, "ES256");
|
|
277
272
|
|
|
278
273
|
// Sign and return the JWT
|
|
279
274
|
return await new SignJWT(claims)
|
|
@@ -346,5 +341,7 @@ async function buildEdwardsJWT(
|
|
|
346
341
|
* @returns {string} The generated nonce.
|
|
347
342
|
*/
|
|
348
343
|
function nonce(): string {
|
|
349
|
-
|
|
344
|
+
const bytes = new Uint8Array(16);
|
|
345
|
+
getRandomValues(bytes);
|
|
346
|
+
return Buffer.from(bytes).toString("hex");
|
|
350
347
|
}
|
package/client/cdp.ts
CHANGED
|
@@ -67,6 +67,15 @@ export class CdpClient {
|
|
|
67
67
|
* @param {CdpClientOptions} [options] - Configuration options for the CdpClient.
|
|
68
68
|
*/
|
|
69
69
|
constructor(options: CdpClientOptions = {}) {
|
|
70
|
+
if (Number(process.versions.node.split(".")[0]) < 19) {
|
|
71
|
+
throw new Error(
|
|
72
|
+
`
|
|
73
|
+
Node.js version ${process.versions.node} is not supported. CDP SDK requires Node.js version 19 or higher. Please upgrade your Node.js version to use the CDP SDK.
|
|
74
|
+
We recommend using https://github.com/Schniz/fnm for managing your Node.js version.
|
|
75
|
+
`,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
70
79
|
const apiKeyId = options.apiKeyId ?? process.env.CDP_API_KEY_ID ?? process.env.CDP_API_KEY_NAME;
|
|
71
80
|
const apiKeySecret = options.apiKeySecret ?? process.env.CDP_API_KEY_SECRET;
|
|
72
81
|
const walletSecret = options.walletSecret ?? process.env.CDP_WALLET_SECRET;
|
package/client/evm/evm.ts
CHANGED
|
@@ -2,7 +2,6 @@ import { constants, publicEncrypt } from "crypto";
|
|
|
2
2
|
|
|
3
3
|
import { type Address, getTypesForEIP712Domain } from "viem";
|
|
4
4
|
|
|
5
|
-
import { ImportEvmAccountPublicRSAKey } from "./constants.js";
|
|
6
5
|
import {
|
|
7
6
|
CreateServerAccountOptions,
|
|
8
7
|
CreateSmartAccountOptions,
|
|
@@ -61,6 +60,7 @@ import {
|
|
|
61
60
|
WaitForUserOperationReturnType,
|
|
62
61
|
} from "../../actions/evm/waitForUserOperation.js";
|
|
63
62
|
import { Analytics } from "../../analytics.js";
|
|
63
|
+
import { ImportAccountPublicRSAKey } from "../../constants.js";
|
|
64
64
|
import { APIError } from "../../openapi-client/errors.js";
|
|
65
65
|
import {
|
|
66
66
|
CdpOpenApiClient,
|
|
@@ -173,7 +173,7 @@ export class EvmClient implements EvmClientInterface {
|
|
|
173
173
|
* ```
|
|
174
174
|
*/
|
|
175
175
|
async importAccount(options: ImportServerAccountOptions): Promise<ServerAccount> {
|
|
176
|
-
const encryptionPublicKey = options.encryptionPublicKey ||
|
|
176
|
+
const encryptionPublicKey = options.encryptionPublicKey || ImportAccountPublicRSAKey;
|
|
177
177
|
|
|
178
178
|
const privateKeyHex = options.privateKey.startsWith("0x")
|
|
179
179
|
? options.privateKey.slice(2)
|
package/client/evm/evm.types.ts
CHANGED
|
@@ -405,7 +405,7 @@ export interface ListServerAccountsOptions {
|
|
|
405
405
|
* A smart account that only contains the owner address.
|
|
406
406
|
*/
|
|
407
407
|
export interface ReadonlySmartAccount
|
|
408
|
-
extends Omit<SmartAccount, "owners" | keyof SmartAccountActions | "
|
|
408
|
+
extends Omit<SmartAccount, "owners" | keyof SmartAccountActions | "useNetwork"> {
|
|
409
409
|
/** The owners of the smart account. */
|
|
410
410
|
owners: Address[];
|
|
411
411
|
}
|
package/client/solana/solana.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
import { constants, publicEncrypt } from "crypto";
|
|
2
|
+
|
|
3
|
+
import bs58 from "bs58";
|
|
4
|
+
|
|
1
5
|
import {
|
|
2
6
|
CreateAccountOptions,
|
|
3
7
|
ExportAccountOptions,
|
|
4
8
|
GetAccountOptions,
|
|
5
9
|
GetOrCreateAccountOptions,
|
|
10
|
+
ImportAccountOptions,
|
|
6
11
|
ListAccountsOptions,
|
|
7
12
|
ListAccountsResult,
|
|
8
13
|
RequestFaucetOptions,
|
|
@@ -18,6 +23,7 @@ import { requestFaucet } from "../../actions/solana/requestFaucet.js";
|
|
|
18
23
|
import { signMessage } from "../../actions/solana/signMessage.js";
|
|
19
24
|
import { signTransaction } from "../../actions/solana/signTransaction.js";
|
|
20
25
|
import { Analytics } from "../../analytics.js";
|
|
26
|
+
import { ImportAccountPublicRSAKey } from "../../constants.js";
|
|
21
27
|
import { APIError } from "../../openapi-client/errors.js";
|
|
22
28
|
import { CdpOpenApiClient } from "../../openapi-client/index.js";
|
|
23
29
|
import {
|
|
@@ -133,6 +139,89 @@ export class SolanaClient implements SolanaClientInterface {
|
|
|
133
139
|
return formatSolanaPrivateKey(decryptedPrivateKey);
|
|
134
140
|
}
|
|
135
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Imports a Solana account using a private key.
|
|
144
|
+
* The private key will be encrypted before being stored securely.
|
|
145
|
+
*
|
|
146
|
+
* @param {ImportAccountOptions} options - Parameters for importing the Solana account.
|
|
147
|
+
* @param {string} options.privateKey - The private key to import (32 or 64 bytes). Can be a base58 encoded string or raw bytes.
|
|
148
|
+
* @param {string} [options.name] - The name of the account.
|
|
149
|
+
* @param {string} [options.encryptionPublicKey] - The RSA public key for encrypting the private key.
|
|
150
|
+
* @param {string} [options.idempotencyKey] - An idempotency key.
|
|
151
|
+
*
|
|
152
|
+
* @returns A promise that resolves to the imported account.
|
|
153
|
+
*
|
|
154
|
+
* @example **Import with private key only**
|
|
155
|
+
* ```ts
|
|
156
|
+
* const account = await cdp.solana.importAccount({
|
|
157
|
+
* privateKey: "3Kzjw8qSxx8bQkV7EHrVFWYiPyNLbBVxtVe1Q5h2zKZY8DdcuT2dKxyz9kU5vQrP",
|
|
158
|
+
* });
|
|
159
|
+
* ```
|
|
160
|
+
*
|
|
161
|
+
* @example **Import with name**
|
|
162
|
+
* ```ts
|
|
163
|
+
* const account = await cdp.solana.importAccount({
|
|
164
|
+
* privateKey: "3Kzjw8qSxx8bQkV7EHrVFWYiPyNLbBVxtVe1Q5h2zKZY8DdcuT2dKxyz9kU5vQrP",
|
|
165
|
+
* name: "ImportedAccount",
|
|
166
|
+
* });
|
|
167
|
+
* ```
|
|
168
|
+
*
|
|
169
|
+
* @example **Import with idempotency key**
|
|
170
|
+
* ```ts
|
|
171
|
+
* const idempotencyKey = uuidv4();
|
|
172
|
+
*
|
|
173
|
+
* const account = await cdp.solana.importAccount({
|
|
174
|
+
* privateKey: "3Kzjw8qSxx8bQkV7EHrVFWYiPyNLbBVxtVe1Q5h2zKZY8DdcuT2dKxyz9kU5vQrP",
|
|
175
|
+
* name: "ImportedAccount",
|
|
176
|
+
* idempotencyKey,
|
|
177
|
+
* });
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
async importAccount(options: ImportAccountOptions): Promise<SolanaAccount> {
|
|
181
|
+
let privateKeyBytes: Uint8Array = new Uint8Array();
|
|
182
|
+
|
|
183
|
+
if (typeof options.privateKey === "string") {
|
|
184
|
+
privateKeyBytes = bs58.decode(options.privateKey);
|
|
185
|
+
} else {
|
|
186
|
+
privateKeyBytes = options.privateKey;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (privateKeyBytes.length !== 32 && privateKeyBytes.length !== 64) {
|
|
190
|
+
throw new Error("Invalid private key length");
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (privateKeyBytes.length === 64) {
|
|
194
|
+
privateKeyBytes = privateKeyBytes.subarray(0, 32);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const encryptionPublicKey = options.encryptionPublicKey || ImportAccountPublicRSAKey;
|
|
198
|
+
|
|
199
|
+
const encryptedPrivateKey = publicEncrypt(
|
|
200
|
+
{
|
|
201
|
+
key: encryptionPublicKey,
|
|
202
|
+
padding: constants.RSA_PKCS1_OAEP_PADDING,
|
|
203
|
+
oaepHash: "sha256",
|
|
204
|
+
},
|
|
205
|
+
privateKeyBytes,
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
const openApiAccount = await CdpOpenApiClient.importSolanaAccount(
|
|
209
|
+
{
|
|
210
|
+
encryptedPrivateKey: encryptedPrivateKey.toString("base64"),
|
|
211
|
+
name: options.name,
|
|
212
|
+
},
|
|
213
|
+
options.idempotencyKey,
|
|
214
|
+
);
|
|
215
|
+
|
|
216
|
+
const account = toSolanaAccount(CdpOpenApiClient, {
|
|
217
|
+
account: openApiAccount,
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
Analytics.wrapObjectMethodsWithErrorTracking(account);
|
|
221
|
+
|
|
222
|
+
return account;
|
|
223
|
+
}
|
|
224
|
+
|
|
136
225
|
/**
|
|
137
226
|
* Gets a Solana account by its address.
|
|
138
227
|
*
|