@coinbase/cdp-sdk 1.2.0 → 1.3.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 (115) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +88 -1
  3. package/_cjs/analytics.js +25 -6
  4. package/_cjs/analytics.js.map +1 -1
  5. package/_cjs/auth/hooks/axios/withAuth.js +1 -0
  6. package/_cjs/auth/hooks/axios/withAuth.js.map +1 -1
  7. package/_cjs/client/cdp.js +2 -0
  8. package/_cjs/client/cdp.js.map +1 -1
  9. package/_cjs/client/evm/evm.js +119 -0
  10. package/_cjs/client/evm/evm.js.map +1 -1
  11. package/_cjs/openapi-client/cdpApiClient.js +16 -50
  12. package/_cjs/openapi-client/cdpApiClient.js.map +1 -1
  13. package/_cjs/openapi-client/errors.js +38 -3
  14. package/_cjs/openapi-client/errors.js.map +1 -1
  15. package/_cjs/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js +12 -1
  16. package/_cjs/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
  17. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.js +39 -4
  18. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.js.map +1 -1
  19. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.msw.js +15 -1
  20. package/_cjs/openapi-client/generated/evm-accounts/evm-accounts.msw.js.map +1 -1
  21. package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js +1 -0
  22. package/_cjs/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js.map +1 -1
  23. package/_cjs/openapi-client/generated/evm-token-balances/evm-token-balances.js +15 -0
  24. package/_cjs/openapi-client/generated/evm-token-balances/evm-token-balances.js.map +1 -0
  25. package/_cjs/openapi-client/generated/evm-token-balances/evm-token-balances.msw.js +45 -0
  26. package/_cjs/openapi-client/generated/evm-token-balances/evm-token-balances.msw.js.map +1 -0
  27. package/_cjs/openapi-client/generated/faucets/faucets.js +2 -1
  28. package/_cjs/openapi-client/generated/faucets/faucets.js.map +1 -1
  29. package/_cjs/openapi-client/generated/index.msw.js +2 -1
  30. package/_cjs/openapi-client/generated/index.msw.js.map +1 -1
  31. package/_cjs/openapi-client/index.js +4 -0
  32. package/_cjs/openapi-client/index.js.map +1 -1
  33. package/_cjs/version.js +1 -1
  34. package/_esm/analytics.js +23 -6
  35. package/_esm/analytics.js.map +1 -1
  36. package/_esm/auth/hooks/axios/withAuth.js +1 -0
  37. package/_esm/auth/hooks/axios/withAuth.js.map +1 -1
  38. package/_esm/client/cdp.js +2 -0
  39. package/_esm/client/cdp.js.map +1 -1
  40. package/_esm/client/evm/evm.js +119 -0
  41. package/_esm/client/evm/evm.js.map +1 -1
  42. package/_esm/openapi-client/cdpApiClient.js +13 -17
  43. package/_esm/openapi-client/cdpApiClient.js.map +1 -1
  44. package/_esm/openapi-client/errors.js +35 -2
  45. package/_esm/openapi-client/errors.js.map +1 -1
  46. package/_esm/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js +11 -0
  47. package/_esm/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.js.map +1 -1
  48. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.js +37 -3
  49. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.js.map +1 -1
  50. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.msw.js +12 -0
  51. package/_esm/openapi-client/generated/evm-accounts/evm-accounts.msw.js.map +1 -1
  52. package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js +1 -0
  53. package/_esm/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.js.map +1 -1
  54. package/_esm/openapi-client/generated/evm-token-balances/evm-token-balances.js +11 -0
  55. package/_esm/openapi-client/generated/evm-token-balances/evm-token-balances.js.map +1 -0
  56. package/_esm/openapi-client/generated/evm-token-balances/evm-token-balances.msw.js +39 -0
  57. package/_esm/openapi-client/generated/evm-token-balances/evm-token-balances.msw.js.map +1 -0
  58. package/_esm/openapi-client/generated/faucets/faucets.js +2 -1
  59. package/_esm/openapi-client/generated/faucets/faucets.js.map +1 -1
  60. package/_esm/openapi-client/generated/index.msw.js +2 -1
  61. package/_esm/openapi-client/generated/index.msw.js.map +1 -1
  62. package/_esm/openapi-client/index.js +4 -0
  63. package/_esm/openapi-client/index.js.map +1 -1
  64. package/_esm/version.js +1 -1
  65. package/_types/analytics.d.ts +15 -0
  66. package/_types/analytics.d.ts.map +1 -1
  67. package/_types/auth/hooks/axios/withAuth.d.ts.map +1 -1
  68. package/_types/client/cdp.d.ts.map +1 -1
  69. package/_types/client/evm/evm.d.ts +83 -1
  70. package/_types/client/evm/evm.d.ts.map +1 -1
  71. package/_types/client/evm/evm.types.d.ts +100 -4
  72. package/_types/client/evm/evm.types.d.ts.map +1 -1
  73. package/_types/openapi-client/cdpApiClient.d.ts.map +1 -1
  74. package/_types/openapi-client/errors.d.ts +28 -1
  75. package/_types/openapi-client/errors.d.ts.map +1 -1
  76. package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts +87 -2
  77. package/_types/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.d.ts.map +1 -1
  78. package/_types/openapi-client/generated/evm-accounts/evm-accounts.d.ts +32 -4
  79. package/_types/openapi-client/generated/evm-accounts/evm-accounts.d.ts.map +1 -1
  80. package/_types/openapi-client/generated/evm-accounts/evm-accounts.msw.d.ts +3 -1
  81. package/_types/openapi-client/generated/evm-accounts/evm-accounts.msw.d.ts.map +1 -1
  82. package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.d.ts +1 -0
  83. package/_types/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.d.ts.map +1 -1
  84. package/_types/openapi-client/generated/evm-token-balances/evm-token-balances.d.ts +20 -0
  85. package/_types/openapi-client/generated/evm-token-balances/evm-token-balances.d.ts.map +1 -0
  86. package/_types/openapi-client/generated/evm-token-balances/evm-token-balances.msw.d.ts +6 -0
  87. package/_types/openapi-client/generated/evm-token-balances/evm-token-balances.msw.d.ts.map +1 -0
  88. package/_types/openapi-client/generated/faucets/faucets.d.ts +2 -1
  89. package/_types/openapi-client/generated/faucets/faucets.d.ts.map +1 -1
  90. package/_types/openapi-client/generated/index.msw.d.ts +2 -1
  91. package/_types/openapi-client/generated/index.msw.d.ts.map +1 -1
  92. package/_types/openapi-client/index.d.ts +5 -0
  93. package/_types/openapi-client/index.d.ts.map +1 -1
  94. package/_types/types/misc.d.ts +37 -0
  95. package/_types/types/misc.d.ts.map +1 -1
  96. package/_types/version.d.ts +1 -1
  97. package/analytics.ts +26 -7
  98. package/auth/hooks/axios/withAuth.ts +1 -0
  99. package/client/cdp.ts +3 -0
  100. package/client/evm/evm.ts +134 -1
  101. package/client/evm/evm.types.ts +113 -8
  102. package/openapi-client/cdpApiClient.ts +28 -21
  103. package/openapi-client/errors.ts +37 -1
  104. package/openapi-client/generated/coinbaseDeveloperPlatformAPIs.schemas.ts +103 -2
  105. package/openapi-client/generated/evm-accounts/evm-accounts.msw.ts +29 -0
  106. package/openapi-client/generated/evm-accounts/evm-accounts.ts +47 -3
  107. package/openapi-client/generated/evm-smart-accounts/evm-smart-accounts.ts +1 -0
  108. package/openapi-client/generated/evm-token-balances/evm-token-balances.msw.ts +57 -0
  109. package/openapi-client/generated/evm-token-balances/evm-token-balances.ts +37 -0
  110. package/openapi-client/generated/faucets/faucets.ts +2 -1
  111. package/openapi-client/generated/index.msw.ts +2 -1
  112. package/openapi-client/index.ts +4 -0
  113. package/package.json +1 -1
  114. package/types/misc.ts +39 -0
  115. package/version.ts +1 -1
