@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.
- package/CHANGELOG.md +22 -0
- package/README.md +41 -1
- package/_cjs/accounts/evm/toEvmServerAccount.js +5 -0
- package/_cjs/accounts/evm/toEvmServerAccount.js.map +1 -1
- package/_cjs/actions/evm/listTokenBalances.js +1 -1
- package/_cjs/actions/evm/listTokenBalances.js.map +1 -1
- package/_cjs/analytics.js +1 -1
- package/_cjs/analytics.js.map +1 -1
- package/_cjs/client/evm/evm.js +102 -2
- package/_cjs/client/evm/evm.js.map +1 -1
- package/_cjs/client/solana/solana.js +43 -0
- package/_cjs/client/solana/solana.js.map +1 -1
- package/_cjs/openapi-client/cdpApiClient.js +15 -2
- package/_cjs/openapi-client/cdpApiClient.js.map +1 -1
- package/_cjs/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js +1 -0
- package/_cjs/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
- package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.js +27 -1
- package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.js.map +1 -1
- package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.msw.js +32 -1
- package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.msw.js.map +1 -1
- package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js +9 -1
- package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js.map +1 -1
- package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.js +23 -1
- package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.js.map +1 -1
- package/_cjs/openapi-client/generated/faucets/faucets.js +1 -1
- package/_cjs/openapi-client/generated/index.msw.js +4 -4
- package/_cjs/openapi-client/generated/index.msw.js.map +1 -1
- package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js +27 -1
- package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
- package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.msw.js +32 -1
- package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.msw.js.map +1 -1
- package/_cjs/utils/export.js +84 -0
- package/_cjs/utils/export.js.map +1 -0
- package/_cjs/version.js +1 -1
- package/_esm/accounts/evm/toEvmServerAccount.js +6 -1
- package/_esm/accounts/evm/toEvmServerAccount.js.map +1 -1
- package/_esm/actions/evm/listTokenBalances.js +1 -1
- package/_esm/actions/evm/listTokenBalances.js.map +1 -1
- package/_esm/analytics.js +2 -2
- package/_esm/analytics.js.map +1 -1
- package/_esm/client/evm/evm.js +103 -3
- package/_esm/client/evm/evm.js.map +1 -1
- package/_esm/client/solana/solana.js +43 -0
- package/_esm/client/solana/solana.js.map +1 -1
- package/_esm/openapi-client/cdpApiClient.js +15 -2
- package/_esm/openapi-client/cdpApiClient.js.map +1 -1
- package/_esm/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js +1 -0
- package/_esm/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
- package/_esm/openapi-client/generated/evm-accounts/evm-accounts.js +24 -0
- package/_esm/openapi-client/generated/evm-accounts/evm-accounts.js.map +1 -1
- package/_esm/openapi-client/generated/evm-accounts/evm-accounts.msw.js +27 -0
- package/_esm/openapi-client/generated/evm-accounts/evm-accounts.msw.js.map +1 -1
- package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js +7 -0
- package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js.map +1 -1
- package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.js +20 -0
- package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.js.map +1 -1
- package/_esm/openapi-client/generated/faucets/faucets.js +1 -1
- package/_esm/openapi-client/generated/index.msw.js +4 -4
- package/_esm/openapi-client/generated/index.msw.js.map +1 -1
- package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js +24 -0
- package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
- package/_esm/openapi-client/generated/solana-accounts/solana-accounts.msw.js +27 -0
- package/_esm/openapi-client/generated/solana-accounts/solana-accounts.msw.js.map +1 -1
- package/_esm/utils/export.js +75 -0
- package/_esm/utils/export.js.map +1 -0
- package/_esm/version.js +1 -1
- package/_types/accounts/evm/toEvmServerAccount.d.ts.map +1 -1
- package/_types/actions/evm/listTokenBalances.d.ts +1 -1
- package/_types/client/cdp.d.ts +1 -2
- package/_types/client/cdp.d.ts.map +1 -1
- package/_types/client/evm/evm.d.ts +53 -4
- package/_types/client/evm/evm.d.ts.map +1 -1
- package/_types/client/evm/evm.types.d.ts +27 -2
- package/_types/client/evm/evm.types.d.ts.map +1 -1
- package/_types/client/solana/solana.d.ts +26 -1
- package/_types/client/solana/solana.d.ts.map +1 -1
- package/_types/client/solana/solana.types.d.ts +13 -1
- package/_types/client/solana/solana.types.d.ts.map +1 -1
- package/_types/openapi-client/cdpApiClient.d.ts.map +1 -1
- package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts +44 -4
- package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts.map +1 -1
- package/_types/openapi-client/generated/evm-accounts/evm-accounts.d.ts +13 -1
- package/_types/openapi-client/generated/evm-accounts/evm-accounts.d.ts.map +1 -1
- package/_types/openapi-client/generated/evm-accounts/evm-accounts.msw.d.ts +5 -1
- package/_types/openapi-client/generated/evm-accounts/evm-accounts.msw.d.ts.map +1 -1
- package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.d.ts +6 -0
- package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.d.ts.map +1 -1
- package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.d.ts +2 -0
- package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.d.ts.map +1 -1
- package/_types/openapi-client/generated/faucets/faucets.d.ts +1 -1
- package/_types/openapi-client/generated/index.msw.d.ts +4 -4
- package/_types/openapi-client/generated/index.msw.d.ts.map +1 -1
- package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts +13 -1
- package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts.map +1 -1
- package/_types/openapi-client/generated/solana-accounts/solana-accounts.msw.d.ts +5 -1
- package/_types/openapi-client/generated/solana-accounts/solana-accounts.msw.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/utils/export.d.ts +30 -0
- package/_types/utils/export.d.ts.map +1 -0
- package/_types/version.d.ts +1 -1
- package/accounts/evm/toEvmServerAccount.ts +6 -1
- package/actions/evm/listTokenBalances.ts +2 -2
- package/analytics.ts +2 -2
- package/client/cdp.ts +1 -1
- package/client/evm/evm.ts +140 -26
- package/client/evm/evm.types.ts +33 -1
- package/client/solana/solana.ts +61 -0
- package/client/solana/solana.types.ts +15 -0
- package/openapi-client/cdpApiClient.ts +17 -2
- package/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.ts +52 -4
- package/openapi-client/generated/evm-accounts/evm-accounts.msw.ts +61 -0
- package/openapi-client/generated/evm-accounts/evm-accounts.ts +46 -0
- package/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.msw.ts +38 -0
- package/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.ts +16 -0
- package/openapi-client/generated/faucets/faucets.ts +1 -1
- package/openapi-client/generated/index.msw.ts +4 -4
- package/openapi-client/generated/solana-accounts/solana-accounts.msw.ts +61 -0
- package/openapi-client/generated/solana-accounts/solana-accounts.ts +48 -0
- package/package.json +1 -1
- package/utils/export.ts +89 -0
- 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
package/utils/export.ts
ADDED
|
@@ -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.
|
|
1
|
+
export const version = "1.15.0";
|