@coinbase/cdp-sdk 1.9.0 → 1.10.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 (55) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +8 -0
  3. package/_cjs/client/evm/constants.js +21 -0
  4. package/_cjs/client/evm/constants.js.map +1 -0
  5. package/_cjs/client/evm/evm.js +75 -0
  6. package/_cjs/client/evm/evm.js.map +1 -1
  7. package/_cjs/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
  8. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.js +14 -1
  9. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.js.map +1 -1
  10. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.msw.js +26 -1
  11. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.msw.js.map +1 -1
  12. package/_cjs/openapi-client/generated/index.msw.js +3 -3
  13. package/_cjs/openapi-client/generated/index.msw.js.map +1 -1
  14. package/_cjs/version.js +1 -1
  15. package/_cjs/version.js.map +1 -1
  16. package/_esm/client/evm/constants.js +18 -0
  17. package/_esm/client/evm/constants.js.map +1 -0
  18. package/_esm/client/evm/evm.js +75 -0
  19. package/_esm/client/evm/evm.js.map +1 -1
  20. package/_esm/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
  21. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.js +12 -0
  22. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.js.map +1 -1
  23. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.msw.js +23 -0
  24. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.msw.js.map +1 -1
  25. package/_esm/openapi-client/generated/index.msw.js +3 -3
  26. package/_esm/openapi-client/generated/index.msw.js.map +1 -1
  27. package/_esm/version.js +1 -1
  28. package/_esm/version.js.map +1 -1
  29. package/_types/client/evm/constants.d.ts +5 -0
  30. package/_types/client/evm/constants.d.ts.map +1 -0
  31. package/_types/client/evm/evm.d.ts +44 -1
  32. package/_types/client/evm/evm.d.ts.map +1 -1
  33. package/_types/client/evm/evm.types.d.ts +13 -1
  34. package/_types/client/evm/evm.types.d.ts.map +1 -1
  35. package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts +11 -0
  36. package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts.map +1 -1
  37. package/_types/openapi-client/generated/evm-accounts/evm-accounts.d.ts +7 -1
  38. package/_types/openapi-client/generated/evm-accounts/evm-accounts.d.ts.map +1 -1
  39. package/_types/openapi-client/generated/evm-accounts/evm-accounts.msw.d.ts +2 -0
  40. package/_types/openapi-client/generated/evm-accounts/evm-accounts.msw.d.ts.map +1 -1
  41. package/_types/openapi-client/generated/index.msw.d.ts +3 -3
  42. package/_types/openapi-client/generated/index.msw.d.ts.map +1 -1
  43. package/_types/openapi-client/index.d.ts +2 -0
  44. package/_types/openapi-client/index.d.ts.map +1 -1
  45. package/_types/version.d.ts +1 -1
  46. package/_types/version.d.ts.map +1 -1
  47. package/client/evm/constants.ts +17 -0
  48. package/client/evm/evm.ts +90 -0
  49. package/client/evm/evm.types.ts +14 -0
  50. package/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.ts +12 -0
  51. package/openapi-client/generated/evm-accounts/evm-accounts.msw.ts +41 -0
  52. package/openapi-client/generated/evm-accounts/evm-accounts.ts +20 -0
  53. package/openapi-client/generated/index.msw.ts +3 -3
  54. package/package.json +1 -1
  55. package/version.ts +1 -1
package/client/evm/evm.ts CHANGED
@@ -1,5 +1,8 @@
1
+ import { publicEncrypt, constants } from "crypto";
2
+
1
3
  import { Address } from "viem";
2
4
 
