@coinbase/cdp-sdk 1.13.0 → 1.15.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 (122) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +41 -1
  3. package/_cjs/accounts/evm/toEvmServerAccount.js +5 -0
  4. package/_cjs/accounts/evm/toEvmServerAccount.js.map +1 -1
  5. package/_cjs/actions/evm/listTokenBalances.js +1 -1
  6. package/_cjs/actions/evm/listTokenBalances.js.map +1 -1
  7. package/_cjs/analytics.js +1 -1
  8. package/_cjs/analytics.js.map +1 -1
  9. package/_cjs/client/evm/evm.js +102 -2
  10. package/_cjs/client/evm/evm.js.map +1 -1
  11. package/_cjs/client/solana/solana.js +43 -0
  12. package/_cjs/client/solana/solana.js.map +1 -1
  13. package/_cjs/openapi-client/cdpApiClient.js +15 -2
  14. package/_cjs/openapi-client/cdpApiClient.js.map +1 -1
  15. package/_cjs/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js +1 -0
  16. package/_cjs/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
  17. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.js +27 -1
  18. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.js.map +1 -1
  19. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.msw.js +32 -1
  20. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.msw.js.map +1 -1
  21. package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js +9 -1
  22. package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js.map +1 -1
  23. package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.js +23 -1
  24. package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.js.map +1 -1
  25. package/_cjs/openapi-client/generated/faucets/faucets.js +1 -1
  26. package/_cjs/openapi-client/generated/index.msw.js +4 -4
  27. package/_cjs/openapi-client/generated/index.msw.js.map +1 -1
  28. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js +27 -1
  29. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
  30. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.msw.js +32 -1
  31. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.msw.js.map +1 -1
  32. package/_cjs/utils/export.js +84 -0
  33. package/_cjs/utils/export.js.map +1 -0
  34. package/_cjs/version.js +1 -1
  35. package/_esm/accounts/evm/toEvmServerAccount.js +6 -1
  36. package/_esm/accounts/evm/toEvmServerAccount.js.map +1 -1
  37. package/_esm/actions/evm/listTokenBalances.js +1 -1
  38. package/_esm/actions/evm/listTokenBalances.js.map +1 -1
  39. package/_esm/analytics.js +2 -2
  40. package/_esm/analytics.js.map +1 -1
  41. package/_esm/client/evm/evm.js +103 -3
  42. package/_esm/client/evm/evm.js.map +1 -1
  43. package/_esm/client/solana/solana.js +43 -0
  44. package/_esm/client/solana/solana.js.map +1 -1
  45. package/_esm/openapi-client/cdpApiClient.js +15 -2
  46. package/_esm/openapi-client/cdpApiClient.js.map +1 -1
  47. package/_esm/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js +1 -0
  48. package/_esm/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
  49. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.js +24 -0
  50. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.js.map +1 -1
  51. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.msw.js +27 -0
  52. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.msw.js.map +1 -1
  53. package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js +7 -0
  54. package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js.map +1 -1
  55. package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.js +20 -0
  56. package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.js.map +1 -1
  57. package/_esm/openapi-client/generated/faucets/faucets.js +1 -1
  58. package/_esm/openapi-client/generated/index.msw.js +4 -4
  59. package/_esm/openapi-client/generated/index.msw.js.map +1 -1
  60. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js +24 -0
  61. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
  62. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.msw.js +27 -0
  63. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.msw.js.map +1 -1
  64. package/_esm/utils/export.js +75 -0
  65. package/_esm/utils/export.js.map +1 -0
  66. package/_esm/version.js +1 -1
  67. package/_types/accounts/evm/toEvmServerAccount.d.ts.map +1 -1
  68. package/_types/actions/evm/listTokenBalances.d.ts +1 -1
  69. package/_types/client/cdp.d.ts +1 -2
  70. package/_types/client/cdp.d.ts.map +1 -1
  71. package/_types/client/evm/evm.d.ts +53 -4
  72. package/_types/client/evm/evm.d.ts.map +1 -1
  73. package/_types/client/evm/evm.types.d.ts +27 -2
  74. package/_types/client/evm/evm.types.d.ts.map +1 -1
  75. package/_types/client/solana/solana.d.ts +26 -1
  76. package/_types/client/solana/solana.d.ts.map +1 -1
  77. package/_types/client/solana/solana.types.d.ts +13 -1
  78. package/_types/client/solana/solana.types.d.ts.map +1 -1
  79. package/_types/openapi-client/cdpApiClient.d.ts.map +1 -1
  80. package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts +44 -4
  81. package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts.map +1 -1
  82. package/_types/openapi-client/generated/evm-accounts/evm-accounts.d.ts +13 -1
  83. package/_types/openapi-client/generated/evm-accounts/evm-accounts.d.ts.map +1 -1
  84. package/_types/openapi-client/generated/evm-accounts/evm-accounts.msw.d.ts +5 -1
  85. package/_types/openapi-client/generated/evm-accounts/evm-accounts.msw.d.ts.map +1 -1
  86. package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.d.ts +6 -0
  87. package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.d.ts.map +1 -1
  88. package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.d.ts +2 -0
  89. package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.d.ts.map +1 -1
  90. package/_types/openapi-client/generated/faucets/faucets.d.ts +1 -1
  91. package/_types/openapi-client/generated/index.msw.d.ts +4 -4
  92. package/_types/openapi-client/generated/index.msw.d.ts.map +1 -1
  93. package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts +13 -1
  94. package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts.map +1 -1
  95. package/_types/openapi-client/generated/solana-accounts/solana-accounts.msw.d.ts +5 -1
  96. package/_types/openapi-client/generated/solana-accounts/solana-accounts.msw.d.ts.map +1 -1
  97. package/_types/openapi-client/index.d.ts +10 -0
  98. package/_types/openapi-client/index.d.ts.map +1 -1
  99. package/_types/utils/export.d.ts +30 -0
  100. package/_types/utils/export.d.ts.map +1 -0
  101. package/_types/version.d.ts +1 -1
  102. package/accounts/evm/toEvmServerAccount.ts +6 -1
  103. package/actions/evm/listTokenBalances.ts +2 -2
  104. package/analytics.ts +2 -2
  105. package/client/cdp.ts +1 -1
  106. package/client/evm/evm.ts +140 -26
  107. package/client/evm/evm.types.ts +33 -1
  108. package/client/solana/solana.ts +61 -0
  109. package/client/solana/solana.types.ts +15 -0
  110. package/openapi-client/cdpApiClient.ts +17 -2
  111. package/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.ts +52 -4
  112. package/openapi-client/generated/evm-accounts/evm-accounts.msw.ts +61 -0
  113. package/openapi-client/generated/evm-accounts/evm-accounts.ts +46 -0
  114. package/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.ts +38 -0
  115. package/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.ts +16 -0
  116. package/openapi-client/generated/faucets/faucets.ts +1 -1
  117. package/openapi-client/generated/index.msw.ts +4 -4
  118. package/openapi-client/generated/solana-accounts/solana-accounts.msw.ts +61 -0
  119. package/openapi-client/generated/solana-accounts/solana-accounts.ts +48 -0
  120. package/package.json +1 -1
  121. package/utils/export.ts +89 -0
  122. package/version.ts +1 -1