@@ -1,9 +1,15 @@
1
1
  // eslint-disable-next-line import/no-named-as-default
2
- import Axios, { AxiosInstance, AxiosRequestConfig, HttpStatusCode } from "axios";
2
+ import Axios, { AxiosInstance, AxiosRequestConfig } from "axios";
3
3
 
4
- import { APIError, isOpenAPIError, HttpErrorType } from "./errors.js";
5
4
  import { withAuth } from "../auth/hooks/axios/index.js";
6
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";
7
13
 
8
14
  /**
9
15
  * The options for the CDP API.
@@ -115,6 +121,15 @@ export const cdpApiClient = async <T>(
115
121
  const response = await axiosInstance(configWithIdempotencyKey);
116
122
  return response.data as T;
117
123
  } catch (error) {
124
+ // eslint-disable-next-line import/no-named-as-default-member
125
+ if (Axios.isAxiosError(error) && !error.response) {
126
+ throw new UnknownApiError(
127
+ HttpErrorType.unknown,
128
+ error.cause instanceof Error ? error.cause.message : error.message,
129
+ error.cause,
130
+ );
131
+ }
132
+
118
133
  // eslint-disable-next-line import/no-named-as-default-member
119
134
  if (Axios.isAxiosError(error) && error.response) {
120
135
  if (isOpenAPIError(error.response.data)) {
@@ -124,6 +139,7 @@ export const cdpApiClient = async <T>(
124
139
  error.response.data.errorMessage,
125
140
  error.response.data.correlationId,
126
141
  error.response.data.errorLink,
142
+ error.cause,
127
143
  );
128
144
  } else {
129
145
  const statusCode = error.response.status;
@@ -135,6 +151,7 @@ export const cdpApiClient = async <T>(
135
151
  "Unauthorized.",
136
152
  undefined,
137
153
  `${ERROR_DOCS_PAGE_URL}#unauthorized`,
154
+ error.cause,
138
155
  );
139
156
  case 404:
140
157
  throw new APIError(
@@ -143,6 +160,7 @@ export const cdpApiClient = async <T>(
143
160
  "API not found.",
144
161
  undefined,
145
162
  `${ERROR_DOCS_PAGE_URL}#not_found`,
163
+ error.cause,
146
164
  );
147
165
  case 502:
148
166
  throw new APIError(
@@ -151,6 +169,7 @@ export const cdpApiClient = async <T>(
151
169
  "Bad gateway.",
152
170
  undefined,
153
171
  `${ERROR_DOCS_PAGE_URL}`,
172
+ error.cause,
154
173
  );
155
174
  case 503:
156
175
  throw new APIError(
@@ -159,6 +178,7 @@ export const cdpApiClient = async <T>(
159
178
  "Service unavailable. Please try again later.",
160
179
  undefined,
161
180
  `${ERROR_DOCS_PAGE_URL}`,
181
+ error.cause,
162
182
  );
163
183
  default:
164
184
  throw new APIError(
@@ -167,29 +187,16 @@ export const cdpApiClient = async <T>(
167
187
  "An unexpected error occurred.",
168
188
  undefined,
169
189
  `${ERROR_DOCS_PAGE_URL}`,
190
+ error.cause,
170
191
  );
171
192
  }
172
193
  }
173
- // eslint-disable-next-line import/no-named-as-default-member
174
- } else if (Axios.isAxiosError(error) && error.request) {
175
- throw new APIError(
176
- HttpStatusCode.ServiceUnavailable,
177
- HttpErrorType.service_unavailable,
178
- "Network error, unable to reach the service.",
179
- undefined,
180
- `${ERROR_DOCS_PAGE_URL}`,
181
- );
182
- } else {
183
- throw new APIError(
184
- HttpStatusCode.InternalServerError,
185
- HttpErrorType.unexpected_error,
186
- error instanceof Error
187
- ? error.message
188
- : `An unexpected error occurred: ${JSON.stringify(error, Object.getOwnPropertyNames(error))}`,
189
- undefined,
190
- `${ERROR_DOCS_PAGE_URL}`,
191
- );
192
194
  }
195
+
196
+ throw new UnknownError(
197
+ "Something went wrong. Please reach out at https://discord.com/channels/1220414409550336183/1271495764580896789 for help.",
198
+ error instanceof Error ? error : undefined,
199
+ );
193
200
  }
194
201
  };
195
202
 
@@ -9,6 +9,7 @@ export const HttpErrorType = {
9
9
  not_found: "not_found",
10
10
  bad_gateway: "bad_gateway",
11
11
  service_unavailable: "service_unavailable",
12
+ unknown: "unknown",
12
13
  } as const;
13
14
 
14
15
  export type HttpErrorType = (typeof HttpErrorType)[keyof typeof HttpErrorType];
@@ -36,6 +37,7 @@ export class APIError extends Error {
36
37
  * @param errorMessage - The error message
37
38
  * @param correlationId - The correlation ID
38
39
  * @param errorLink - URL to documentation about this error
40
+ * @param cause - The cause of the error
39
41
  */
