@coinbase/cdp-sdk 1.26.0 → 1.28.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 (178) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +58 -2
  3. package/_cjs/accounts/evm/resolveViemClients.js +3 -2
  4. package/_cjs/accounts/evm/resolveViemClients.js.map +1 -1
  5. package/_cjs/accounts/evm/toEvmServerAccount.js +84 -0
  6. package/_cjs/accounts/evm/toEvmServerAccount.js.map +1 -1
  7. package/_cjs/accounts/evm/toEvmSmartAccount.js +83 -0
  8. package/_cjs/accounts/evm/toEvmSmartAccount.js.map +1 -1
  9. package/_cjs/accounts/evm/toNetworkScopedEvmServerAccount.js +30 -6
  10. package/_cjs/accounts/evm/toNetworkScopedEvmServerAccount.js.map +1 -1
  11. package/_cjs/accounts/evm/toNetworkScopedEvmSmartAccount.js +65 -0
  12. package/_cjs/accounts/evm/toNetworkScopedEvmSmartAccount.js.map +1 -1
  13. package/_cjs/accounts/solana/toSolanaAccount.js +20 -0
  14. package/_cjs/accounts/solana/toSolanaAccount.js.map +1 -1
  15. package/_cjs/actions/evm/fund/fund.js +3 -2
  16. package/_cjs/actions/evm/fund/fund.js.map +1 -1
  17. package/_cjs/actions/evm/fund/quoteFund.js +3 -2
  18. package/_cjs/actions/evm/fund/quoteFund.js.map +1 -1
  19. package/_cjs/actions/solana/sendTransaction.js +32 -0
  20. package/_cjs/actions/solana/sendTransaction.js.map +1 -0
  21. package/_cjs/actions/solana/transfer.js +25 -38
  22. package/_cjs/actions/solana/transfer.js.map +1 -1
  23. package/_cjs/actions/solana/utils.js +4 -14
  24. package/_cjs/actions/solana/utils.js.map +1 -1
  25. package/_cjs/analytics.js +39 -3
  26. package/_cjs/analytics.js.map +1 -1
  27. package/_cjs/auth/utils/jwt.js +6 -5
  28. package/_cjs/auth/utils/jwt.js.map +1 -1
  29. package/_cjs/client/cdp.js +4 -1
  30. package/_cjs/client/cdp.js.map +1 -1
  31. package/_cjs/client/evm/evm.js +116 -10
  32. package/_cjs/client/evm/evm.js.map +1 -1
  33. package/_cjs/client/policies/policies.js +22 -0
  34. package/_cjs/client/policies/policies.js.map +1 -1
  35. package/_cjs/client/solana/solana.js +83 -6
  36. package/_cjs/client/solana/solana.js.map +1 -1
  37. package/_cjs/constants.js +1 -1
  38. package/_cjs/constants.js.map +1 -1
  39. package/_cjs/errors.js +19 -1
  40. package/_cjs/errors.js.map +1 -1
  41. package/_cjs/index.js +3 -1
  42. package/_cjs/index.js.map +1 -1
  43. package/_cjs/openapi-client/cdpApiClient.js +46 -6
  44. package/_cjs/openapi-client/cdpApiClient.js.map +1 -1
  45. package/_cjs/openapi-client/errors.js +38 -9
  46. package/_cjs/openapi-client/errors.js.map +1 -1
  47. package/_cjs/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js +6 -1
  48. package/_cjs/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
  49. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js +34 -1
  50. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
  51. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.msw.js +18 -1
  52. package/_cjs/openapi-client/generated/solana-accounts/solana-accounts.msw.js.map +1 -1
  53. package/_cjs/policies/schema.js +6 -6
  54. package/_cjs/version.js +1 -1
  55. package/_esm/accounts/evm/resolveViemClients.js +3 -2
  56. package/_esm/accounts/evm/resolveViemClients.js.map +1 -1
  57. package/_esm/accounts/evm/toEvmServerAccount.js +84 -0
  58. package/_esm/accounts/evm/toEvmServerAccount.js.map +1 -1
  59. package/_esm/accounts/evm/toEvmSmartAccount.js +83 -0
  60. package/_esm/accounts/evm/toEvmSmartAccount.js.map +1 -1
  61. package/_esm/accounts/evm/toNetworkScopedEvmServerAccount.js +30 -6
  62. package/_esm/accounts/evm/toNetworkScopedEvmServerAccount.js.map +1 -1
  63. package/_esm/accounts/evm/toNetworkScopedEvmSmartAccount.js +65 -0
  64. package/_esm/accounts/evm/toNetworkScopedEvmSmartAccount.js.map +1 -1
  65. package/_esm/accounts/solana/toSolanaAccount.js +20 -0
  66. package/_esm/accounts/solana/toSolanaAccount.js.map +1 -1
  67. package/_esm/actions/evm/fund/fund.js +3 -2
  68. package/_esm/actions/evm/fund/fund.js.map +1 -1
  69. package/_esm/actions/evm/fund/quoteFund.js +3 -2
  70. package/_esm/actions/evm/fund/quoteFund.js.map +1 -1
  71. package/_esm/actions/solana/sendTransaction.js +29 -0
  72. package/_esm/actions/solana/sendTransaction.js.map +1 -0
  73. package/_esm/actions/solana/transfer.js +26 -39
  74. package/_esm/actions/solana/transfer.js.map +1 -1
  75. package/_esm/actions/solana/utils.js +5 -15
  76. package/_esm/actions/solana/utils.js.map +1 -1
  77. package/_esm/analytics.js +39 -3
  78. package/_esm/analytics.js.map +1 -1
  79. package/_esm/auth/utils/jwt.js +3 -2
  80. package/_esm/auth/utils/jwt.js.map +1 -1
  81. package/_esm/client/cdp.js +4 -1
  82. package/_esm/client/cdp.js.map +1 -1
  83. package/_esm/client/evm/evm.js +110 -4
  84. package/_esm/client/evm/evm.js.map +1 -1
  85. package/_esm/client/policies/policies.js +22 -0
  86. package/_esm/client/policies/policies.js.map +1 -1
  87. package/_esm/client/solana/solana.js +80 -3
  88. package/_esm/client/solana/solana.js.map +1 -1
  89. package/_esm/constants.js +1 -1
  90. package/_esm/constants.js.map +1 -1
  91. package/_esm/errors.js +17 -0
  92. package/_esm/errors.js.map +1 -1
  93. package/_esm/index.js +1 -0
  94. package/_esm/index.js.map +1 -1
  95. package/_esm/openapi-client/cdpApiClient.js +47 -7
  96. package/_esm/openapi-client/cdpApiClient.js.map +1 -1
  97. package/_esm/openapi-client/errors.js +36 -8
  98. package/_esm/openapi-client/errors.js.map +1 -1
  99. package/_esm/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js +5 -0
  100. package/_esm/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
  101. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js +32 -0
  102. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.js.map +1 -1
  103. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.msw.js +15 -0
  104. package/_esm/openapi-client/generated/solana-accounts/solana-accounts.msw.js.map +1 -1
  105. package/_esm/policies/schema.js +6 -6
  106. package/_esm/version.js +1 -1
  107. package/_types/accounts/evm/resolveViemClients.d.ts.map +1 -1
  108. package/_types/accounts/evm/toEvmServerAccount.d.ts.map +1 -1
  109. package/_types/accounts/evm/toEvmSmartAccount.d.ts.map +1 -1
  110. package/_types/accounts/evm/toNetworkScopedEvmServerAccount.d.ts.map +1 -1
  111. package/_types/accounts/evm/toNetworkScopedEvmSmartAccount.d.ts.map +1 -1
  112. package/_types/accounts/solana/toSolanaAccount.d.ts.map +1 -1
  113. package/_types/actions/evm/fund/fund.d.ts.map +1 -1
  114. package/_types/actions/evm/fund/quoteFund.d.ts.map +1 -1
  115. package/_types/actions/solana/sendTransaction.d.ts +23 -0
  116. package/_types/actions/solana/sendTransaction.d.ts.map +1 -0
  117. package/_types/actions/solana/transfer.d.ts.map +1 -1
  118. package/_types/actions/solana/utils.d.ts +2 -2
  119. package/_types/actions/solana/utils.d.ts.map +1 -1
  120. package/_types/analytics.d.ts +36 -1
  121. package/_types/analytics.d.ts.map +1 -1
  122. package/_types/auth/utils/jwt.d.ts.map +1 -1
  123. package/_types/client/cdp.d.ts.map +1 -1
  124. package/_types/client/evm/evm.d.ts +1 -0
  125. package/_types/client/evm/evm.d.ts.map +1 -1
  126. package/_types/client/policies/policies.d.ts.map +1 -1
  127. package/_types/client/solana/solana.d.ts +20 -1
  128. package/_types/client/solana/solana.d.ts.map +1 -1
  129. package/_types/client/solana/solana.types.d.ts +21 -2
  130. package/_types/client/solana/solana.types.d.ts.map +1 -1
  131. package/_types/constants.d.ts +1 -1
  132. package/_types/constants.d.ts.map +1 -1
  133. package/_types/errors.d.ts +11 -0
  134. package/_types/errors.d.ts.map +1 -1
  135. package/_types/index.d.ts +1 -0
  136. package/_types/index.d.ts.map +1 -1
  137. package/_types/openapi-client/cdpApiClient.d.ts.map +1 -1
  138. package/_types/openapi-client/errors.d.ts +46 -9
  139. package/_types/openapi-client/errors.d.ts.map +1 -1
  140. package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts +18 -0
  141. package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts.map +1 -1
  142. package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts +27 -1
  143. package/_types/openapi-client/generated/solana-accounts/solana-accounts.d.ts.map +1 -1
  144. package/_types/openapi-client/generated/solana-accounts/solana-accounts.msw.d.ts +3 -1
  145. package/_types/openapi-client/generated/solana-accounts/solana-accounts.msw.d.ts.map +1 -1
  146. package/_types/openapi-client/index.d.ts +2 -0
  147. package/_types/openapi-client/index.d.ts.map +1 -1
  148. package/_types/policies/schema.d.ts +34 -34
  149. package/_types/version.d.ts +1 -1
  150. package/accounts/evm/resolveViemClients.ts +5 -2
  151. package/accounts/evm/toEvmServerAccount.ts +98 -0
  152. package/accounts/evm/toEvmSmartAccount.ts +96 -0
  153. package/accounts/evm/toNetworkScopedEvmServerAccount.ts +34 -6
  154. package/accounts/evm/toNetworkScopedEvmSmartAccount.ts +75 -0
  155. package/accounts/solana/toSolanaAccount.ts +24 -0
  156. package/actions/evm/fund/fund.ts +3 -2
  157. package/actions/evm/fund/quoteFund.ts +3 -2
  158. package/actions/solana/sendTransaction.ts +38 -0
  159. package/actions/solana/transfer.ts +33 -52
  160. package/actions/solana/utils.ts +5 -13
  161. package/analytics.ts +73 -4
  162. package/auth/utils/jwt.ts +5 -2
  163. package/client/cdp.ts +7 -1
  164. package/client/evm/evm.ts +135 -6
  165. package/client/policies/policies.ts +28 -0
  166. package/client/solana/solana.ts +95 -3
  167. package/client/solana/solana.types.ts +24 -0
  168. package/constants.ts +1 -1
  169. package/errors.ts +18 -0
  170. package/index.ts +1 -0
  171. package/openapi-client/cdpApiClient.ts +87 -17
  172. package/openapi-client/errors.ts +65 -10
  173. package/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.ts +24 -0
  174. package/openapi-client/generated/solana-accounts/solana-accounts.msw.ts +32 -0
  175. package/openapi-client/generated/solana-accounts/solana-accounts.ts +43 -0
  176. package/package.json +1 -1
  177. package/policies/schema.ts +6 -6
  178. package/version.ts +1 -1