@@ -11,6 +11,8 @@ import { HttpResponse, delay, http } from "msw";
11
11
 
12
12
  import type {
13
13
  EvmAccount,
14
+ ExportEvmAccount200,
15
+ ExportEvmAccountByName200,
14
16
  ListEvmAccounts200,
15
17
  SendEvmTransaction200,
16
18
  SignEvmHash200,
@@ -157,6 +159,17 @@ export const getImportEvmAccountResponseMock = (
157
159
  ...overrideResponse,
158
160
  });
159
161
 
162
+ export const getExportEvmAccountResponseMock = (
163
+ overrideResponse: Partial<ExportEvmAccount200> = {},
164
+ ): ExportEvmAccount200 => ({ encryptedPrivateKey: faker.string.alpha(20), ...overrideResponse });
165
+
166
+ export const getExportEvmAccountByNameResponseMock = (
167
+ overrideResponse: Partial<ExportEvmAccountByName200> = {},
168
+ ): ExportEvmAccountByName200 => ({
169
+ encryptedPrivateKey: faker.string.alpha(20),
170
+ ...overrideResponse,
171
+ });
172
+
160
173
  export const getListEvmAccountsMockHandler = (
161
174
  overrideResponse?:
162
175
  | ListEvmAccounts200
@@ -399,6 +412,52 @@ export const getImportEvmAccountMockHandler = (
399
412
  );
400
413
  });