40
42
  constructor(
41
43
  statusCode: number,
@@ -43,8 +45,9 @@ export class APIError extends Error {
43
45
  errorMessage: string,
44
46
  correlationId?: string,
45
47
  errorLink?: string,
48
+ cause?: Error,
46
49
  ) {
47
- super(errorMessage);
50
+ super(errorMessage, { cause });
48
51
  this.name = "APIError";
49
52
  this.statusCode = statusCode;
50
53
  this.errorType = errorType;
@@ -78,6 +81,39 @@ export class APIError extends Error {
78
81
  }
79
82
  }
80
83
 
84
+ /**
85
+ * Error thrown when an Axios request is made but no response is received
86
+ */
87
+ export class UnknownApiError extends APIError {
88
+ /**
89
+ * Constructor for the UnknownApiError class
90
+ *
91
+ * @param errorType - The type of error
92
+ * @param errorMessage - The error message
93
+ * @param cause - The cause of the error
94
+ */
95
+ constructor(errorType: APIErrorType, errorMessage: string, cause?: Error) {
96
+ super(0, errorType, errorMessage, undefined, undefined, cause);
97
+ this.name = "UnknownApiError";
98
+ }
99
+ }
100
+
101
+ /**
102
+ * Error thrown when an error is not known
103
+ */
104
+ export class UnknownError extends Error {
105
+ /**
106
+ * Constructor for the UnknownError class
107
+ *
108
+ * @param message - The error message
109
+ * @param cause - The cause of the error
110
+ */
111
+ constructor(message: string, cause?: Error) {
112
+ super(message, { cause });
113
+ this.name = "UnknownError";
114
+ }
115
+ }
116
+
81
117
  /**
82
118
  * Type guard to check if an object is an OpenAPIError
83
119
  *
@@ -45,6 +45,7 @@ export const ErrorType = {
45
45
  request_canceled: "request_canceled",
46
46
  timed_out: "timed_out",
47
47
  unauthorized: "unauthorized",
48
+ policy_violation: "policy_violation",
48
49
  } as const;
49
50
 
50
51
  /**
@@ -138,6 +139,64 @@ export interface EvmUserOperation {
138
139
  transactionHash?: string;
139
140
  }
140
141
 
142
+ /**
143
+ * The name of the supported EVM networks in human-readable format.
144
+ */
145
+ export type ListEvmTokenBalancesNetwork =
146
+ (typeof ListEvmTokenBalancesNetwork)[keyof typeof ListEvmTokenBalancesNetwork];
147
+
148
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
149
+ export const ListEvmTokenBalancesNetwork = {
150
+ base: "base",
151
+ "base-sepolia": "base-sepolia",
152
+ } as const;
153
+
154
+ /**
155
+ * Amount of a given token.
156
+ */
157
+ export interface TokenAmount {
158
+ /**
159
+ * The amount is denominated in the smallest indivisible unit of the token. For ETH, the smallest indivisible unit is Wei (10^-18 ETH). For ERC-20s, the smallest unit is the unit returned from `function totalSupply() public view returns (uint256)`.
160
+ * @pattern ^[0-9]+$
161
+ */
162
+ amount: string;
163
+ /** 'decimals' is the exponential value N that satisfies the equation `amount * 10^-N = standard_denomination`. The standard denomination is the most commonly used denomination for the token.
164
+ - In the case of the native gas token, `decimals` is defined via convention. As an example, for ETH of Ethereum mainnet, the standard denomination is 10^-18 the smallest denomination (Wei). As such, for ETH on Ethereum mainnet, `decimals` is 18. - In the case of ERC-20 tokens, `decimals` is defined via configuration. `decimals` will be the number returned by `function decimals() public view returns (uint8)` on the underlying token contract.
165
+ Not all tokens have a `decimals` field, as this function is [optional in the ERC-20 specification](https://eips.ethereum.org/EIPS/eip-20#decimals). This field will be left empty if the underlying token contract doesn't implement `decimals`.
166
+ Further, this endpoint will only populate this value for a small subset of whitelisted ERC-20 tokens at this time. We intend to improve coverage in the future. */
167
+ decimals: number;
168
+ }
169
+
170
+ /**
171
+ * General information about a token. Includes the type, the network, and other identifying information.
172
+ */
173
+ export interface Token {
174
+ network: ListEvmTokenBalancesNetwork;
175
+ /** The symbol of this token (ex: SOL, ETH, USDC).
176
+ The token symbol is not unique. It is possible for two different tokens to have the same symbol.
177
+ For native gas tokens, this symbol is defined via convention. As an example, for ETH on Ethereum mainnet, the symbol is "ETH". For ERC-20 tokens, this symbol is defined via configuration. `symbol` will be the string returned by `function symbol() public view returns (string)` on the underlying token contract.
178
+ Not all tokens have a symbol, as this function is [optional in the ERC-20 specification](https://eips.ethereum.org/EIPS/eip-20#symbol). This field will only be populated when the token's underlying ERC-20 contract has a `symbol()` function.
179
+ Further, this endpoint will only populate this value for a small subset of whitelisted ERC-20 tokens at this time. We intend to improve coverage in the future. */
180
+ symbol?: string;
181
+ /** The name of this token (ex: "Solana", "Ether", "USD Coin").
182
+ The token name is not unique. It is possible for two different tokens to have the same name.
183
+ For native gas tokens, this name is defined via convention. As an example, for ETH on Ethereum mainnet, the name is "Ether". For ERC-20 tokens, this name is defined via configuration. `name` will be the string returned by `function name() public view returns (string)` on the underlying token contract.
184
+ Not all tokens have a name, as this function is [optional in the ERC-20 specification](https://eips.ethereum.org/EIPS/eip-20#name). This field will only be populated when the token's underlying ERC-20 contract has a `name()` function.
185
+ Further, this endpoint will only populate this value for a small subset of whitelisted ERC-20 tokens at this time. We intend to improve coverage in the future. */
186
+ name?: string;
187
+ /**
188
+ * The contract address of the token.
189
+ For Ether, the contract address is `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` per [EIP-7528](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7528.md). For ERC-20 tokens, this is the contract address where the token is deployed.
190
+ * @pattern ^0x[0-9a-fA-F]{40}$
191
+ */
192
+ contractAddress: string;
193
+ }
194
+
195
+ export interface TokenBalance {
196
+ amount: TokenAmount;
197
+ token: Token;
198
+ }
199
+
141
200
  export interface SolanaAccount {
142
201
  /**
143
202
  * The base58 encoded Solana address.
@@ -170,7 +229,7 @@ export type AlreadyExistsErrorResponse = Error;
170
229
 
171
230
  /**
172
231
  * A JWT signed using your Wallet Secret, encoded in base64. Refer to the
173
- [Generate a Wallet Token](https://docs.cdp.coinbase.com/api-v2/docs/authentication#3-generate-a-wallet-token)
232
+ [Generate Wallet Token](https://docs.cdp.coinbase.com/api-v2/docs/authentication#2-generate-wallet-token)
174
233
  section of our Authentication docs for more details on how to generate your Wallet Token.
175
234
 
176
235
  */
@@ -212,6 +271,30 @@ Account names must be unique across all EVM accounts in the developer's CDP Proj
212
271
  name?: string;
213
272
  };
214
273
 
274
+ /**
275
+ * The network to send the transaction to.
276
+ */
277
+ export type SendEvmTransactionBodyNetwork =
278
+ (typeof SendEvmTransactionBodyNetwork)[keyof typeof SendEvmTransactionBodyNetwork];
279
+
280
+ // eslint-disable-next-line @typescript-eslint/no-redeclare
281
+ export const SendEvmTransactionBodyNetwork = {
282
+ base: "base",
283
+ "base-sepolia": "base-sepolia",
284
+ } as const;
285
+
286
+ export type SendEvmTransactionBody = {
287
+ /** The network to send the transaction to. */
288
+ network: SendEvmTransactionBodyNetwork;
289
+ /** The RLP-encoded transaction to sign and send, as a 0x-prefixed hex string. */
290
+ transaction: string;
291
+ };
292
+
293
+ export type SendEvmTransaction200 = {
294
+ /** The hash of the transaction, as a 0x-prefixed hex string. */
295
+ transactionHash: string;
296
+ };
297
+
215
298
  export type SignEvmTransactionBody = {
216
299
  /** The RLP-encoded transaction to sign, as a 0x-prefixed hex string. */
217
300
  transaction: string;
@@ -287,10 +370,28 @@ export type PrepareUserOperationBody = {
287
370
  };
288
371
 
289
372
  export type SendUserOperationBody = {
290
- /** The hex-encoded signature of the user operation. */
373
+ /** The hex-encoded signature of the user operation. This should be a 65-byte signature consisting of the `r`, `s`, and `v` values of the ECDSA signature. Note that the `v` value should conform to the `personal_sign` standard, which means it should be 27 or 28. */
291
374
  signature: string;
292
375
  };
293
376
 
377
+ export type ListEvmTokenBalancesParams = {
378
+ /**
379
+ * The number of balances to return per page.
380
+ */
381
+ pageSize?: number;
382
+ /**
383
+ * The token for the next page of balances. Will be empty if there are no more balances to fetch.
384
+ */
385
+ pageToken?: string;
386
+ };
387
+
388
+ export type ListEvmTokenBalances200AllOf = {
389
+ /** The list of EVM token balances. */
390
+ balances: TokenBalance[];
391
+ };
392
+
393
+ export type ListEvmTokenBalances200 = ListEvmTokenBalances200AllOf & ListResponse;
394
+
294
395
  /**
295
396
  * The network to request funds from.
296
397
  */
@@ -12,6 +12,7 @@ import { HttpResponse, delay, http } from "msw";
12
12
  import type {
13
13
  EvmAccount,
14
14
  ListEvmAccounts200,
15
+ SendEvmTransaction200,
15
16
  SignEvmHash200,
16
17
  SignEvmMessage200,
17
18
  SignEvmTransaction200,
@@ -65,6 +66,10 @@ export const getGetEvmAccountByNameResponseMock = (
65
66
  ...overrideResponse,
66
67
  });
67
68
 
69
+ export const getSendEvmTransactionResponseMock = (
70
+ overrideResponse: Partial<SendEvmTransaction200> = {},
71
+ ): SendEvmTransaction200 => ({ transactionHash: faker.string.alpha(20), ...overrideResponse });
72
+
68
73
  export const getSignEvmTransactionResponseMock = (
69
74
  overrideResponse: Partial<SignEvmTransaction200> = {},
70
75
  ): SignEvmTransaction200 => ({ signedTransaction: faker.string.alpha(20), ...overrideResponse });
@@ -163,6 +168,29 @@ export const getGetEvmAccountByNameMockHandler = (
163
168
  });
164
169
  };