5
+ import { ImportEvmAccountPublicRSAKey } from "./constants.js";
3
6
  import {
4
7
  CreateServerAccountOptions,
5
8
  GetServerAccountOptions,
@@ -23,6 +26,7 @@ import {
23
26
  GetOrCreateServerAccountOptions,
24
27
  SignTypedDataOptions,
25
28
  UpdateEvmAccountOptions,
29
+ ImportServerAccountOptions,
26
30
  } from "./evm.types.js";
27
31
  import { toEvmServerAccount } from "../../accounts/evm/toEvmServerAccount.js";
28
32
  import { toEvmSmartAccount } from "../../accounts/evm/toEvmSmartAccount.js";
@@ -112,6 +116,92 @@ export class EvmClient implements EvmClientInterface {
112
116
  return account;
113
117
  }
114
118
 
119
+ /**
120
+ * Imports a CDP EVM account from an external source.
121
+ *
122
+ * @param {ImportServerAccountOptions} options - Parameters for importing the account.
123
+ * @param {string} options.privateKey - The private key of the account to import.
124
+ * @param {string} [options.name] - A name for the account to import.
125
+ * @param {string} [options.idempotencyKey] - An idempotency key.
126
+ *
127
+ * @returns A promise that resolves to the imported account.
128
+ *
129
+ * @example **Without arguments**
130
+ * ```ts
131
+ * const account = await cdp.evm.importAccount({
132
+ * privateKey: "0x123456"
133
+ * });
134
+ * ```
135
+ *
136
+ * @example **With a name**
137
+ * ```ts
138
+ * const account = await cdp.evm.importAccount({
139
+ * privateKey: "0x123456",
140
+ * name: "MyAccount"
141
+ * });
142
+ * ```
143
+ *
144
+ * @example **With an idempotency key**
145
+ * ```ts
146
+ * const idempotencyKey = uuidv4();
147
+ *
148
+ * // First call
149
+ * await cdp.evm.importAccount({
150
+ * privateKey: "0x123456",
151
+ * idempotencyKey,
152
+ * });
153
+ *
154
+ * // Second call with the same idempotency key will return the same account
155
+ * await cdp.evm.importAccount({
156
+ * privateKey: "0x123456"
157
+ * idempotencyKey,
158
+ * });
159
+ * ```
160
+ */
161
+ async importAccount(options: ImportServerAccountOptions): Promise<ServerAccount> {
162
+ const privateKeyHex = options.privateKey.startsWith("0x")
163
+ ? options.privateKey.slice(2)
164
+ : options.privateKey;
165
+
166
+ if (!/^[0-9a-fA-F]+$/.test(privateKeyHex)) {
167
+ throw new Error("Private key must be a valid hexadecimal string");
168
+ }
169
+
170
+ try {
171
+ const privateKeyBytes = Buffer.from(privateKeyHex, "hex");
172
+
173
+ const encryptedPrivateKey = publicEncrypt(
174
+ {
175
+ key: ImportEvmAccountPublicRSAKey,
176
+ padding: constants.RSA_PKCS1_OAEP_PADDING,
177
+ oaepHash: "sha256",
178
+ },
179
+ privateKeyBytes,
180
+ );
181
+
182
+ const openApiAccount = await CdpOpenApiClient.importEvmAccount(
183
+ {
184
+ name: options.name,
185
+ encryptedPrivateKey: encryptedPrivateKey.toString("base64"),
186
+ },
187
+ options.idempotencyKey,
188
+ );
189
+
190
+ const account = toEvmServerAccount(CdpOpenApiClient, {
191
+ account: openApiAccount,
192
+ });
193
+
194
+ Analytics.wrapObjectMethodsWithErrorTracking(account);
195
+
196
+ return account;
197
+ } catch (error) {
198
+ if (error instanceof APIError) {
199
+ throw error;
200
+ }
201
+ throw new Error(`Failed to import account: ${String(error)}`);
202
+ }
203
+ }
204
+
115
205
  /**
116
206
  * Creates a new CDP EVM smart account.
117
207
  *
@@ -34,6 +34,7 @@ export type EvmClientInterface = Omit<
34
34
  typeof OpenApiEvmMethods,
35
35
  | "createEvmAccount" // mapped to createAccount
36
36
  | "createEvmSmartAccount" // mapped to createSmartAccount
37
+ | "importEvmAccount" // mapped to importAccount
37
38
  | "getEvmAccount" // mapped to getAccount
38
39
  | "getEvmAccountByName" // mapped to getAccount
39
40
  | "getEvmSmartAccount" // mapped to getSmartAccount
@@ -55,6 +56,7 @@ export type EvmClientInterface = Omit<
55
56
  > & {
56
57
  createAccount: (options: CreateServerAccountOptions) => Promise<ServerAccount>;
57
58
  createSmartAccount: (options: CreateSmartAccountOptions) => Promise<SmartAccount>;
59
+ importAccount: (options: ImportServerAccountOptions) => Promise<ServerAccount>;
58
60
  getAccount: (options: GetServerAccountOptions) => Promise<ServerAccount>;
59
61
  getSmartAccount: (options: GetSmartAccountOptions) => Promise<SmartAccount>;
60
62
  getOrCreateAccount: (options: GetOrCreateServerAccountOptions) => Promise<ServerAccount>;
@@ -147,6 +149,18 @@ export interface CreateServerAccountOptions {
147
149
  idempotencyKey?: string;
148
150
  }
149
151
 
152
+ /**
153
+ * Options for importing an EVM server account.
154
+ */
155
+ export interface ImportServerAccountOptions {
156
+ /** The name of the account. */
157
+ name?: string;
158
+ /** The idempotency key. */
159
+ idempotencyKey?: string;
160
+ /** The private key of the account. */
161
+ privateKey: Hex;
162
+ }
163
+
150
164
  /**
151
165
  * Options for getting an EVM account.
152
166
  */
@@ -744,6 +744,18 @@ export type CreateEvmSmartAccountBody = {
744
744
  owners: string[];
745
745
  };
746
746
 
747
+ export type ImportEvmAccountBody = {
748
+ /** The base64-encoded, encrypted private key of the EVM account. The private key must be encrypted using the CDP SDK's encryption scheme. */
749
+ encryptedPrivateKey: string;
750
+ /**
751
+ * An optional name for the account.
752
+ Account names can consist of alphanumeric characters and hyphens, and be between 2 and 36 characters long.
753
+ Account names must be unique across all EVM accounts in the developer's CDP Project.
754
+ * @pattern ^[A-Za-z0-9][A-Za-z0-9-]{0,34}[A-Za-z0-9]$
755
+ */
756
+ name?: string;
757
+ };
758
+
747
759
  /**
748
760
  * The network to prepare the user operation for.
749
761
  */
@@ -138,6 +138,25 @@ export const getSignEvmTypedDataResponseMock = (
138
138
  overrideResponse: Partial<SignEvmTypedData200> = {},
139
139
  ): SignEvmTypedData200 => ({ signature: faker.string.alpha(20), ...overrideResponse });
140
140
 
141
+ export const getImportEvmAccountResponseMock = (
142
+ overrideResponse: Partial<EvmAccount> = {},
143
+ ): EvmAccount => ({
144
+ address: faker.helpers.fromRegExp("^0x[0-9a-fA-F]{40}$"),
145
+ name: faker.helpers.arrayElement([
146
+ faker.helpers.fromRegExp("^[A-Za-z0-9][A-Za-z0-9-]{0,34}[A-Za-z0-9]$"),
147
+ undefined,
148
+ ]),
149
+ policies: faker.helpers.arrayElement([
150
+ Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() =>
151
+ faker.helpers.fromRegExp(
152
+ "^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$",
153
+ ),
154
+ ),
155
+ undefined,
156
+ ]),
157
+ ...overrideResponse,
158
+ });
159
+
141
160
  export const getListEvmAccountsMockHandler = (
142
161
  overrideResponse?:
143
162
  | ListEvmAccounts200
@@ -359,6 +378,27 @@ export const getSignEvmTypedDataMockHandler = (
359
378
  );
360
379
  });