401
414
  };
415
+
416
+ export const getExportEvmAccountMockHandler = (
417
+ overrideResponse?:
418
+ | ExportEvmAccount200
419
+ | ((
420
+ info: Parameters<Parameters<typeof http.post>[1]>[0],
421
+ ) => Promise<ExportEvmAccount200> | ExportEvmAccount200),
422
+ ) => {
423
+ return http.post("*/v2/evm/accounts/:address/export", async info => {
424
+ await delay(0);
425
+
426
+ return new HttpResponse(
427
+ JSON.stringify(
428
+ overrideResponse !== undefined
429
+ ? typeof overrideResponse === "function"
430
+ ? await overrideResponse(info)
431
+ : overrideResponse
432
+ : getExportEvmAccountResponseMock(),
433
+ ),
434
+ { status: 200, headers: { "Content-Type": "application/json" } },
435
+ );
436
+ });
437
+ };
438
+
439
+ export const getExportEvmAccountByNameMockHandler = (
440
+ overrideResponse?:
441
+ | ExportEvmAccountByName200
442
+ | ((
443
+ info: Parameters<Parameters<typeof http.post>[1]>[0],
444
+ ) => Promise<ExportEvmAccountByName200> | ExportEvmAccountByName200),
445
+ ) => {
446
+ return http.post("*/v2/evm/accounts/export/by-name/:name", async info => {
447
+ await delay(0);
448
+
449
+ return new HttpResponse(
450
+ JSON.stringify(
451
+ overrideResponse !== undefined
452
+ ? typeof overrideResponse === "function"
453
+ ? await overrideResponse(info)
454
+ : overrideResponse
455
+ : getExportEvmAccountByNameResponseMock(),
456
+ ),
457
+ { status: 200, headers: { "Content-Type": "application/json" } },
458
+ );
459
+ });
460
+ };
402
461
  export const getEvmAccountsMock = () => [
403
462
  getListEvmAccountsMockHandler(),
404
463
  getCreateEvmAccountMockHandler(),
@@ -411,4 +470,6 @@ export const getEvmAccountsMock = () => [
411
470
  getSignEvmMessageMockHandler(),
412
471
  getSignEvmTypedDataMockHandler(),
413
472
  getImportEvmAccountMockHandler(),
473
+ getExportEvmAccountMockHandler(),
474
+ getExportEvmAccountByNameMockHandler(),
414
475
  ];
@@ -9,6 +9,10 @@ import type {
9
9
  CreateEvmAccountBody,
10
10
  EIP712Message,
11
11
  EvmAccount,
12
+ ExportEvmAccount200,
13
+ ExportEvmAccountBody,
14
+ ExportEvmAccountByName200,
15
+ ExportEvmAccountByNameBody,
12
16
  ImportEvmAccountBody,
13
17
  ListEvmAccounts200,
14
18
  ListEvmAccountsParams,
@@ -242,6 +246,44 @@ export const importEvmAccount = (
242
246
  options,
243
247
  );
244
248
  };
249
+ /**
250
+ * Export an existing EVM account's private key. It is important to store the private key in a secure place after it's exported.
251
+ * @summary Export an EVM account
252
+ */
253
+ export const exportEvmAccount = (
254
+ address: string,
255
+ exportEvmAccountBody: ExportEvmAccountBody,
256
+ options?: SecondParameter<typeof cdpApiClient>,
257
+ ) => {
258
+ return cdpApiClient<ExportEvmAccount200>(
259
+ {
260
+ url: `/v2/evm/accounts/${address}/export`,
261
+ method: "POST",
262
+ headers: { "Content-Type": "application/json" },
263
+ data: exportEvmAccountBody,
264
+ },
265
+ options,
266
+ );
267
+ };
268
+ /**
269
+ * Export an existing EVM account's private key by its name. It is important to store the private key in a secure place after it's exported.
270
+ * @summary Export an EVM account by name
271
+ */
272
+ export const exportEvmAccountByName = (
273
+ name: string,
274
+ exportEvmAccountByNameBody: ExportEvmAccountByNameBody,
275
+ options?: SecondParameter<typeof cdpApiClient>,
276
+ ) => {
277
+ return cdpApiClient<ExportEvmAccountByName200>(
278
+ {
279
+ url: `/v2/evm/accounts/export/by-name/${name}`,
280
+ method: "POST",
281
+ headers: { "Content-Type": "application/json" },
282
+ data: exportEvmAccountByNameBody,
283
+ },
284
+ options,
285
+ );
286
+ };
245
287
  export type ListEvmAccountsResult = NonNullable<Awaited<ReturnType<typeof listEvmAccounts>>>;
246
288
  export type CreateEvmAccountResult = NonNullable<Awaited<ReturnType<typeof createEvmAccount>>>;
247
289
  export type GetEvmAccountResult = NonNullable<Awaited<ReturnType<typeof getEvmAccount>>>;
@@ -255,3 +297,7 @@ export type SignEvmHashResult = NonNullable<Awaited<ReturnType<typeof signEvmHas
255
297
  export type SignEvmMessageResult = NonNullable<Awaited<ReturnType<typeof signEvmMessage>>>;
256
298
  export type SignEvmTypedDataResult = NonNullable<Awaited<ReturnType<typeof signEvmTypedData>>>;
257
299
  export type ImportEvmAccountResult = NonNullable<Awaited<ReturnType<typeof importEvmAccount>>>;
300
+ export type ExportEvmAccountResult = NonNullable<Awaited<ReturnType<typeof exportEvmAccount>>>;
301
+ export type ExportEvmAccountByNameResult = NonNullable<
302
+ Awaited<ReturnType<typeof exportEvmAccountByName>>
303
+ >;
@@ -47,6 +47,20 @@ export const getCreateEvmSmartAccountResponseMock = (
47
47
  ...overrideResponse,
48
48
  });