165
170
 
171
+ export const getSendEvmTransactionMockHandler = (
172
+ overrideResponse?:
173
+ | SendEvmTransaction200
174
+ | ((
175
+ info: Parameters<Parameters<typeof http.post>[1]>[0],
176
+ ) => Promise<SendEvmTransaction200> | SendEvmTransaction200),
177
+ ) => {
178
+ return http.post("*/v2/evm/accounts/:address/send/transaction", async info => {
179
+ await delay(0);
180
+
181
+ return new HttpResponse(
182
+ JSON.stringify(
183
+ overrideResponse !== undefined
184
+ ? typeof overrideResponse === "function"
185
+ ? await overrideResponse(info)
186
+ : overrideResponse
187
+ : getSendEvmTransactionResponseMock(),
188
+ ),
189
+ { status: 200, headers: { "Content-Type": "application/json" } },
190
+ );
191
+ });
192
+ };
193
+
166
194
  export const getSignEvmTransactionMockHandler = (
167
195
  overrideResponse?:
168
196
  | SignEvmTransaction200
@@ -236,6 +264,7 @@ export const getEvmAccountsMock = () => [
236
264
  getCreateEvmAccountMockHandler(),
237
265
  getGetEvmAccountMockHandler(),
238
266
  getGetEvmAccountByNameMockHandler(),
267
+ getSendEvmTransactionMockHandler(),
239
268
  getSignEvmTransactionMockHandler(),
240
269
  getSignEvmHashMockHandler(),
241
270
  getSignEvmMessageMockHandler(),
@@ -10,6 +10,8 @@ import type {
10
10
  EvmAccount,
11
11
  ListEvmAccounts200,
12
12
  ListEvmAccountsParams,
13
+ SendEvmTransaction200,
14
+ SendEvmTransactionBody,
13
15
  SignEvmHash200,
14
16
  SignEvmHashBody,
15
17
  SignEvmMessage200,
@@ -74,6 +76,50 @@ export const getEvmAccountByName = (
74
76
  options,
75
77
  );
76
78
  };
79
+ /**
80
+ * Signs a transaction with the given EVM account and sends it to the indicated supported network. This API handles nonce management and gas estimation, leaving the developer to provide only the minimal set of fields necessary to send the transaction. The transaction should be serialized as a hex string using [RLP](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/).
81
+
82
+ The transaction must be an [EIP-1559 dynamic fee transaction](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md).
83
+
84
+
85
+ **Transaction fields and API behavior**
86
+
87
+ - `to` *(Required)*: The address of the contract or account to send the transaction to.
88
+ - `chainId` *(Ignored)*: The value of the `chainId` field in the transaction is ignored.
89
+ The transaction will be sent to the network indicated by the `network` field in the request body.
90
+
91
+ - `nonce` *(Optional)*: The nonce to use for the transaction. If not provided, the API will assign
92
+ a nonce to the transaction based on the current state of the account.
93
+
94
+ - `maxPriorityFeePerGas` *(Optional)*: The maximum priority fee per gas to use for the transaction.
95
+ If not provided, the API will estimate a value based on current network conditions.
96
+
97
+ - `maxFeePerGas` *(Optional)*: The maximum fee per gas to use for the transaction.
98
+ If not provided, the API will estimate a value based on current network conditions.
99
+
100
+ - `gasLimit` *(Optional)*: The gas limit to use for the transaction. If not provided, the API will estimate a value
101
+ based on the `to` and `data` fields of the transaction.
102
+
103
+ - `value` *(Optional)*: The amount of ETH, in wei, to send with the transaction.
104
+ - `data` *(Optional)*: The data to send with the transaction; only used for contract calls.
105
+ - `accessList` *(Optional)*: The access list to use for the transaction.
106
+ * @summary Send a transaction
107
+ */
108
+ export const sendEvmTransaction = (
109
+ address: string,
110
+ sendEvmTransactionBody: SendEvmTransactionBody,
111
+ options?: SecondParameter<typeof cdpApiClient>,
112
+ ) => {
113
+ return cdpApiClient<SendEvmTransaction200>(
114
+ {
115
+ url: `/v2/evm/accounts/${address}/send/transaction`,
116
+ method: "POST",
117
+ headers: { "Content-Type": "application/json" },
118
+ data: sendEvmTransactionBody,
119
+ },
120
+ options,
121
+ );
122
+ };
77
123
  /**
78
124
  * Signs a transaction with the given EVM account.
79
125
  The transaction should be serialized as a hex string using [RLP](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp/).
@@ -98,9 +144,6 @@ export const signEvmTransaction = (
98
144
  };
99
145
  /**
100
146
  * Signs an arbitrary 32 byte hash with the given EVM account.
101
-
102
-
103
- **WARNING: This API will likely be deprecated in the future.** It is recommended not to depend on it. Never sign a hash that you didn't generate, as it can be an arbitrary transaction. For example, it might send all of your funds to an attacker.
104
147
  * @summary Sign a hash
105
148
  */
106
149
  export const signEvmHash = (
@@ -145,6 +188,7 @@ export type GetEvmAccountResult = NonNullable<Awaited<ReturnType<typeof getEvmAc
145
188
  export type GetEvmAccountByNameResult = NonNullable<
146
189
  Awaited<ReturnType<typeof getEvmAccountByName>>
147
190
  >;
191
+ export type SendEvmTransactionResult = NonNullable<Awaited<ReturnType<typeof sendEvmTransaction>>>;
148
192
  export type SignEvmTransactionResult = NonNullable<Awaited<ReturnType<typeof signEvmTransaction>>>;
149
193
  export type SignEvmHashResult = NonNullable<Awaited<ReturnType<typeof signEvmHash>>>;
150
194
  export type SignEvmMessageResult = NonNullable<Awaited<ReturnType<typeof signEvmMessage>>>;
@@ -99,6 +99,7 @@ export const getUserOperation = (
99
99
  };
100
100
  /**
101
101
  * Sends a user operation with a signature.
102
+ The signature that is sent should be 65 bytes, consisting of the `r`, `s`, and `v` values of the ECDSA signature. Note that the `v` value should conform to the `personal_sign` standard, which means it should be 27 or 28.
102
103
  * @summary Send a user operation
103
104
  */
104
105
  export const sendUserOperation = (
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Generated by orval v7.6.0 🍺
3
+ * Do not edit manually.
4
+ * Coinbase Developer Platform APIs
5
+ * The Coinbase Developer Platform APIs - leading the world's transition onchain.
6
+ * OpenAPI spec version: 2.0.0
7
+ */
8
+ import { faker } from "@faker-js/faker";
9
+
10
+ import { HttpResponse, delay, http } from "msw";
11
+
12
+ import { ListEvmTokenBalancesNetwork } from "../coinbaseDeveloperPlatformAPIs.schemas.js";
13
+ import type { ListEvmTokenBalances200 } from "../coinbaseDeveloperPlatformAPIs.schemas.js";
14
+
15
+ export const getListEvmTokenBalancesResponseMock = (): ListEvmTokenBalances200 => ({
16
+ ...{
17
+ balances: Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(
18
+ () => ({
19
+ amount: {
20
+ amount: faker.helpers.fromRegExp("^[0-9]+$"),
21
+ decimals: faker.number.int({ min: undefined, max: undefined }),
22
+ },
23
+ token: {
24
+ network: faker.helpers.arrayElement(Object.values(ListEvmTokenBalancesNetwork)),
25
+ symbol: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
26
+ name: faker.helpers.arrayElement([faker.string.alpha(20), undefined]),
27
+ contractAddress: faker.helpers.fromRegExp("^0x[0-9a-fA-F]{40}$"),
28
+ },
29
+ }),
30
+ ),
31
+ },
32
+ ...{ nextPageToken: faker.helpers.arrayElement([faker.string.alpha(20), undefined]) },
33
+ });
34
+
35
+ export const getListEvmTokenBalancesMockHandler = (
36
+ overrideResponse?:
37
+ | ListEvmTokenBalances200
38
+ | ((
39
+ info: Parameters<Parameters<typeof http.get>[1]>[0],
40
+ ) => Promise<ListEvmTokenBalances200> | ListEvmTokenBalances200),
41
+ ) => {
42
+ return http.get("*/v2/evm/token-balances/:network/:address", async info => {
43
+ await delay(0);
44
+
45
+ return new HttpResponse(
46
+ JSON.stringify(
47
+ overrideResponse !== undefined
48
+ ? typeof overrideResponse === "function"
49
+ ? await overrideResponse(info)
50
+ : overrideResponse
51
+ : getListEvmTokenBalancesResponseMock(),
52
+ ),
53
+ { status: 200, headers: { "Content-Type": "application/json" } },
54
+ );
55
+ });
56
+ };
57
+ export const getEvmTokenBalancesMock = () => [getListEvmTokenBalancesMockHandler()];
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Generated by orval v7.6.0 🍺
3
+ * Do not edit manually.
4
+ * Coinbase Developer Platform APIs
5
+ * The Coinbase Developer Platform APIs - leading the world's transition onchain.
6
+ * OpenAPI spec version: 2.0.0
7
+ */
8
+ import type {
9
+ ListEvmTokenBalances200,
10
+ ListEvmTokenBalancesNetwork,
11
+ ListEvmTokenBalancesParams,
12
+ } from "../coinbaseDeveloperPlatformAPIs.schemas.js";
13
+
14
+ import { cdpApiClient } from "../../cdpApiClient.js";
15
+
16
+ type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
17
+
18
+ /**
19
+ * Lists the token balances of an EVM address on a given network. The balances include ERC-20 tokens and the native gas token (usually ETH). The response is paginated, and by default, returns 20 balances per page.
20
+
21
+ **Note:** This endpoint is still under development and does not yet provide strong freshness guarantees. Specifically, balances of new tokens can, on occasion, take up to ~30 seconds to appear, while balances of tokens already belonging to an address will generally be close to chain tip. Freshness of new token balances will improve over the coming weeks.
22
+ * @summary List EVM token balances
23
+ */
24
+ export const listEvmTokenBalances = (
25
+ network: ListEvmTokenBalancesNetwork,
26
+ address: string,
27
+ params?: ListEvmTokenBalancesParams,
28
+ options?: SecondParameter<typeof cdpApiClient>,
29
+ ) => {
30
+ return cdpApiClient<ListEvmTokenBalances200>(
31
+ { url: `/v2/evm/token-balances/${network}/${address}`, method: "GET", params },
32
+ options,
33
+ );
34
+ };
35
+ export type ListEvmTokenBalancesResult = NonNullable<
36
+ Awaited<ReturnType<typeof listEvmTokenBalances>>
37
+ >;
@@ -27,7 +27,7 @@ A single blockchain address cannot exceed the specified limits, even if multiple
27
27
 
28
28
  | Token | Amount per Faucet Request |Rolling 24-hour window Rate Limits|
29
29
  |:-----:|:-------------------------:|:--------------------------------:|
30
- | ETH | 0.0001 ETH | 0.001 ETH |
30
+ | ETH | 0.0001 ETH | 0.1 ETH |
31
31
  | USDC | 1 USDC | 10 USDC |
32
32
  | EURC | 1 EURC | 10 EURC |
33
33
  | cbBTC | 0.0001 cbBTC | 0.001 cbBTC |
@@ -60,6 +60,7 @@ A single blockchain address cannot exceed the specified limits, even if multiple
60
60
  | Token | Amount per Faucet Request |Rolling 24-hour window Rate Limits|
61
61
  |:-----:|:-------------------------:|:--------------------------------:|
62
62
  | SOL | 0.00125 SOL | 0.0125 SOL |
63
+ | USDC | 1 USDC | 10 USDC |
63
64
 
64
65
  * @summary Request funds on Solana devnet
65
66
  */
@@ -1,4 +1,5 @@
1
1
  export * from "./evm-accounts/evm-accounts.msw.js";
2
- export * from "./evm-smart-accounts/evm-smart-accounts.msw.js";
3
2
  export * from "./faucets/faucets.msw.js";
3
+ export * from "./evm-smart-accounts/evm-smart-accounts.msw.js";
4
+ export * from "./evm-token-balances/evm-token-balances.msw.js";
4
5
  export * from "./solana-accounts/solana-accounts.msw.js";
@@ -1,18 +1,21 @@
1
1
  export * from "./generated/coinbaseDeveloperPlatformAPIs.schemas.js";
2
2
  export * from "./generated/evm-accounts/evm-accounts.js";
3
3
  export * from "./generated/evm-smart-accounts/evm-smart-accounts.js";
4
+ export * from "./generated/evm-token-balances/evm-token-balances.js";
4
5
  export * from "./generated/solana-accounts/solana-accounts.js";
5
6
  export * from "./generated/faucets/faucets.js";
6
7
 
7
8
  import { configure } from "./cdpApiClient.js";
8
9
  import * as evm from "./generated/evm-accounts/evm-accounts.js";
9
10
  import * as evmSmartAccounts from "./generated/evm-smart-accounts/evm-smart-accounts.js";
11
+ import * as evmTokenBalances from "./generated/evm-token-balances/evm-token-balances.js";
10
12
  import * as faucets from "./generated/faucets/faucets.js";
11
13
  import * as solana from "./generated/solana-accounts/solana-accounts.js";
12
14
 
13
15
  export const CdpOpenApiClient = {
14
16
  ...evm,
15
17
  ...evmSmartAccounts,
18
+ ...evmTokenBalances,
16
19
  ...solana,
17
20
  ...faucets,
18
21
  configure,
@@ -21,6 +24,7 @@ export const CdpOpenApiClient = {
21
24
  export const OpenApiEvmMethods = {
22
25
  ...evm,
23
26
  ...evmSmartAccounts,
27
+ ...evmTokenBalances,
24
28
  requestEvmFaucet: faucets.requestEvmFaucet,
25
29
  };
26
30
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coinbase/cdp-sdk",
3
- "version": "1.2.0",
3
+ "version": "1.3.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",
package/types/misc.ts CHANGED
@@ -3,3 +3,42 @@
3
3
  export type Hex = `0x${string}`;
4
4
  export type Hash = `0x${string}`;
5
5
  export type Address = `0x${string}`;
6
+
7
+ export type AccessList = readonly {
8
+ address: Address;
9
+ storageKeys: readonly Hex[];
10
+ }[];
11
+
12
+ export type TransactionRequestEIP1559 = {
13
+ /** The address of the contract or account to send the transaction to. */
14
+ to: Address;
15
+ /** The amount of ETH, in wei, to send with the transaction. */
16
+ value?: bigint | undefined;
17
+ /** The data to send with the transaction; only used for contract calls. */
18
+ data?: Hex | undefined;
19
+ /** The amount of gas to use for the transaction. */
20
+ gas?: bigint | undefined;
21
+ /**
22
+ * The nonce to use for the transaction.
23
+ * If not provided, the API will assign a nonce to the transaction based on the current state of the account.
24
+ */
25
+ nonce?: number | undefined;
26
+ /**
27
+ * The maximum fee per gas to use for the transaction.
28
+ * If not provided, the API will estimate a value based on current network conditions.
29
+ */
30
+ maxFeePerGas?: bigint | undefined;
31
+ /**
32
+ * The maximum priority fee per gas to use for the transaction.
33
+ * If not provided, the API will estimate a value based on current network conditions.
34
+ */
35
+ maxPriorityFeePerGas?: bigint | undefined;
36
+ /** The access list to use for the transaction. */
37
+ accessList?: AccessList | undefined;
38
+ /** (Ignored) The value of the `chainId` field in the transaction is ignored. */
39
+ chainId?: number | undefined;
40
+ /** (Ignored) Ignored in favor of the account address that is sending the transaction. */
41
+ from?: Address | undefined;
42
+ /** (Ignored) The transaction type is always `eip1559`. */
43
+ type?: "eip1559" | undefined;
44
+ };
package/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = "1.2.0";
1
+ export const version = "1.3.0";