package/client/evm/evm.ts CHANGED
@@ -62,6 +62,7 @@ import {
62
62
  } from "../../actions/evm/waitForUserOperation.js";
63
63
  import { Analytics } from "../../analytics.js";
64
64
  import { ImportAccountPublicRSAKey } from "../../constants.js";
65
+ import { UserInputValidationError } from "../../errors.js";
65
66
  import { APIError } from "../../openapi-client/errors.js";
66
67
  import {
67
68
  CdpOpenApiClient,
@@ -114,6 +115,11 @@ export class EvmClient implements EvmClientInterface {
114
115
  * ```
115
116
  */
116
117
  async createAccount(options: CreateServerAccountOptions = {}): Promise<ServerAccount> {
118
+ Analytics.trackAction({
119
+ action: "create_account",
120
+ accountType: "evm_server",
121
+ });
122
+
117
123
  const openApiAccount = await CdpOpenApiClient.createEvmAccount(
118
124
  {
119
125
  name: options.name,
@@ -174,6 +180,11 @@ export class EvmClient implements EvmClientInterface {
174
180
  * ```
175
181
  */
176
182
  async importAccount(options: ImportServerAccountOptions): Promise<ServerAccount> {
183
+ Analytics.trackAction({
184
+ action: "import_account",
185
+ accountType: "evm_server",
186
+ });
187
+
177
188
  const encryptionPublicKey = options.encryptionPublicKey || ImportAccountPublicRSAKey;
178
189
 
179
190
  const privateKeyHex = options.privateKey.startsWith("0x")
@@ -181,7 +192,7 @@ export class EvmClient implements EvmClientInterface {
181
192
  : options.privateKey;
182
193
 
183
194
  if (!/^[0-9a-fA-F]+$/.test(privateKeyHex)) {
184
- throw new Error("Private key must be a valid hexadecimal string");
195
+ throw new UserInputValidationError("Private key must be a valid hexadecimal string");
185
196
  }
186
197
 
187
198
  try {
@@ -245,6 +256,11 @@ export class EvmClient implements EvmClientInterface {
245
256
  * ```
246
257
  */
247
258
  async exportAccount(options: ExportServerAccountOptions): Promise<string> {
259
+ Analytics.trackAction({
260
+ action: "export_account",
261
+ accountType: "evm_server",
262
+ });
263
+
248
264
  const { publicKey, privateKey } = await generateExportEncryptionKeyPair();
249
265
 
250
266
  const { encryptedPrivateKey } = await (async () => {
@@ -268,7 +284,7 @@ export class EvmClient implements EvmClientInterface {
268
284
  );
269
285
  }
270
286
 
271
- throw new Error("Either address or name must be provided");
287
+ throw new UserInputValidationError("Either address or name must be provided");
272
288
  })();
273
289
 
274
290
  return decryptWithPrivateKey(privateKey, encryptedPrivateKey);
@@ -320,6 +336,11 @@ export class EvmClient implements EvmClientInterface {
320
336
  * ```
321
337
  */
322
338
  async createSmartAccount(options: CreateSmartAccountOptions): Promise<SmartAccount> {
339
+ Analytics.trackAction({
340
+ action: "create_smart_account",
341
+ accountType: "evm_smart",
342
+ });
343
+
323
344
  const openApiSmartAccount = await CdpOpenApiClient.createEvmSmartAccount(
324
345
  {
325
346
  owners: [options.owner.address],
@@ -364,6 +385,11 @@ export class EvmClient implements EvmClientInterface {
364
385
  * ```
365
386
  */
366
387
  async getAccount(options: GetServerAccountOptions): Promise<ServerAccount> {
388
+ Analytics.trackAction({
389
+ action: "get_account",
390
+ accountType: "evm_server",
391
+ });
392
+
367
393
  const openApiAccount = await (() => {
368
394
  if (options.address) {
369
395
  return CdpOpenApiClient.getEvmAccount(options.address);
@@ -373,7 +399,7 @@ export class EvmClient implements EvmClientInterface {
373
399
  return CdpOpenApiClient.getEvmAccountByName(options.name);
374
400
  }
375
401
 
376
- throw new Error("Either address or name must be provided");
402
+ throw new UserInputValidationError("Either address or name must be provided");
377
403
  })();
378
404
 
379
405
  const account = toEvmServerAccount(CdpOpenApiClient, {
@@ -408,13 +434,17 @@ export class EvmClient implements EvmClientInterface {
408
434
  * ```
409
435
  */
410
436
  async getSmartAccount(options: GetSmartAccountOptions): Promise<SmartAccount> {
437
+ Analytics.trackAction({
438
+ action: "get_smart_account",
439
+ });
440
+
411
441
  const openApiSmartAccount = await (async () => {
412
442
  if (options.address) {
413
443
  return CdpOpenApiClient.getEvmSmartAccount(options.address);
414
444
  } else if (options.name) {
415
445
  return CdpOpenApiClient.getEvmSmartAccountByName(options.name);
416
446
  }
417
- throw new Error("Either address or name must be provided");
447
+ throw new UserInputValidationError("Either address or name must be provided");
418
448
  })();
419
449
 
420
450
  const smartAccount = toEvmSmartAccount(CdpOpenApiClient, {
@@ -443,6 +473,11 @@ export class EvmClient implements EvmClientInterface {
443
473
  * ```
444
474
  */
445
475
  async getOrCreateAccount(options: GetOrCreateServerAccountOptions): Promise<ServerAccount> {
476
+ Analytics.trackAction({
477
+ action: "get_or_create_account",
478
+ accountType: "evm_server",
479
+ });
480
+
446
481
  try {
447
482
  const account = await this.getAccount(options);
448
483
  return account;
@@ -463,7 +498,6 @@ export class EvmClient implements EvmClientInterface {
463
498
  throw error;
464
499
  }
465
500
  }
466
-
467
501
  throw error;
468
502
  }
469
503
  }
@@ -488,6 +522,11 @@ export class EvmClient implements EvmClientInterface {
488
522
  * ```
489
523
  */
490
524
  async getOrCreateSmartAccount(options: GetOrCreateSmartAccountOptions): Promise<SmartAccount> {
525
+ Analytics.trackAction({
526
+ action: "get_or_create_smart_account",
527
+ accountType: "evm_smart",
528
+ });
529
+
491
530
  try {
492
531
  const account = await this.getSmartAccount(options);
493
532
  return account;
@@ -508,7 +547,6 @@ export class EvmClient implements EvmClientInterface {
508
547
  throw error;
509
548
  }
510
549
  }
511
-
512
550
  throw error;
513
551
  }
514
552
  }
@@ -534,6 +572,13 @@ export class EvmClient implements EvmClientInterface {
534
572
  async getSwapPrice(
535
573
  options: GetSwapPriceOptions,
536
574
  ): Promise<GetSwapPriceResult | SwapUnavailableResult> {
575
+ Analytics.trackAction({
576
+ action: "get_swap_price",
577
+ properties: {
578
+ network: options.network,
579
+ },
580
+ });
581
+
537
582
  return getSwapPrice(CdpOpenApiClient, options);
538
583
  }
539
584
 
@@ -558,6 +603,13 @@ export class EvmClient implements EvmClientInterface {
558
603
  async createSwapQuote(
559
604
  options: CreateSwapQuoteOptions,
560
605
  ): Promise<CreateSwapQuoteResult | SwapUnavailableResult> {
606
+ Analytics.trackAction({
607
+ action: "create_swap_quote",
608
+ properties: {
609
+ network: options.network,
610
+ },
611
+ });
612
+
561
613
  return createSwapQuote(CdpOpenApiClient, options);
562
614
  }
563
615
 
@@ -579,6 +631,10 @@ export class EvmClient implements EvmClientInterface {
579
631
  * ```
580
632
  */
581
633
  async getUserOperation(options: GetUserOperationOptions): Promise<UserOperation> {
634
+ Analytics.trackAction({
635
+ action: "get_user_operation",
636
+ });
637
+
582
638
  return getUserOperation(CdpOpenApiClient, options);
583
639
  }
584
640
 
@@ -607,6 +663,11 @@ export class EvmClient implements EvmClientInterface {
607
663
  * ```
608
664
  */
609
665
  async listAccounts(options: ListServerAccountsOptions = {}): Promise<ListServerAccountResult> {
666
+ Analytics.trackAction({
667
+ action: "list_accounts",
668
+ accountType: "evm_server",
669
+ });
670
+
610
671
  const ethAccounts = await CdpOpenApiClient.listEvmAccounts({
611
672
  pageSize: options.pageSize,
612
673
  pageToken: options.pageToken,
@@ -661,6 +722,13 @@ export class EvmClient implements EvmClientInterface {
661
722
  * }
662
723
  */
663
724
  async listTokenBalances(options: ListTokenBalancesOptions): Promise<ListTokenBalancesResult> {
725
+ Analytics.trackAction({
726
+ action: "list_token_balances",
727
+ properties: {
728
+ network: options.network,
729
+ },
730
+ });
731
+
664
732
  return listTokenBalances(CdpOpenApiClient, options);
665
733
  }
666
734
 
@@ -686,8 +754,13 @@ export class EvmClient implements EvmClientInterface {
686
754
  * while (page.nextPageToken) {
687
755
  * page = await cdp.evm.listSmartAccounts({ pageToken: page.nextPageToken });
688
756
  * }
757
+ * ```
689
758
  */
690
759
  async listSmartAccounts(options: ListSmartAccountsOptions = {}): Promise<ListSmartAccountResult> {
760
+ Analytics.trackAction({
761
+ action: "list_smart_accounts",
762
+ });
763
+
691
764
  const smartAccounts = await CdpOpenApiClient.listEvmSmartAccounts({
692
765
  pageSize: options.pageSize,
693
766
  pageToken: options.pageToken,
@@ -731,6 +804,13 @@ export class EvmClient implements EvmClientInterface {
731
804
  * ```
732
805
  */
733
806
  async prepareUserOperation(options: PrepareUserOperationOptions): Promise<UserOperation> {
807
+ Analytics.trackAction({
808
+ action: "prepare_user_operation",
809
+ properties: {
810
+ network: options.network,
811
+ },
812
+ });
813
+
734
814
  const userOp = await CdpOpenApiClient.prepareUserOperation(options.smartAccount.address, {
735
815
  network: options.network,
736
816
  calls: options.calls.map(call => ({
@@ -774,6 +854,13 @@ export class EvmClient implements EvmClientInterface {
774
854
  * ```
775
855
  */
776
856
  async requestFaucet(options: RequestFaucetOptions): Promise<RequestFaucetResult> {
857
+ Analytics.trackAction({
858
+ action: "request_faucet",
859
+ properties: {
860
+ network: options.network,
861
+ },
862
+ });
863
+
777
864
  return requestFaucet(CdpOpenApiClient, options);
778
865
  }
779
866
 
@@ -824,6 +911,13 @@ export class EvmClient implements EvmClientInterface {
824
911
  * ```
825
912
  */
826
913
  async sendTransaction(options: SendTransactionOptions): Promise<TransactionResult> {
914
+ Analytics.trackAction({
915
+ action: "send_transaction",
916
+ properties: {
917
+ network: options.network,
918
+ },
919
+ });
920
+
827
921
  return sendTransaction(CdpOpenApiClient, options);
828
922
  }
829
923
 
@@ -858,6 +952,13 @@ export class EvmClient implements EvmClientInterface {
858
952
  async sendUserOperation(
859
953
  options: SendUserOperationOptions<unknown[]>,
860
954
  ): Promise<SendUserOperationReturnType> {
955
+ Analytics.trackAction({
956
+ action: "send_user_operation",
957
+ properties: {
958
+ network: options.network,
959
+ },
960
+ });
961
+
861
962
  return sendUserOperation(CdpOpenApiClient, {
862
963
  smartAccount: options.smartAccount,
863
964
  network: options.network,
@@ -889,6 +990,10 @@ export class EvmClient implements EvmClientInterface {
889
990
  * ```
890
991
  */
891
992
  async signHash(options: SignHashOptions): Promise<SignatureResult> {
993
+ Analytics.trackAction({
994
+ action: "sign_hash",
995
+ });
996
+
892
997
  const signature = await CdpOpenApiClient.signEvmHash(
893
998
  options.address,
894
999
  {
@@ -924,6 +1029,10 @@ export class EvmClient implements EvmClientInterface {
924
1029
  * ```
925
1030
  */
926
1031
  async signMessage(options: SignMessageOptions): Promise<SignatureResult> {
1032
+ Analytics.trackAction({
1033
+ action: "sign_message",
1034
+ });
1035
+
927
1036
  const signature = await CdpOpenApiClient.signEvmMessage(
928
1037
  options.address,
929
1038
  {
@@ -983,6 +1092,10 @@ export class EvmClient implements EvmClientInterface {
983
1092
  * ```
984
1093
  */
985
1094
  async signTypedData(options: SignTypedDataOptions): Promise<SignatureResult> {
1095
+ Analytics.trackAction({
1096
+ action: "sign_typed_data",
1097
+ });
1098
+
986
1099
  const { domain, message, primaryType } = options;
987
1100
  const types = {
988
1101
  EIP712Domain: getTypesForEIP712Domain({ domain }),
@@ -1038,6 +1151,10 @@ export class EvmClient implements EvmClientInterface {
1038
1151
  * ```
1039
1152
  */
1040
1153
  async signTransaction(options: SignTransactionOptions): Promise<SignatureResult> {
1154
+ Analytics.trackAction({
1155
+ action: "sign_transaction",
1156
+ });
1157
+
1041
1158
  const signature = await CdpOpenApiClient.signEvmTransaction(
1042
1159
  options.address,
1043
1160
  {
@@ -1093,6 +1210,10 @@ export class EvmClient implements EvmClientInterface {
1093
1210
  * ```
1094
1211
  */
1095
1212
  async updateAccount(options: UpdateEvmAccountOptions): Promise<ServerAccount> {
1213
+ Analytics.trackAction({
1214
+ action: "update_account",
1215
+ });
1216
+
1096
1217
  const openApiAccount = await CdpOpenApiClient.updateEvmAccount(
1097
1218
  options.address,
1098
1219
  options.update,
@@ -1121,6 +1242,10 @@ export class EvmClient implements EvmClientInterface {
1121
1242
  * @returns A promise that resolves to the updated account.
1122
1243
  */
1123
1244
  async updateSmartAccount(options: UpdateEvmSmartAccountOptions): Promise<SmartAccount> {
1245
+ Analytics.trackAction({
1246
+ action: "update_smart_account",
1247
+ });
1248
+
1124
1249
  const openApiSmartAccount = await CdpOpenApiClient.updateEvmSmartAccount(
1125
1250
  options.address,
1126
1251
  options.update,
@@ -1172,6 +1297,10 @@ export class EvmClient implements EvmClientInterface {
1172
1297
  async waitForUserOperation(
1173
1298
  options: WaitForUserOperationOptions,
1174
1299
  ): Promise<WaitForUserOperationReturnType> {
1300
+ Analytics.trackAction({
1301
+ action: "wait_for_user_operation",
1302
+ });
1303
+
1175
1304
  return waitForUserOperation(CdpOpenApiClient, {
1176
1305
  ...options,
1177
1306
  });
@@ -7,6 +7,7 @@ import {
7
7
  DeletePolicyOptions,
8
8
  UpdatePolicyOptions,
9
9
  } from "./policies.types.js";
10
+ import { Analytics } from "../../analytics.js";
10
11
  import {
11
12
  CdpOpenApiClient,
12
13
  CreatePolicyBody,
@@ -57,6 +58,13 @@ export class PoliciesClient implements PoliciesClientInterface {
57
58
  * ```
58
59
  */
59
60
  async listPolicies(options: ListPoliciesOptions = {}): Promise<ListPoliciesResult> {
61
+ Analytics.trackAction({
62
+ action: "list_policies",
63
+ properties: {
64
+ scope: options.scope,
65
+ },
66
+ });
67
+
60
68
  return CdpOpenApiClient.listPolicies(options) as Promise<ListPoliciesResult>;
61
69
  }
62
70
 
@@ -129,10 +137,18 @@ export class PoliciesClient implements PoliciesClientInterface {
129
137
  * ```
130
138
  */
131
139
  async createPolicy(options: CreatePolicyOptions): Promise<Policy> {
140
+ Analytics.trackAction({
141
+ action: "create_policy",
142
+ properties: {
143
+ scope: options.policy.scope,
144
+ },
145
+ });
146
+
132
147
  CreatePolicyBodySchema.parse(options.policy);
133
148
  return CdpOpenApiClient.createPolicy(
134
149
  // There are arbitrary differences between the abitype Abi and the openapi Abi
135
150
  options.policy as CreatePolicyBody,
151
+
136
152
  options.idempotencyKey,
137
153
  ) as Promise<Policy>;
138
154
  }
@@ -156,6 +172,10 @@ export class PoliciesClient implements PoliciesClientInterface {
156
172
  * ```
157
173
  */
158
174
  async getPolicyById(options: GetPolicyByIdOptions): Promise<Policy> {
175
+ Analytics.trackAction({
176
+ action: "get_policy_by_id",
177
+ });
178
+
159
179
  return CdpOpenApiClient.getPolicyById(options.id) as Promise<Policy>;
160
180
  }
161
181
 
@@ -188,6 +208,10 @@ export class PoliciesClient implements PoliciesClientInterface {
188
208
  * ```
189
209
  */
190
210
  async deletePolicy(options: DeletePolicyOptions): Promise<void> {
211
+ Analytics.trackAction({
212
+ action: "delete_policy",
213
+ });
214
+
191
215
  return CdpOpenApiClient.deletePolicy(options.id, options.idempotencyKey);
192
216
  }
193
217
 
@@ -244,6 +268,10 @@ export class PoliciesClient implements PoliciesClientInterface {
244
268
  * ```
245
269
  */
246
270
  async updatePolicy(options: UpdatePolicyOptions): Promise<Policy> {
271
+ Analytics.trackAction({
272
+ action: "update_policy",
273
+ });
274
+
247
275
  UpdatePolicyBodySchema.parse(options.policy);
248
276
  return CdpOpenApiClient.updatePolicy(
249
277
  options.id,
@@ -13,19 +13,23 @@ import {
13
13
  ListTokenBalancesOptions,
14
14
  ListTokenBalancesResult,
15
15
  RequestFaucetOptions,
16
+ SendTransactionOptions,
16
17
  SignatureResult,
17
18
  SignMessageOptions,
18
19
  SignTransactionOptions,
19
20
  SolanaClientInterface,
21
+ TransactionResult,
20
22
  UpdateSolanaAccountOptions,
21
23
  } from "./solana.types.js";
22
24
  import { toSolanaAccount } from "../../accounts/solana/toSolanaAccount.js";
23
25
  import { SolanaAccount } from "../../accounts/solana/types.js";
24
26
  import { requestFaucet } from "../../actions/solana/requestFaucet.js";
27
+ import { sendTransaction } from "../../actions/solana/sendTransaction.js";
25
28
  import { signMessage } from "../../actions/solana/signMessage.js";
26
29
  import { signTransaction } from "../../actions/solana/signTransaction.js";
27
30
  import { Analytics } from "../../analytics.js";
28
31
  import { ImportAccountPublicRSAKey } from "../../constants.js";
32
+ import { UserInputValidationError } from "../../errors.js";
29
33
  import { APIError } from "../../openapi-client/errors.js";
30
34
  import { CdpOpenApiClient } from "../../openapi-client/index.js";
31
35
  import {
@@ -69,6 +73,11 @@ export class SolanaClient implements SolanaClientInterface {
69
73
  * ```
70
74
  */
71
75
  async createAccount(options: CreateAccountOptions = {}): Promise<SolanaAccount> {
76
+ Analytics.trackAction({
77
+ action: "create_account",
78
+ accountType: "solana",
79
+ });
80
+
72
81
  const openApiAccount = await CdpOpenApiClient.createSolanaAccount(
73
82
  {
74
83
  name: options.name,
@@ -111,6 +120,11 @@ export class SolanaClient implements SolanaClientInterface {
111
120
  * ```
112
121
  */
113
122
  async exportAccount(options: ExportAccountOptions): Promise<string> {
123
+ Analytics.trackAction({
124
+ action: "export_account",
125
+ accountType: "solana",
126
+ });
127
+
114
128
  const { publicKey, privateKey } = await generateExportEncryptionKeyPair();
115
129
 
116
130
  const { encryptedPrivateKey } = await (async () => {
@@ -134,7 +148,7 @@ export class SolanaClient implements SolanaClientInterface {
134
148
  );
135
149
  }
136
150
 
137
- throw new Error("Either address or name must be provided");
151
+ throw new UserInputValidationError("Either address or name must be provided");
138
152
  })();
139
153
 
140
154
  const decryptedPrivateKey = decryptWithPrivateKey(privateKey, encryptedPrivateKey);
@@ -180,6 +194,11 @@ export class SolanaClient implements SolanaClientInterface {
180
194
  * ```
181
195
  */
182
196
  async importAccount(options: ImportAccountOptions): Promise<SolanaAccount> {
197
+ Analytics.trackAction({
198
+ action: "import_account",
199
+ accountType: "solana",
200
+ });
201
+
183
202
  let privateKeyBytes: Uint8Array = new Uint8Array();
184
203
 
185
204
  if (typeof options.privateKey === "string") {
@@ -189,7 +208,7 @@ export class SolanaClient implements SolanaClientInterface {
189
208
  }
190
209
 
191
210
  if (privateKeyBytes.length !== 32 && privateKeyBytes.length !== 64) {
192
- throw new Error("Invalid private key length");
211
+ throw new UserInputValidationError("Invalid private key length");
193
212
  }
194
213
 
195
214
  if (privateKeyBytes.length === 64) {
@@ -250,6 +269,11 @@ export class SolanaClient implements SolanaClientInterface {
250
269
  * ```
251
270
  */
252
271
  async getAccount(options: GetAccountOptions): Promise<SolanaAccount> {
272
+ Analytics.trackAction({
273
+ action: "get_account",
274
+ accountType: "solana",
275
+ });
276
+
253
277
  const openApiAccount = await (() => {
254
278
  if (options.address) {
255
279
  return CdpOpenApiClient.getSolanaAccount(options.address);
@@ -259,7 +283,7 @@ export class SolanaClient implements SolanaClientInterface {
259
283
  return CdpOpenApiClient.getSolanaAccountByName(options.name);
260
284
  }
261
285
 
262
- throw new Error("Either address or name must be provided");
286
+ throw new UserInputValidationError("Either address or name must be provided");
263
287
  })();
264
288
 
265
289
  const account = toSolanaAccount(CdpOpenApiClient, {
@@ -287,6 +311,11 @@ export class SolanaClient implements SolanaClientInterface {
287
311
  * ```
288
312
  */
289
313
  async getOrCreateAccount(options: GetOrCreateAccountOptions): Promise<SolanaAccount> {
314
+ Analytics.trackAction({
315
+ action: "get_or_create_account",
316
+ accountType: "solana",
317
+ });
318
+
290
319
  try {
291
320
  const account = await this.getAccount(options);
292
321
  return account;
@@ -341,6 +370,11 @@ export class SolanaClient implements SolanaClientInterface {
341
370
  * ```
342
371
  */
343
372
  async listAccounts(options: ListAccountsOptions = {}): Promise<ListAccountsResult> {
373
+ Analytics.trackAction({
374
+ action: "list_accounts",
375
+ accountType: "solana",
376
+ });
377
+
344
378
  const solAccounts = await CdpOpenApiClient.listSolanaAccounts({
345
379
  pageSize: options.pageSize,
346
380
  pageToken: options.pageToken,
@@ -379,6 +413,11 @@ export class SolanaClient implements SolanaClientInterface {
379
413
  * ```
380
414
  */
381
415
  async requestFaucet(options: RequestFaucetOptions): Promise<SignatureResult> {
416
+ Analytics.trackAction({
417
+ action: "request_faucet",
418
+ accountType: "solana",
419
+ });
420
+
382
421
  return requestFaucet(CdpOpenApiClient, options);
383
422
  }
384
423
 
@@ -405,6 +444,11 @@ export class SolanaClient implements SolanaClientInterface {
405
444
  * ```
406
445
  */
407
446
  async signMessage(options: SignMessageOptions): Promise<SignatureResult> {
447
+ Analytics.trackAction({
448
+ action: "sign_message",
449
+ accountType: "solana",
450
+ });
451
+
408
452
  return signMessage(CdpOpenApiClient, options);
409
453
  }
410
454
 
@@ -442,6 +486,11 @@ export class SolanaClient implements SolanaClientInterface {
442
486
  * ```
443
487
  */
444
488
  async signTransaction(options: SignTransactionOptions): Promise<SignatureResult> {
489
+ Analytics.trackAction({
490
+ action: "sign_transaction",
491
+ accountType: "solana",
492
+ });
493
+
445
494
  return signTransaction(CdpOpenApiClient, options);
446
495
  }
447
496
 
@@ -487,6 +536,11 @@ export class SolanaClient implements SolanaClientInterface {
487
536
  * ```
488
537
  */
489
538
  async updateAccount(options: UpdateSolanaAccountOptions): Promise<SolanaAccount> {
539
+ Analytics.trackAction({
540
+ action: "update_account",
541
+ accountType: "solana",
542
+ });
543
+
490
544
  const openApiAccount = await CdpOpenApiClient.updateSolanaAccount(
491
545
  options.address,
492
546
  options.update,
@@ -502,6 +556,36 @@ export class SolanaClient implements SolanaClientInterface {
502
556
  return account;
503
557
  }
504
558
 
559
+ /**
560
+ * Sends a Solana transaction using the Coinbase API.
561
+ *
562
+ * @param {SendTransactionOptions} options - Parameters for sending the Solana transaction.
563
+ * @param {string} options.network - The network to send the transaction to.
564
+ * @param {string} options.transaction - The base64 encoded transaction to send.
565
+ * @param {string} [options.idempotencyKey] - An idempotency key.
566
+ *
567
+ * @returns A promise that resolves to the transaction result.
568
+ *
569
+ * @example
570
+ * ```ts
571
+ * const signature = await cdp.solana.sendTransaction({
572
+ * network: "solana-devnet",
573
+ * transaction: "...",
574
+ * });
575
+ * ```
576
+ */
577
+ async sendTransaction(options: SendTransactionOptions): Promise<TransactionResult> {
578
+ Analytics.trackAction({
579
+ action: "send_transaction",
580
+ accountType: "solana",
581
+ properties: {
582
+ network: options.network,
583
+ },
584
+ });
585
+
586
+ return sendTransaction(CdpOpenApiClient, options);
587
+ }
588
+
505
589
  /**
506
590
  * Lists the token balances for a Solana account.
507
591
  *
@@ -520,6 +604,14 @@ export class SolanaClient implements SolanaClientInterface {
520
604
  * ```
521
605
  */
522
606
  async listTokenBalances(options: ListTokenBalancesOptions): Promise<ListTokenBalancesResult> {
607
+ Analytics.trackAction({
608
+ action: "list_token_balances",
609
+ accountType: "solana",
610
+ properties: {
611
+ network: options.network,
612
+ },
613
+ });
614
+
523
615
  const tokenBalances = await CdpOpenApiClient.listSolanaTokenBalances(
524
616
  options.network || "solana",
525
617
  options.address,
@@ -2,6 +2,8 @@ import { Account, SolanaAccount } from "../../accounts/solana/types.js";
2
2
  import {
3
3
  ListSolanaTokenBalancesNetwork,
4
4
  OpenApiSolanaMethods,
5
+ SendSolanaTransactionBody,
6
+ SendSolanaTransactionBodyNetwork,
5
7
  UpdateSolanaAccountBody,
6
8
  } from "../../openapi-client/index.js";
7
9
 
@@ -23,6 +25,7 @@ export type SolanaClientInterface = Omit<
23
25
  | "exportSolanaAccountByName" // mapped to exportAccount
24
26
  | "importSolanaAccount" // mapped to importAccount
25
27
  | "listSolanaTokenBalances" // mapped to listTokenBalances
28
+ | "sendSolanaTransaction" // mapped to sendTransaction
26
29
  > & {
27
30
  createAccount: (options: CreateAccountOptions) => Promise<Account>;
28
31
  exportAccount: (options: ExportAccountOptions) => Promise<string>;
@@ -35,6 +38,7 @@ export type SolanaClientInterface = Omit<
35
38
  signMessage: (options: SignMessageOptions) => Promise<SignatureResult>;
36
39
  signTransaction: (options: SignTransactionOptions) => Promise<SignatureResult>;
37
40
  listTokenBalances: (options: ListTokenBalancesOptions) => Promise<ListTokenBalancesResult>;
41
+ sendTransaction: (options: SendSolanaTransactionBody) => Promise<SignatureResult>;
38
42
  };
39
43
 
40
44
  /**
@@ -185,6 +189,26 @@ export interface ListTokenBalancesOptions {
185
189
  pageToken?: string;
186
190
  }
187
191
 
192
+ /**
193
+ * Options for sending a Solana transaction.
194
+ */
195
+ export interface SendTransactionOptions {
196
+ /** The network to send the transaction to. */
197
+ network: SendSolanaTransactionBodyNetwork;
198
+ /** The base64 encoded transaction to send. */
199
+ transaction: string;
200
+ /** The idempotency key. */
201
+ idempotencyKey?: string;
202
+ }
203
+
204
+ /**
205
+ * The result of sending a Solana transaction.
206
+ */
207
+ export interface TransactionResult {
208
+ /** The signature of the transaction base58 encoded. */
209
+ signature: string;
210
+ }
211
+
188
212
  export interface SolanaTokenAmount {
189
213
  /** The amount of the token. */
190
214
  amount: bigint;
package/constants.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * The URL to the Coinbase CDP API error docs page.
3
3
  */
4
- export const ERROR_DOCS_PAGE_URL = "https://docs.cdp.coinbase.com/api-v2/docs/errors";
4
+ export const ERROR_DOCS_PAGE_URL = "https://docs.cdp.coinbase.com/api-reference/v2/errors";
5
5
 
6
6
  /**
7
7
  * The public RSA key used to encrypt the private key when importing an EVM or Solana account.