@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
@@ -1,6 +1,7 @@
1
1
  import { formatUnits } from "viem";
2
2
 
3
3
  import { FundOperationResult } from "./types.js";
4
+ import { UserInputValidationError } from "../../../errors.js";
4
5
  import {
5
6
  CreatePaymentTransferQuoteBodySourceType,
6
7
  CreatePaymentTransferQuoteBodyTargetType,
@@ -42,8 +43,8 @@ export async function fund(
42
43
  throw new Error("No card found to fund account");
43
44
  }
44
45
 
45
- if (options.token.toLowerCase() !== "eth" && options.token.toLowerCase() !== "usdc") {
46
- throw new Error("Invalid currency, must be eth or usdc");
46
+ if (options.token !== "eth" && options.token !== "usdc") {
47
+ throw new UserInputValidationError("Invalid token, must be eth or usdc");
47
48
  }
48
49
 
49
50
  const decimals = options.token === "eth" ? 18 : 6;
@@ -1,6 +1,7 @@
1
1
  import { formatUnits } from "viem";
2
2
 
3
3
  import { Quote } from "./Quote.js";
4
+ import { UserInputValidationError } from "../../../errors.js";
4
5
  import {
5
6
  CreatePaymentTransferQuoteBodySourceType,
6
7
  CreatePaymentTransferQuoteBodyTargetType,
@@ -42,8 +43,8 @@ export async function quoteFund(
42
43
  throw new Error("No card found to fund account");
43
44
  }
44
45
 
45
- if (options.token.toLowerCase() !== "eth" && options.token.toLowerCase() !== "usdc") {
46
- throw new Error("Invalid currency, must be eth or usdc");
46
+ if (options.token !== "eth" && options.token !== "usdc") {
47
+ throw new UserInputValidationError("Invalid token, must be eth or usdc");
47
48
  }
48
49
 
49
50
  const decimals = options.token === "eth" ? 18 : 6;
@@ -0,0 +1,38 @@
1
+ import { SendTransactionOptions, TransactionResult } from "../../client/solana/solana.types.js";
2
+ import { CdpOpenApiClientType } from "../../openapi-client/index.js";
3
+
4
+ /**
5
+ * Sends a Solana transaction using the Coinbase API.
6
+ *
7
+ * @param {CdpOpenApiClientType} apiClient - The API client to use.
8
+ * @param {SendTransactionOptions} options - Parameters for sending the Solana transaction.
9
+ * @param {string} options.network - The network to send the transaction to.
10
+ * @param {string} options.transaction - The base64 encoded transaction to send.
11
+ * @param {string} [options.idempotencyKey] - An idempotency key.
12
+ *
13
+ * @returns A promise that resolves to the transaction result.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const signature = await sendTransaction({
18
+ * network: "solana-devnet",
19
+ * transaction: "...",
20
+ * });
21
+ * ```
22
+ */
23
+ export async function sendTransaction(
24
+ apiClient: CdpOpenApiClientType,
25
+ options: SendTransactionOptions,
26
+ ): Promise<TransactionResult> {
27
+ const signature = await apiClient.sendSolanaTransaction(
28
+ {
29
+ network: options.network,
30
+ transaction: options.transaction,
31
+ },
32
+ options.idempotencyKey,
33
+ );
34
+
35
+ return {
36
+ signature: signature.transactionSignature,
37
+ };
38
+ }
@@ -7,14 +7,13 @@ import {
7
7
  } from "@solana/spl-token";
8
8
  import {
9
9
  Connection,
10
- MessageV0,
11
10
  PublicKey,
12
11
  SystemProgram,
13
- TransactionInstruction,
14
- TransactionMessage,
15
- VersionedTransaction,
12
+ SYSVAR_RECENT_BLOCKHASHES_PUBKEY,
13
+ Transaction,
16
14
  } from "@solana/web3.js";
17
15
 
16
+ import { sendTransaction } from "./sendTransaction.js";
18
17
  import {
19
18
  getConnectedNetwork,
20
19
  getOrCreateConnection,
@@ -61,11 +60,11 @@ export async function transfer(
61
60
  options: TransferOptions,
62
61
  ): Promise<SignatureResult> {
63
62
  const connection = getOrCreateConnection({ networkOrConnection: options.network });
63
+ const connectedNetwork = await getConnectedNetwork(connection);
64
64
 
65
65
  const tx =
66
66
  options.token === "sol"
67
67
  ? await getNativeTransfer({
68
- connection,
69
68
  from: options.from,
70
69
  to: options.to,
71
70
  amount: options.amount,
@@ -75,41 +74,29 @@ export async function transfer(
75
74
  from: options.from,
76
75
  to: options.to,
77
76
  mintAddress:
78
- options.token === "usdc"
79
- ? getUsdcMintAddress(await getConnectedNetwork(connection))
80
- : options.token,
77
+ options.token === "usdc" ? getUsdcMintAddress(connectedNetwork) : options.token,
81
78
  amount: options.amount,
82
79
  });
83
80
 
84
- const serializedTx = Buffer.from(tx.serialize()).toString("base64");
81
+ const serializedTx = Buffer.from(tx.serialize({ requireAllSignatures: false })).toString(
82
+ "base64",
83
+ );
85
84
 
86
- const signedTxResponse = await apiClient.signSolanaTransaction(options.from, {
85
+ const signature = await sendTransaction(apiClient, {
86
+ network: connectedNetwork === "mainnet" ? "solana" : "solana-devnet",
87
87
  transaction: serializedTx,
88
88
  });
89
89
 
90
- const decodedSignedTx = Buffer.from(signedTxResponse.signedTransaction, "base64");
91
-
92
- const signature = await connection.sendRawTransaction(decodedSignedTx, {
93
- skipPreflight: false,
94
- maxRetries: 3,
95
- });
96
-
97
- return { signature };
90
+ return signature;
98
91
  }
99
92
 
100
- type GetNativeTransferOptions = Omit<TransferOptions, "token" | "network"> & {
101
- /**
102
- * The connection to the Solana network
103
- */
104
- connection: Connection;
105
- };
93
+ type GetNativeTransferOptions = Omit<TransferOptions, "token" | "network">;
106
94
 
107
95
  /**
108
- * Gets the instructions for a native SOL transfer
96
+ * Gets the transaction for a native SOL transfer
109
97
  *
110
98
  * @param options - The options for the native SOL transfer
111
99
  *
112
- * @param options.connection - The Solana connection
113
100
  * @param options.from - The source address
114
101
  * @param options.to - The destination address
115
102
  * @param options.amount - The amount to transfer
@@ -117,39 +104,37 @@ type GetNativeTransferOptions = Omit<TransferOptions, "token" | "network"> & {
117
104
  * @returns The native SOL transfer transaction
118
105
  */
119
106
  async function getNativeTransfer({
120
- connection,
121
107
  from,
122
108
  to,
123
109
  amount,
124
- }: GetNativeTransferOptions): Promise<VersionedTransaction> {
125
- const { blockhash } = await connection.getLatestBlockhash();
126
-
127
- const instructions = [
110
+ }: GetNativeTransferOptions): Promise<Transaction> {
111
+ const transaction = new Transaction();
112
+ transaction.add(
128
113
  SystemProgram.transfer({
129
114
  fromPubkey: new PublicKey(from),
130
115
  toPubkey: new PublicKey(to),
131
116
  lamports: amount,
132
117
  }),
133
- ];
134
-
135
- const messageV0 = new TransactionMessage({
136
- payerKey: new PublicKey(from),
137
- recentBlockhash: blockhash,
138
- instructions,
139
- }).compileToV0Message();
118
+ );
119
+ transaction.recentBlockhash = SYSVAR_RECENT_BLOCKHASHES_PUBKEY.toBase58();
120
+ transaction.feePayer = new PublicKey(from);
140
121
 
141
- return new VersionedTransaction(messageV0);
122
+ return transaction;
142
123
  }
143
124
 
144
- type GetSplTransferOptions = GetNativeTransferOptions & {
125
+ type GetSplTransferOptions = Omit<TransferOptions, "token" | "network"> & {
145
126
  /**
146
127
  * The mint address of the token
147
128
  */
148
129
  mintAddress: string;
130
+ /**
131
+ * The connection to the Solana network.
132
+ */
133
+ connection: Connection;
149
134
  };
150
135
 
151
136
  /**
152
- * Gets the instructions for a SPL token transfer
137
+ * Gets the transaction for a SPL token transfer
153
138
  *
154
139
  * @param options - The options for the SPL token transfer
155
140
  *
@@ -167,7 +152,7 @@ async function getSplTransfer({
167
152
  to,
168
153
  mintAddress,
169
154
  amount,
170
- }: GetSplTransferOptions): Promise<VersionedTransaction> {
155
+ }: GetSplTransferOptions): Promise<Transaction> {
171
156
  const fromPubkey = new PublicKey(from);
172
157
  const toPubkey = new PublicKey(to);
173
158
  const mintPubkey = new PublicKey(mintAddress);
@@ -182,7 +167,7 @@ async function getSplTransfer({
182
167
  const sourceAta = await getAssociatedTokenAddress(mintPubkey, fromPubkey);
183
168
  const destinationAta = await getAssociatedTokenAddress(mintPubkey, toPubkey);
184
169
 
185
- const instructions: TransactionInstruction[] = [];
170
+ const transaction = new Transaction();
186
171
 
187
172
  const sourceAccount = await getAccount(connection, sourceAta);
188
173
  if (sourceAccount.amount < amount) {
@@ -193,12 +178,12 @@ async function getSplTransfer({
193
178
  try {
194
179
  await getAccount(connection, destinationAta);
195
180
  } catch {
196
- instructions.push(
181
+ transaction.add(
197
182
  createAssociatedTokenAccountInstruction(fromPubkey, destinationAta, toPubkey, mintPubkey),
198
183
  );
199
184
  }
200
185
 
201
- instructions.push(
186
+ transaction.add(
202
187
  createTransferCheckedInstruction(
203
188
  sourceAta,
204
189
  mintPubkey,
@@ -208,12 +193,8 @@ async function getSplTransfer({
208
193
  mintInfo.decimals,
209
194
  ),
210
195
  );
196
+ transaction.recentBlockhash = SYSVAR_RECENT_BLOCKHASHES_PUBKEY.toBase58();
197
+ transaction.feePayer = new PublicKey(from);
211
198
 
212
- return new VersionedTransaction(
213
- MessageV0.compile({
214
- payerKey: fromPubkey,
215
- instructions: instructions,
216
- recentBlockhash: (await connection.getLatestBlockhash()).blockhash,
217
- }),
218
- );
199
+ return transaction;
219
200
  }
@@ -2,13 +2,12 @@ import { Connection } from "@solana/web3.js";
2
2
 
3
3
  import {
4
4
  GENESIS_HASH_MAINNET,
5
- GENESIS_HASH_TESTNET,
6
5
  GENESIS_HASH_DEVNET,
7
6
  USDC_MAINNET_MINT_ADDRESS,
8
7
  USDC_DEVNET_MINT_ADDRESS,
9
8
  } from "./constants.js";
10
9
 
11
- export type Network = "mainnet" | "devnet" | "testnet";
10
+ export type Network = "mainnet" | "devnet";
12
11
 
13
12
  type GetOrCreateConnectionOptions = {
14
13
  networkOrConnection: Network | Connection;
@@ -33,9 +32,7 @@ export function getOrCreateConnection({
33
32
  return new Connection(
34
33
  networkOrConnection === "mainnet"
35
34
  ? "https://api.mainnet-beta.solana.com"
36
- : networkOrConnection === "devnet"
37
- ? "https://api.devnet.solana.com"
38
- : "https://api.testnet.solana.com",
35
+ : "https://api.devnet.solana.com",
39
36
  );
40
37
  }
41
38
 
@@ -43,7 +40,7 @@ export function getOrCreateConnection({
43
40
  * Get the network of the connected Solana node
44
41
  *
45
42
  * @param connection - The connection to the Solana network
46
- * @throws {Error} If the network is not mainnet, devnet, or testnet
43
+ * @throws {Error} If the network is not mainnet or devnet
47
44
  *
48
45
  * @returns The network of the connected Solana node
49
46
  */
@@ -54,11 +51,9 @@ export async function getConnectedNetwork(connection: Connection): Promise<Netwo
54
51
  return "mainnet";
55
52
  } else if (genesisHash === GENESIS_HASH_DEVNET) {
56
53
  return "devnet";
57
- } else if (genesisHash === GENESIS_HASH_TESTNET) {
58
- return "testnet";
59
54
  }
60
55
 
61
- throw new Error("Unknown network");
56
+ throw new Error("Unknown or unsupported network");
62
57
  }
63
58
 
64
59
  /**
@@ -71,9 +66,6 @@ export async function getConnectedNetwork(connection: Connection): Promise<Netwo
71
66
  export function getUsdcMintAddress(network: Network): string {
72
67
  if (network === "mainnet") {
73
68
  return USDC_MAINNET_MINT_ADDRESS;
74
- } else if (network === "devnet") {
75
- return USDC_DEVNET_MINT_ADDRESS;
76
- } else {
77
- throw new Error("Testnet is not supported for USDC");
78
69
  }
70
+ return USDC_DEVNET_MINT_ADDRESS;
79
71
  }
package/analytics.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import md5 from "md5";
2
2
 
3
- import { APIError, HttpErrorType } from "./openapi-client/errors.js";
3
+ import { UserInputValidationError } from "./errors.js";
4
+ import { APIError, NetworkError } from "./openapi-client/errors.js";
4
5
  import { version } from "./version.js";
5
6
 
6
7
  /**
@@ -25,7 +26,29 @@ type ErrorEventData = {
25
26
  name: "error";
26
27
  };
27
28
 
28
- type EventData = ErrorEventData;
29
+ /**
30
+ * The data in an action event
31
+ */
32
+ type ActionEventData = {
33
+ /**
34
+ * The operation being performed, e.g. "transfer", "swap", "fund", "requestFaucet"
35
+ */
36
+ action: string;
37
+ /**
38
+ * The account type, e.g. "evm-server", "evm-smart", "solana"
39
+ */
40
+ accountType?: "evm_server" | "evm_smart" | "solana";
41
+ /**
42
+ * Additional properties specific to the action
43
+ */
44
+ properties?: Record<string, unknown>;
45
+ /**
46
+ * The name of the event
47
+ */
48
+ name: "action";
49
+ };
50
+
51
+ type EventData = ErrorEventData | ActionEventData;
29
52
 
30
53
  // This is a public client id for the analytics service
31
54
  const publicClientId = "54f2ee2fb3d2b901a829940d70fbfc13";
@@ -35,6 +58,7 @@ export const Analytics = {
35
58
  wrapClassWithErrorTracking,
36
59
  wrapObjectMethodsWithErrorTracking,
37
60
  sendEvent,
61
+ trackAction,
38
62
  };
39
63
 
40
64
  /**
@@ -44,7 +68,11 @@ export const Analytics = {
44
68
  * @returns Promise that resolves when the event is sent
45
69
  */
46
70
  async function sendEvent(event: EventData): Promise<void> {
47
- if (process.env.DISABLE_CDP_ERROR_REPORTING === "true") {
71
+ if (event.name === "error" && process.env.DISABLE_CDP_ERROR_REPORTING === "true") {
72
+ return;
73
+ }
74
+
75
+ if (event.name !== "error" && process.env.DISABLE_CDP_USAGE_TRACKING === "true") {
48
76
  return;
49
77
  }
50
78
 
@@ -89,6 +117,39 @@ async function sendEvent(event: EventData): Promise<void> {
89
117
  });
90
118
  }
91
119
 
120
+ /**
121
+ * Track an action being performed
122
+ *
123
+ * @param params - The parameters for tracking an action
124
+ * @param params.action - The action being performed
125
+ * @param params.accountType - The type of account
126
+ * @param params.properties - Additional properties
127
+ */
128
+ function trackAction(params: {
129
+ action: string;
130
+ accountType?: "evm_server" | "evm_smart" | "solana";
131
+ properties?: Record<string, unknown>;
132
+ }): void {
133
+ if (
134
+ params.properties?.network &&
135
+ typeof params.properties.network === "string" &&
136
+ params.properties.network.startsWith("http")
137
+ ) {
138
+ const url = new URL(params.properties.network);
139
+ params.properties.customRpcHost = url.hostname;
140
+ params.properties.network = "custom";
141
+ }
142
+
143
+ sendEvent({
144
+ action: params.action,
145
+ accountType: params.accountType,
146
+ properties: params.properties,
147
+ name: "action",
148
+ }).catch(() => {
149
+ // ignore error
150
+ });
151
+ }
152
+
92
153
  /**
93
154
  * Wraps all methods of a class with error tracking.
94
155
  *
@@ -184,7 +245,15 @@ function shouldTrackError(error: unknown): boolean {
184
245
  return false;
185
246
  }
186
247
 
187
- if (error instanceof APIError && error.errorType !== HttpErrorType.unexpected_error) {
248
+ if (error instanceof UserInputValidationError) {
249
+ return false;
250
+ }
251
+
252
+ if (error instanceof NetworkError) {
253
+ return true;
254
+ }
255
+
256
+ if (error instanceof APIError && error.errorType !== "unexpected_error") {
188
257
  return false;
189
258
  }
190
259
 
package/auth/utils/jwt.ts CHANGED
@@ -2,6 +2,7 @@ import { SignJWT, importPKCS8, importJWK, JWTPayload } from "jose";
2
2
  import { getRandomValues } from "uncrypto";
3
3
 
4
4
  import { authHash } from "./hash.js";
5
+ import { UserInputValidationError } from "../../errors.js";
5
6
  import { sortKeys } from "../../utils/sortKeys.js";
6
7
  import { InvalidWalletSecretFormatError, UndefinedWalletSecretError } from "../errors.js";
7
8
 
@@ -164,7 +165,9 @@ export async function generateJwt(options: JwtOptions): Promise<string> {
164
165
  randomNonce,
165
166
  );
166
167
  } else {
167
- throw new Error("Invalid key format - must be either PEM EC key or base64 Ed25519 key");
168
+ throw new UserInputValidationError(
169
+ "Invalid key format - must be either PEM EC key or base64 Ed25519 key",
170
+ );
168
171
  }
169
172
  }
170
173
 
@@ -306,7 +309,7 @@ async function buildEdwardsJWT(
306
309
  // Decode the base64 key (expecting 64 bytes: 32 for seed + 32 for public key)
307
310
  const decoded = Buffer.from(privateKey, "base64");
308
311
  if (decoded.length !== 64) {
309
- throw new Error("Invalid Ed25519 key length");
312
+ throw new UserInputValidationError("Invalid Ed25519 key length");
310
313
  }
311
314
 
312
315
  const seed = decoded.subarray(0, 32);
package/client/cdp.ts CHANGED
@@ -121,8 +121,14 @@ For more information, see: https://github.com/coinbase/cdp-sdk/blob/main/typescr
121
121
  sourceVersion: version,
122
122
  });
123
123
 
124
- if (process.env.DISABLE_CDP_ERROR_REPORTING !== "true") {
124
+ if (
125
+ process.env.DISABLE_CDP_ERROR_REPORTING !== "true" ||
126
+ process.env.DISABLE_CDP_USAGE_TRACKING !== "true"
127
+ ) {
125
128
  Analytics.identifier = apiKeyId;
129
+ }
130
+
131
+ if (process.env.DISABLE_CDP_ERROR_REPORTING !== "true") {
126
132
  Analytics.wrapClassWithErrorTracking(CdpClient);
127
133
  Analytics.wrapClassWithErrorTracking(EvmClient);
128
134
  Analytics.wrapClassWithErrorTracking(SolanaClient);