49
49
 
50
+ export const getGetEvmSmartAccountByNameResponseMock = (
51
+ overrideResponse: Partial<EvmSmartAccount> = {},
52
+ ): EvmSmartAccount => ({
53
+ address: faker.helpers.fromRegExp("^0x[0-9a-fA-F]{40}$"),
54
+ owners: Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() =>
55
+ faker.helpers.fromRegExp("^0x[0-9a-fA-F]{40}$"),
56
+ ),
57
+ name: faker.helpers.arrayElement([
58
+ faker.helpers.fromRegExp("^[A-Za-z0-9][A-Za-z0-9-]{0,34}[A-Za-z0-9]$"),
59
+ undefined,
60
+ ]),
61
+ ...overrideResponse,
62
+ });
63
+
50
64
  export const getGetEvmSmartAccountResponseMock = (
51
65
  overrideResponse: Partial<EvmSmartAccount> = {},
52
66
  ): EvmSmartAccount => ({
@@ -179,6 +193,29 @@ export const getCreateEvmSmartAccountMockHandler = (
179
193
  });
180
194
  };
181
195
 
196
+ export const getGetEvmSmartAccountByNameMockHandler = (
197
+ overrideResponse?:
198
+ | EvmSmartAccount
199
+ | ((
200
+ info: Parameters<Parameters<typeof http.get>[1]>[0],
201
+ ) => Promise<EvmSmartAccount> | EvmSmartAccount),
202
+ ) => {
203
+ return http.get("*/v2/evm/smart-accounts/by-name/:name", async info => {
204
+ await delay(0);
205
+
206
+ return new HttpResponse(
207
+ JSON.stringify(
208
+ overrideResponse !== undefined
209
+ ? typeof overrideResponse === "function"
210
+ ? await overrideResponse(info)
211
+ : overrideResponse
212
+ : getGetEvmSmartAccountByNameResponseMock(),
213
+ ),
214
+ { status: 200, headers: { "Content-Type": "application/json" } },
215
+ );
216
+ });
217
+ };
218
+
182
219
  export const getGetEvmSmartAccountMockHandler = (
183
220
  overrideResponse?:
184
221
  | EvmSmartAccount
@@ -276,6 +313,7 @@ export const getSendUserOperationMockHandler = (
276
313
  export const getEvmSmartAccountsMock = () => [
277
314
  getListEvmSmartAccountsMockHandler(),
278
315
  getCreateEvmSmartAccountMockHandler(),
316
+ getGetEvmSmartAccountByNameMockHandler(),
279
317
  getGetEvmSmartAccountMockHandler(),
280
318
  getPrepareUserOperationMockHandler(),
281
319
  getGetUserOperationMockHandler(),
@@ -51,6 +51,19 @@ export const createEvmSmartAccount = (
51
51
  options,
52
52
  );
53
53
  };
54
+ /**
55
+ * Gets a Smart Account by its name.
56
+ * @summary Get a Smart Account by name
57
+ */
58
+ export const getEvmSmartAccountByName = (
59
+ name: string,
60
+ options?: SecondParameter<typeof cdpApiClient>,
61
+ ) => {
62
+ return cdpApiClient<EvmSmartAccount>(
63
+ { url: `/v2/evm/smart-accounts/by-name/${name}`, method: "GET" },
64
+ options,
65
+ );
66
+ };
54
67
  /**
55
68
  * Gets a Smart Account by its address.
56
69
  * @summary Get a Smart Account by address
@@ -126,6 +139,9 @@ export type ListEvmSmartAccountsResult = NonNullable<
126
139
  export type CreateEvmSmartAccountResult = NonNullable<
127
140
  Awaited<ReturnType<typeof createEvmSmartAccount>>
128
141
  >;
142
+ export type GetEvmSmartAccountByNameResult = NonNullable<
143
+ Awaited<ReturnType<typeof getEvmSmartAccountByName>>
144
+ >;
129
145
  export type GetEvmSmartAccountResult = NonNullable<Awaited<ReturnType<typeof getEvmSmartAccount>>>;
130
146
  export type PrepareUserOperationResult = NonNullable<
131
147
  Awaited<ReturnType<typeof prepareUserOperation>>
@@ -19,7 +19,7 @@ type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
19
19
  /**
20
20
  * Request funds from the CDP Faucet on supported EVM test networks.
21
21
 
22
- Faucets are available for ETH, USDC, EURC, and cbBTC on Base Sepolia and Ethereum Sepolia.
22
+ Faucets are available for ETH, USDC, EURC, and cbBTC on Base Sepolia and Ethereum Sepolia, and for ETH only on Ethereum Hoodi.
23
23
 
24
24
  To prevent abuse, we enforce rate limits within a rolling 24-hour window to control the amount of funds that can be requested.
25
25
  These limits are applied at both the CDP User level and the blockchain address level.
@@ -1,8 +1,8 @@
1
- export * from "./faucets/faucets.msw.js";
2
1
  export * from "./evm-accounts/evm-accounts.msw.js";
3
- export * from "./evm-token-balances/evm-token-balances.msw.js";
4
- export * from "./policy-engine/policy-engine.msw.js";
5
- export * from "./evm-smart-accounts/evm-smart-accounts.msw.js";
6
2
  export * from "./evm-swaps/evm-swaps.msw.js";
7
3
  export * from "./solana-accounts/solana-accounts.msw.js";
4
+ export * from "./policy-engine/policy-engine.msw.js";
5
+ export * from "./evm-token-balances/evm-token-balances.msw.js";
6
+ export * from "./faucets/faucets.msw.js";
8
7
  export * from "./payments-alpha/payments-alpha.msw.js";
8
+ export * from "./evm-smart-accounts/evm-smart-accounts.msw.js";
@@ -10,6 +10,8 @@ import { faker } from "@faker-js/faker";
10
10
  import { HttpResponse, delay, http } from "msw";
11
11
 
12
12
  import type {
13
+ ExportSolanaAccount200,
14
+ ExportSolanaAccountByName200,
13
15
  ListSolanaAccounts200,
14
16
  SignSolanaMessage200,
15
17
  SignSolanaTransaction200,
@@ -115,6 +117,17 @@ export const getGetSolanaAccountByNameResponseMock = (
115
117
  ...overrideResponse,
116
118
  });
117
119
 
120
+ export const getExportSolanaAccountResponseMock = (
121
+ overrideResponse: Partial<ExportSolanaAccount200> = {},
122
+ ): ExportSolanaAccount200 => ({ encryptedPrivateKey: faker.string.alpha(20), ...overrideResponse });
123
+
124
+ export const getExportSolanaAccountByNameResponseMock = (
125
+ overrideResponse: Partial<ExportSolanaAccountByName200> = {},
126
+ ): ExportSolanaAccountByName200 => ({
127
+ encryptedPrivateKey: faker.string.alpha(20),
128
+ ...overrideResponse,
129
+ });
130
+
118
131
  export const getSignSolanaTransactionResponseMock = (
119
132
  overrideResponse: Partial<SignSolanaTransaction200> = {},
120
133
  ): SignSolanaTransaction200 => ({ signedTransaction: faker.string.alpha(20), ...overrideResponse });
@@ -238,6 +251,52 @@ export const getGetSolanaAccountByNameMockHandler = (
238
251
  });
239
252
  };
240
253
 
254
+ export const getExportSolanaAccountMockHandler = (
255
+ overrideResponse?:
256
+ | ExportSolanaAccount200
257
+ | ((
258
+ info: Parameters<Parameters<typeof http.post>[1]>[0],
259
+ ) => Promise<ExportSolanaAccount200> | ExportSolanaAccount200),
260
+ ) => {
261
+ return http.post("*/v2/solana/accounts/:address/export", async info => {
262
+ await delay(0);
263
+
264
+ return new HttpResponse(
265
+ JSON.stringify(
266
+ overrideResponse !== undefined
267
+ ? typeof overrideResponse === "function"
268
+ ? await overrideResponse(info)
269
+ : overrideResponse
270
+ : getExportSolanaAccountResponseMock(),
271
+ ),
272
+ { status: 200, headers: { "Content-Type": "application/json" } },
273
+ );
274
+ });
275
+ };
276
+
277
+ export const getExportSolanaAccountByNameMockHandler = (
278
+ overrideResponse?:
279
+ | ExportSolanaAccountByName200
280
+ | ((
281
+ info: Parameters<Parameters<typeof http.post>[1]>[0],
282
+ ) => Promise<ExportSolanaAccountByName200> | ExportSolanaAccountByName200),
283
+ ) => {
284
+ return http.post("*/v2/solana/accounts/export/by-name/:name", async info => {
285
+ await delay(0);
286
+
287
+ return new HttpResponse(
288
+ JSON.stringify(
289
+ overrideResponse !== undefined
290
+ ? typeof overrideResponse === "function"
291
+ ? await overrideResponse(info)
292
+ : overrideResponse
293
+ : getExportSolanaAccountByNameResponseMock(),
294
+ ),
295
+ { status: 200, headers: { "Content-Type": "application/json" } },
296
+ );
297
+ });
298
+ };
299
+
241
300
  export const getSignSolanaTransactionMockHandler = (
242
301
  overrideResponse?:
243
302
  | SignSolanaTransaction200
@@ -289,6 +348,8 @@ export const getSolanaAccountsMock = () => [
289
348
  getGetSolanaAccountMockHandler(),
290
349
  getUpdateSolanaAccountMockHandler(),
291
350
  getGetSolanaAccountByNameMockHandler(),
351
+ getExportSolanaAccountMockHandler(),
352
+ getExportSolanaAccountByNameMockHandler(),
292
353
  getSignSolanaTransactionMockHandler(),
293
354
  getSignSolanaMessageMockHandler(),
294
355
  ];
@@ -7,6 +7,10 @@
7
7
  */
8
8
  import type {
9
9
  CreateSolanaAccountBody,
10
+ ExportSolanaAccount200,
11
+ ExportSolanaAccountBody,
12
+ ExportSolanaAccountByName200,
13
+ ExportSolanaAccountByNameBody,
10
14
  ListSolanaAccounts200,
11
15
  ListSolanaAccountsParams,
12
16
  SignSolanaMessage200,
@@ -100,6 +104,44 @@ export const getSolanaAccountByName = (
100
104
  options,
101
105
  );
102
106
  };
107
+ /**
108
+ * Export an existing Solana account's private key. It is important to store the private key in a secure place after it's exported.
109
+ * @summary Export an Solana account
110
+ */
111
+ export const exportSolanaAccount = (
112
+ address: string,
113
+ exportSolanaAccountBody: ExportSolanaAccountBody,
114
+ options?: SecondParameter<typeof cdpApiClient>,
115
+ ) => {
116
+ return cdpApiClient<ExportSolanaAccount200>(
117
+ {
118
+ url: `/v2/solana/accounts/${address}/export`,
119
+ method: "POST",
120
+ headers: { "Content-Type": "application/json" },
121
+ data: exportSolanaAccountBody,
122
+ },
123
+ options,
124
+ );
125
+ };
126
+ /**
127
+ * Export an existing Solana account's private key by its name. It is important to store the private key in a secure place after it's exported.
128
+ * @summary Export a Solana account by name
129
+ */
130
+ export const exportSolanaAccountByName = (
131
+ name: string,
132
+ exportSolanaAccountByNameBody: ExportSolanaAccountByNameBody,
133
+ options?: SecondParameter<typeof cdpApiClient>,
134
+ ) => {
135
+ return cdpApiClient<ExportSolanaAccountByName200>(
136
+ {
137
+ url: `/v2/solana/accounts/export/by-name/${name}`,
138
+ method: "POST",
139
+ headers: { "Content-Type": "application/json" },
140
+ data: exportSolanaAccountByNameBody,
141
+ },
142
+ options,
143
+ );
144
+ };
103
145
  /**
104
146
  * Signs a transaction with the given Solana account.
105
147
  The unsigned transaction should be serialized into a byte array and then encoded as base64.
@@ -160,6 +202,12 @@ export type UpdateSolanaAccountResult = NonNullable<
160
202
  export type GetSolanaAccountByNameResult = NonNullable<
161
203
  Awaited<ReturnType<typeof getSolanaAccountByName>>
162
204
  >;
205
+ export type ExportSolanaAccountResult = NonNullable<
206
+ Awaited<ReturnType<typeof exportSolanaAccount>>
207
+ >;
208
+ export type ExportSolanaAccountByNameResult = NonNullable<
209
+ Awaited<ReturnType<typeof exportSolanaAccountByName>>
210
+ >;
163
211
  export type SignSolanaTransactionResult = NonNullable<
164
212
  Awaited<ReturnType<typeof signSolanaTransaction>>
165
213
  >;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cdp-sdk",
3
- "version": "1.13.0",
3
+ "version": "1.15.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",
@@ -0,0 +1,89 @@
1
+ import { generateKeyPair, privateDecrypt, constants, createPrivateKey } from "crypto";
2
+
3
+ import { Keypair } from "@solana/web3.js";
4
+ import bs58 from "bs58";
5
+
6
+ /**
7
+ * Generates a new RSA key pair with 4096-bit private key.
8
+ * - Private key in PKCS1 DER format
9
+ * - Public key in PKIX/SPKI DER format
10
+ *
11
+ * @returns A promise that resolves to the generated key pair, or rejects with an error.
12
+ */
13
+ export const generateExportEncryptionKeyPair = async () => {
14
+ return await new Promise<{
15
+ publicKey: string;
16
+ privateKey: string;
17
+ }>((resolve, reject) => {
18
+ generateKeyPair(
19
+ "rsa",
20
+ {
21
+ modulusLength: 4096,
22
+ publicKeyEncoding: {
23
+ type: "spki",
24
+ format: "der",
25
+ },
26
+ privateKeyEncoding: {
27
+ type: "pkcs1",
28
+ format: "der",
29
+ },
30
+ },
31
+ (err, publicKey, privateKey) => {
32
+ if (err) {
33
+ reject(err);
34
+ }
35
+ resolve({
36
+ publicKey: publicKey.toString("base64"),
37
+ privateKey: privateKey.toString("base64"),
38
+ });
39
+ },
40
+ );
41
+ });
42
+ };
43
+
44
+ /**
45
+ * Decrypts a ciphertext using RSA-OAEP-SHA256.
46
+ * - Parses PKCS1 private key
47
+ * - Uses RSA-OAEP-SHA256 for decryption
48
+ * - Returns hex-encoded result
49
+ *
50
+ * @param b64PrivateKey - The base64-encoded private key in PKCS1 DER format.
51
+ * @param b64Cipher - The base64-encoded ciphertext.
52
+ * @returns The decrypted key hex string, or throws an error if decryption fails.
53
+ */
54
+ export const decryptWithPrivateKey = (b64PrivateKey: string, b64Cipher: string): string => {
55
+ try {
56
+ // Create a private key object from the PKCS1 DER format
57
+ const privateKey = createPrivateKey({
58
+ key: Buffer.from(b64PrivateKey, "base64"),
59
+ format: "der",
60
+ type: "pkcs1",
61
+ });
62
+
63
+ const decryptedBuffer = privateDecrypt(
64
+ {
65
+ key: privateKey,
66
+ padding: constants.RSA_PKCS1_OAEP_PADDING,
67
+ oaepHash: "sha256",
68
+ },
69
+ Buffer.from(b64Cipher, "base64"),
70
+ );
71
+
72
+ return decryptedBuffer.toString("hex");
73
+ } catch (error) {
74
+ throw new Error(`Decryption failed: ${String(error)}`);
75
+ }
76
+ };
77
+
78
+ /**
79
+ * Format a private key to a base58 string for easy import into Solana wallet apps.
80
+ *
81
+ * @param privateKey - The private key as a hex string
82
+ * @returns The formatted private key as a base58 string
83
+ */
84
+ export const formatSolanaPrivateKey = (privateKey: string): string => {
85
+ const privateKeyBytes = Buffer.from(privateKey, "hex");
86
+ const keypair = Keypair.fromSeed(privateKeyBytes);
87
+ const fullKey = Buffer.concat([keypair.secretKey.subarray(0, 32), keypair.publicKey.toBytes()]);
88
+ return bs58.encode(fullKey);
89
+ };
package/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "1.13.0";
1
+ export const version = "1.15.0";