@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/errors.ts CHANGED
@@ -15,3 +15,21 @@ export class TimeoutError extends Error {
15
15
  }
16
16
  }
17
17
  }
18
+
19
+ /**
20
+ * UserInputValidationError is thrown when validation of a user-supplied input fails.
21
+ */
22
+ export class UserInputValidationError extends Error {
23
+ /**
24
+ * Initializes a new UserInputValidationError instance.
25
+ *
26
+ * @param message - The user input validation error message.
27
+ */
28
+ constructor(message: string) {
29
+ super(message);
30
+ this.name = "UserInputValidationError";
31
+ if (Error.captureStackTrace) {
32
+ Error.captureStackTrace(this, UserInputValidationError);
33
+ }
34
+ }
35
+ }
package/index.ts CHANGED
@@ -7,5 +7,6 @@ export {
7
7
  type CreatePolicyBody,
8
8
  type UpdatePolicyBody,
9
9
  } from "./policies/schema.js";
10
+ export { NetworkError } from "./openapi-client/errors.js";
10
11
 
11
12
  export { parseEther } from "viem";
@@ -3,13 +3,7 @@ import Axios, { AxiosInstance, AxiosRequestConfig } from "axios";
3
3
 
4
4
  import { withAuth } from "../auth/hooks/axios/index.js";
5
5
  import { ERROR_DOCS_PAGE_URL } from "../constants.js";
6
- import {
7
- isOpenAPIError,
8
- APIError,
9
- HttpErrorType,
10
- UnknownApiError,
11
- UnknownError,
12
- } from "./errors.js";
6
+ import { isOpenAPIError, APIError, UnknownError, NetworkError } from "./errors.js";
13
7
 
14
8
  import type { Prettify } from "../types/utils.js";
15
9
 