361
380
  };
381
+
382
+ export const getImportEvmAccountMockHandler = (
383
+ overrideResponse?:
384
+ | EvmAccount
385
+ | ((info: Parameters<Parameters<typeof http.post>[1]>[0]) => Promise<EvmAccount> | EvmAccount),
386
+ ) => {
387
+ return http.post("*/v2/evm/accounts/import", async info => {
388
+ await delay(0);
389
+
390
+ return new HttpResponse(
391
+ JSON.stringify(
392
+ overrideResponse !== undefined
393
+ ? typeof overrideResponse === "function"
394
+ ? await overrideResponse(info)
395
+ : overrideResponse
396
+ : getImportEvmAccountResponseMock(),
397
+ ),
398
+ { status: 201, headers: { "Content-Type": "application/json" } },
399
+ );
400
+ });
401
+ };
362
402
  export const getEvmAccountsMock = () => [
363
403
  getListEvmAccountsMockHandler(),
364
404
  getCreateEvmAccountMockHandler(),
@@ -370,4 +410,5 @@ export const getEvmAccountsMock = () => [
370
410
  getSignEvmHashMockHandler(),
371
411
  getSignEvmMessageMockHandler(),
372
412
  getSignEvmTypedDataMockHandler(),
413
+ getImportEvmAccountMockHandler(),
373
414
  ];
@@ -9,6 +9,7 @@ import type {
9
9
  CreateEvmAccountBody,
10
10
  EIP712Message,
11
11
  EvmAccount,
12
+ ImportEvmAccountBody,
12
13
  ListEvmAccounts200,
13
14
  ListEvmAccountsParams,
14
15
  SendEvmTransaction200,
@@ -223,6 +224,24 @@ export const signEvmTypedData = (
223
224
  options,
224
225
  );
225
226
  };
227
+ /**
228
+ * Import an existing EVM account into the developer's CDP Project. This API should be called from the [CDP SDK](https://github.com/coinbase/cdp-sdk) to ensure that the associated private key is properly encrypted.
229
+ * @summary Import an EVM account
230
+ */
231
+ export const importEvmAccount = (
232
+ importEvmAccountBody: ImportEvmAccountBody,
233
+ options?: SecondParameter<typeof cdpApiClient>,
234
+ ) => {
235
+ return cdpApiClient<EvmAccount>(
236
+ {
237
+ url: `/v2/evm/accounts/import`,
238
+ method: "POST",
239
+ headers: { "Content-Type": "application/json" },
240
+ data: importEvmAccountBody,
241
+ },
242
+ options,
243
+ );
244
+ };
226
245
  export type ListEvmAccountsResult = NonNullable<Awaited<ReturnType<typeof listEvmAccounts>>>;
227
246
  export type CreateEvmAccountResult = NonNullable<Awaited<ReturnType<typeof createEvmAccount>>>;
228
247
  export type GetEvmAccountResult = NonNullable<Awaited<ReturnType<typeof getEvmAccount>>>;
@@ -235,3 +254,4 @@ export type SignEvmTransactionResult = NonNullable<Awaited<ReturnType<typeof sig
235
254
  export type SignEvmHashResult = NonNullable<Awaited<ReturnType<typeof signEvmHash>>>;
236
255
  export type SignEvmMessageResult = NonNullable<Awaited<ReturnType<typeof signEvmMessage>>>;
237
256
  export type SignEvmTypedDataResult = NonNullable<Awaited<ReturnType<typeof signEvmTypedData>>>;
257
+ export type ImportEvmAccountResult = NonNullable<Awaited<ReturnType<typeof importEvmAccount>>>;
@@ -1,6 +1,6 @@
1
- export * from "./faucets/faucets.msw.js";
2
- export * from "./policy-engine/policy-engine.msw.js";
3
1
  export * from "./evm-accounts/evm-accounts.msw.js";
4
- export * from "./evm-smart-accounts/evm-smart-accounts.msw.js";
5
2
  export * from "./evm-token-balances/evm-token-balances.msw.js";
3
+ export * from "./evm-smart-accounts/evm-smart-accounts.msw.js";
4
+ export * from "./faucets/faucets.msw.js";
5
+ export * from "./policy-engine/policy-engine.msw.js";
6
6
  export * from "./solana-accounts/solana-accounts.msw.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cdp-sdk",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "SDK for interacting with the Coinbase Developer Platform Wallet API",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",
package/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "1.9.0";
1
+ export const version = "1.10.0";