@@ -135,11 +129,52 @@ export const cdpApiClient = async <T>(
135
129
  } catch (error) {
136
130
  // eslint-disable-next-line import/no-named-as-default-member
137
131
  if (Axios.isAxiosError(error) && !error.response) {
138
- throw new UnknownApiError(
139
- HttpErrorType.unknown,
140
- error.cause instanceof Error ? error.cause.message : error.message,
141
- error.cause,
142
- );
132
+ // Network-level errors (no response received)
133
+ const errorMessage = (error.message || "").toLowerCase();
134
+ const errorCode = error.code?.toLowerCase();
135
+
136
+ // Categorize network errors based on error messages and codes
137
+ if (errorCode === "econnrefused" || errorMessage.includes("connection refused")) {
138
+ throw new NetworkError(
139
+ "network_connection_failed",
140
+ "Unable to connect to CDP service. The service may be unavailable.",
141
+ { code: error.code, message: error.message, retryable: true },
142
+ error.cause,
143
+ );
144
+ } else if (
145
+ errorCode === "etimedout" ||
146
+ errorCode === "econnaborted" ||
147
+ errorMessage.includes("timeout")
148
+ ) {
149
+ throw new NetworkError(
150
+ "network_timeout",
151
+ "Request timed out. Please try again.",
152
+ { code: error.code, message: error.message, retryable: true },
153
+ error.cause,
154
+ );
155
+ } else if (errorCode === "enotfound" || errorMessage.includes("getaddrinfo")) {
156
+ throw new NetworkError(
157
+ "network_dns_failure",
158
+ "DNS resolution failed. Please check your network connection.",
159
+ { code: error.code, message: error.message, retryable: false },
160
+ error.cause,
161
+ );
162
+ } else if (errorMessage.includes("network error") || errorMessage.includes("econnreset")) {
163
+ throw new NetworkError(
164
+ "network_connection_failed",
165
+ "Network error occurred. Please check your connection and try again.",
166
+ { code: error.code, message: error.message, retryable: true },
167
+ error.cause,
168
+ );
169
+ } else {
170
+ // Generic network error
171
+ throw new NetworkError(
172
+ "unknown",
173
+ error.cause instanceof Error ? error.cause.message : error.message,
174
+ { code: error.code, message: error.message, retryable: true },
175
+ error.cause,
176
+ );
177
+ }
143
178
  }
144
179
 
145
180
  // eslint-disable-next-line import/no-named-as-default-member
@@ -155,20 +190,55 @@ export const cdpApiClient = async <T>(
155
190
  );
156
191
  } else {
157
192
  const statusCode = error.response.status;
193
+ const responseData = error.response.data;
194
+
195
+ // Check for gateway-level errors that might indicate network issues
196
+ const isGatewayError =
197
+ responseData &&
198
+ typeof responseData === "string" &&
199
+ (responseData.toLowerCase().includes("forbidden") ||
200
+ responseData.toLowerCase().includes("ip") ||
201
+ responseData.toLowerCase().includes("blocked") ||
202
+ responseData.toLowerCase().includes("gateway"));
203
+
158
204
  switch (statusCode) {
159
205
  case 401:
160
206
  throw new APIError(
161
207
  statusCode,
162
- HttpErrorType.unauthorized,
208
+ "unauthorized",
163
209
  "Unauthorized.",
164
210
  undefined,
165
211
  `${ERROR_DOCS_PAGE_URL}#unauthorized`,
166
212
  error.cause,
167
213
  );
214
+ case 403:
215
+ // Special handling for IP blocklist and other gateway-level 403s
216
+ if (isGatewayError) {
217
+ throw new NetworkError(
218
+ "network_ip_blocked",
219
+ "Access denied. Your IP address may be blocked or restricted.",
220
+ {
221
+ code: "IP_BLOCKED",
222
+ message:
223
+ typeof responseData === "string" ? responseData : JSON.stringify(responseData),
224
+ retryable: false,
225
+ },
226
+ error.cause,
227
+ );
228
+ }
229
+ // Regular 403 forbidden error
230
+ throw new APIError(
231
+ statusCode,
232
+ "unauthorized",
233
+ "Forbidden. You don't have permission to access this resource.",
234
+ undefined,
235
+ `${ERROR_DOCS_PAGE_URL}#forbidden`,
236
+ error.cause,
237
+ );
168
238
  case 404:
169
239
  throw new APIError(
170
240
  statusCode,
171
- HttpErrorType.not_found,
241
+ "not_found",
172
242
  "API not found.",
173
243
  undefined,
174
244
  `${ERROR_DOCS_PAGE_URL}#not_found`,
@@ -177,7 +247,7 @@ export const cdpApiClient = async <T>(
177
247
  case 502:
178
248
  throw new APIError(
179
249
  statusCode,
180
- HttpErrorType.bad_gateway,
250
+ "bad_gateway",
181
251
  "Bad gateway.",
182
252
  undefined,
183
253
  `${ERROR_DOCS_PAGE_URL}`,
@@ -186,7 +256,7 @@ export const cdpApiClient = async <T>(
186
256
  case 503:
187
257
  throw new APIError(
188
258
  statusCode,
189
- HttpErrorType.service_unavailable,
259
+ "service_unavailable",
190
260
  "Service unavailable. Please try again later.",
191
261
  undefined,
192
262
  `${ERROR_DOCS_PAGE_URL}`,
@@ -209,7 +279,7 @@ export const cdpApiClient = async <T>(
209
279
 
210
280
  throw new APIError(
211
281
  statusCode,
212
- HttpErrorType.unexpected_error,
282
+ "unexpected_error",
213
283
  errorMessage,
214
284
  undefined,
215
285
  `${ERROR_DOCS_PAGE_URL}`,
@@ -1,18 +1,20 @@
1
+ import { ERROR_DOCS_PAGE_URL } from "../constants.js";
1
2
  import {
2
3
  Error as OpenAPIError,
3
4
  ErrorType as OpenAPIErrorType,
4
5
  } from "./generated/coinbaseDeveloperPlatformAPIs.schemas.js";
5
6
 
6
- export const HttpErrorType = {
7
- unexpected_error: "unexpected_error",
8
- unauthorized: "unauthorized",
9
- not_found: "not_found",
10
- bad_gateway: "bad_gateway",
11
- service_unavailable: "service_unavailable",
12
- unknown: "unknown",
13
- } as const;
14
-
15
- export type HttpErrorType = (typeof HttpErrorType)[keyof typeof HttpErrorType];
7
+ export type HttpErrorType =
8
+ | "unexpected_error"
9
+ | "unauthorized"
10
+ | "not_found"
11
+ | "bad_gateway"
12
+ | "service_unavailable"
13
+ | "unknown"
14
+ | "network_timeout"
15
+ | "network_connection_failed"
16
+ | "network_ip_blocked"
17
+ | "network_dns_failure";
16
18
 
17
19
  /**
18
20
  * Extended error codes that include both OpenAPI errors and network errors
@@ -114,6 +116,59 @@ export class UnknownError extends Error {
114
116
  }
115
117
  }
116
118
 
119
+ /**
120
+ * Error thrown when a network-level failure occurs before reaching the CDP service
121
+ * This includes gateway errors, IP blocklist rejections, DNS failures, etc.
122
+ */
123
+ export class NetworkError extends APIError {
124
+ networkDetails?: {
125
+ code?: string;
126
+ message?: string;
127
+ retryable?: boolean;
128
+ };
129
+
130
+ /**
131
+ * Constructor for the NetworkError class
132
+ *
133
+ * @param errorType - The type of network error
134
+ * @param errorMessage - The error message
135
+ * @param networkDetails - Additional network error details
136
+ * @param networkDetails.code - The error code
137
+ * @param networkDetails.message - The error message
138
+ * @param networkDetails.retryable - Whether the error is retryable
139
+ * @param cause - The cause of the error
140
+ */
141
+ constructor(
142
+ errorType: HttpErrorType,
143
+ errorMessage: string,
144
+ networkDetails?: { code?: string; message?: string; retryable?: boolean },
145
+ cause?: Error,
146
+ ) {
147
+ super(
148
+ 0, // Status code 0 indicates no response was received
149
+ errorType,
150
+ errorMessage,
151
+ undefined,
152
+ `${ERROR_DOCS_PAGE_URL}#network-errors`,
153
+ cause,
154
+ );
155
+ this.name = "NetworkError";
156
+ this.networkDetails = networkDetails;
157
+ }
158
+
159
+ /**
160
+ * Convert the error to a JSON object, including network details
161
+ *
162
+ * @returns The error as a JSON object
163
+ */
164
+ toJSON() {
165
+ return {
166
+ ...super.toJSON(),
167
+ ...(this.networkDetails && { networkDetails: this.networkDetails }),
168
+ };
169
+ }
170
+ }
171
+
117
172
  /**
118
173
  * Type guard to check if an object is an OpenAPIError
119
174
  *
@@ -2252,6 +2252,30 @@ export type SignSolanaMessage200 = {
2252
2252
  signature: string;
2253
2253
  };
2254
2254
 
2255
+ /**
2256
+ * The Solana network to send the transaction to.
2257
+ */
2258
+ export type SendSolanaTransactionBodyNetwork =
2259
+ (typeof SendSolanaTransactionBodyNetwork)[keyof typeof SendSolanaTransactionBodyNetwork];
2260
+
2261
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
2262
+ export const SendSolanaTransactionBodyNetwork = {
2263
+ solana: "solana",
2264
+ "solana-devnet": "solana-devnet",
2265
+ } as const;
2266
+
2267
+ export type SendSolanaTransactionBody = {
2268
+ /** The Solana network to send the transaction to. */
2269
+ network: SendSolanaTransactionBodyNetwork;
2270
+ /** The base64 encoded transaction to sign and send. This transaction can contain multiple instructions for native Solana batching. */
2271
+ transaction: string;
2272
+ };
2273
+
2274
+ export type SendSolanaTransaction200 = {
2275
+ /** The base58 encoded transaction signature. */
2276
+ transactionSignature: string;
2277
+ };
2278
+
2255
2279
  /**
2256
2280
  * The token to request funds for.
2257
2281
  */
@@ -13,6 +13,7 @@ import type {
13
13
  ExportSolanaAccount200,
14
14
  ExportSolanaAccountByName200,
15
15
  ListSolanaAccounts200,
16
+ SendSolanaTransaction200,
16
17
  SignSolanaMessage200,
17
18
  SignSolanaTransaction200,
18
19
  SolanaAccount,
@@ -203,6 +204,13 @@ export const getSignSolanaMessageResponseMock = (
203
204
  overrideResponse: Partial<SignSolanaMessage200> = {},
204
205
  ): SignSolanaMessage200 => ({ signature: faker.string.alpha(20), ...overrideResponse });
205
206
 
207
+ export const getSendSolanaTransactionResponseMock = (
208
+ overrideResponse: Partial<SendSolanaTransaction200> = {},
209
+ ): SendSolanaTransaction200 => ({
210
+ transactionSignature: faker.string.alpha(20),
211
+ ...overrideResponse,
212
+ });
213
+
206
214
  export const getListSolanaAccountsMockHandler = (
207
215
  overrideResponse?:
208
216
  | ListSolanaAccounts200
@@ -432,6 +440,29 @@ export const getSignSolanaMessageMockHandler = (
432
440
  );
433
441
  });
434
442
  };
443
+
444
+ export const getSendSolanaTransactionMockHandler = (
445
+ overrideResponse?:
446
+ | SendSolanaTransaction200
447
+ | ((
448
+ info: Parameters<Parameters<typeof http.post>[1]>[0],
449
+ ) => Promise<SendSolanaTransaction200> | SendSolanaTransaction200),
450
+ ) => {
451
+ return http.post("*/v2/solana/accounts/send/transaction", async info => {
452
+ await delay(0);
453
+
454
+ return new HttpResponse(
455
+ JSON.stringify(
456
+ overrideResponse !== undefined
457
+ ? typeof overrideResponse === "function"
458
+ ? await overrideResponse(info)
459
+ : overrideResponse
460
+ : getSendSolanaTransactionResponseMock(),
461
+ ),
462
+ { status: 200, headers: { "Content-Type": "application/json" } },
463
+ );
464
+ });
465
+ };
435
466
  export const getSolanaAccountsMock = () => [
436
467
  getListSolanaAccountsMockHandler(),
437
468
  getCreateSolanaAccountMockHandler(),
@@ -443,4 +474,5 @@ export const getSolanaAccountsMock = () => [
443
474
  getExportSolanaAccountByNameMockHandler(),
444
475
  getSignSolanaTransactionMockHandler(),
445
476
  getSignSolanaMessageMockHandler(),
477
+ getSendSolanaTransactionMockHandler(),
446
478
  ];
@@ -14,6 +14,8 @@ import type {
14
14
  ImportSolanaAccountBody,
15
15
  ListSolanaAccounts200,
16
16
  ListSolanaAccountsParams,
17
+ SendSolanaTransaction200,
18
+ SendSolanaTransactionBody,
17
19
  SignSolanaMessage200,
18
20
  SignSolanaMessageBody,
19
21
  SignSolanaTransaction200,
@@ -210,6 +212,44 @@ export const signSolanaMessage = (
210
212
  options,
211
213
  );
212
214
  };
215
+ /**
216
+ * Signs and sends a single Solana transaction using multiple Solana accounts. The transaction may contain contain several instructions, each of which may require signatures from different account keys.
217
+
218
+ The transaction should be serialized into a byte array and base64 encoded. The API handles recent blockhash management and fee estimation, leaving the developer to provide only the minimal set of fields necessary to send the transaction.
219
+
220
+ **Transaction types**
221
+
222
+ The following transaction types are supported:
223
+ * [Legacy transactions](https://solana.com/developers/guides/advanced/versions#current-transaction-versions)
224
+ * [Versioned transactions](https://solana.com/developers/guides/advanced/versions)
225
+
226
+ **Instruction Batching**
227
+
228
+ To batch multiple operations, include multiple instructions within a single transaction. All instructions within a transaction are executed atomically - if any instruction fails, the entire transaction fails and is rolled back.
229
+
230
+ **Network Support**
231
+
232
+ The following Solana networks are supported:
233
+ * `solana` - Solana Mainnet
234
+ * `solana-devnet` - Solana Devnet
235
+
236
+ The developer is responsible for ensuring that the unsigned transaction is valid, as the API will not validate the transaction.
237
+ * @summary Send a Solana transaction
238
+ */
239
+ export const sendSolanaTransaction = (
240
+ sendSolanaTransactionBody: SendSolanaTransactionBody,
241
+ options?: SecondParameter<typeof cdpApiClient>,
242
+ ) => {
243
+ return cdpApiClient<SendSolanaTransaction200>(
244
+ {
245
+ url: `/v2/solana/accounts/send/transaction`,
246
+ method: "POST",
247
+ headers: { "Content-Type": "application/json" },
248
+ data: sendSolanaTransactionBody,
249
+ },
250
+ options,
251
+ );
252
+ };
213
253
  export type ListSolanaAccountsResult = NonNullable<Awaited<ReturnType<typeof listSolanaAccounts>>>;
214
254
  export type CreateSolanaAccountResult = NonNullable<
215
255
  Awaited<ReturnType<typeof createSolanaAccount>>
@@ -234,3 +274,6 @@ export type SignSolanaTransactionResult = NonNullable<
234
274
  Awaited<ReturnType<typeof signSolanaTransaction>>
235
275
  >;
236
276
  export type SignSolanaMessageResult = NonNullable<Awaited<ReturnType<typeof signSolanaMessage>>>;
277
+ export type SendSolanaTransactionResult = NonNullable<
278
+ Awaited<ReturnType<typeof sendSolanaTransaction>>
279
+ >;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cdp-sdk",
3
- "version": "1.26.0",
3
+ "version": "1.28.0",
4
4
  "description": "SDK for interacting with the Coinbase Developer Platform Wallet API",
5
5
  "main": "./_cjs/index.js",
6
6
  "module": "./_esm/index.js",
@@ -66,9 +66,9 @@ export const EvmAddressCriterionSchema = z.object({
66
66
  /**
67
67
  * Array of EVM addresses to compare against.
68
68
  * Each address must be a 0x-prefixed 40-character hexadecimal string.
69
- * Limited to a maximum of 100 addresses per criterion.
69
+ * Limited to a maximum of 300 addresses per criterion.
70
70
  */
71
- addresses: z.array(Address).max(100),
71
+ addresses: z.array(Address).max(300),
72
72
  /**
73
73
  * The operator to use for evaluating transaction addresses.
74
74
  * "in" checks if an address is in the provided list.
@@ -128,9 +128,9 @@ export const EvmTypedAddressConditionSchema = z.object({
128
128
  /**
129
129
  * Array of EVM addresses to compare against.
130
130
  * Each address must be a 0x-prefixed 40-character hexadecimal string.
131
- * Limited to a maximum of 100 addresses per condition.
131
+ * Limited to a maximum of 300 addresses per condition.
132
132
  */
133
- addresses: z.array(Address).max(100),
133
+ addresses: z.array(Address).max(300),
134
134
  /**
135
135
  * The operator to use for evaluating addresses.
136
136
  * "in" checks if an address is in the provided list.
@@ -235,9 +235,9 @@ export const SignEvmTypedDataVerifyingContractCriterionSchema = z.object({
235
235
  /**
236
236
  * Array of EVM addresses allowed or disallowed as verifying contracts.
237
237
  * Each address must be a 0x-prefixed 40-character hexadecimal string.
238
- * Limited to a maximum of 100 addresses per criterion.
238
+ * Limited to a maximum of 300 addresses per criterion.
239
239
  */
240
- addresses: z.array(Address).max(100),
240
+ addresses: z.array(Address).max(300),
241
241
  /**
242
242
  * The operator to use for evaluating verifying contract addresses.
243
243
  * "in" checks if the verifying contract is in the provided list.
package/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "1.26.0";
1
+ export const version = "1.28.0";