diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fd93212..97ead9c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Coinbase Node.js SDK Changelog +## [0.18.0] - 2025-02-13 + +### Added +- Add `TransactionReceipt` and `TransactionLog` to contract invocation response. + ## [0.17.0] - 2025-02-01 ### Added diff --git a/package-lock.json b/package-lock.json index 0399d8ce..82464954 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@coinbase/coinbase-sdk", - "version": "0.16.0", + "version": "0.18.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@coinbase/coinbase-sdk", - "version": "0.16.0", + "version": "0.18.0", "license": "ISC", "dependencies": { "@scure/bip32": "^1.4.0", diff --git a/package.json b/package.json index 222d7b75..ab76959c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "license": "ISC", "description": "Coinbase Platform SDK", "repository": "https://github.com/coinbase/coinbase-sdk-nodejs", - "version": "0.17.0", + "version": "0.18.0", "main": "dist/index.js", "types": "dist/index.d.ts", "scripts": { diff --git a/quickstart-template/package.json b/quickstart-template/package.json index 11b8bc42..404f2166 100644 --- a/quickstart-template/package.json +++ b/quickstart-template/package.json @@ -22,7 +22,7 @@ "dependencies": { "@solana/web3.js": "^2.0.0-rc.1", "bs58": "^6.0.0", - "@coinbase/coinbase-sdk": "^0.16.0", + "@coinbase/coinbase-sdk": "^0.18.0", "csv-parse": "^5.5.6", "csv-writer": "^1.6.0", "viem": "^2.21.6" diff --git a/src/client/api.ts b/src/client/api.ts index da0e706f..64d79f8d 100644 --- a/src/client/api.ts +++ b/src/client/api.ts @@ -417,6 +417,19 @@ export interface BroadcastTransferRequest { */ 'signed_payload': string; } +/** + * + * @export + * @interface BroadcastUserOperationRequest + */ +export interface BroadcastUserOperationRequest { + /** + * The hex-encoded signature of the user operation. + * @type {string} + * @memberof BroadcastUserOperationRequest + */ + 'signature': string; +} /** * * @export @@ -454,6 +467,31 @@ export interface BuildStakingOperationRequest { */ 'options': { [key: string]: string; }; } +/** + * An action that will be bundled into a user operation. + * @export + * @interface Call + */ +export interface Call { + /** + * The address the call is interacting with. + * @type {string} + * @memberof Call + */ + 'to': string; + /** + * The hex-encoded data to send with the call. + * @type {string} + * @memberof Call + */ + 'data': string; + /** + * The string-encoded integer value to send with the call. + * @type {string} + * @memberof Call + */ + 'value': string; +} /** * * @export @@ -938,6 +976,19 @@ export interface CreateSmartContractRequest { } +/** + * + * @export + * @interface CreateSmartWalletRequest + */ +export interface CreateSmartWalletRequest { + /** + * The address of the owner of the smart wallet. + * @type {string} + * @memberof CreateSmartWalletRequest + */ + 'owner': string; +} /** * * @export @@ -1037,6 +1088,19 @@ export interface CreateTransferRequest { */ 'skip_batching'?: boolean; } +/** + * + * @export + * @interface CreateUserOperationRequest + */ +export interface CreateUserOperationRequest { + /** + * The list of calls to make from the smart wallet. + * @type {Array} + * @memberof CreateUserOperationRequest + */ + 'calls': Array; +} /** * * @export @@ -1506,6 +1570,12 @@ export interface EthereumTransaction { * @memberof EthereumTransaction */ 'rlp_encoded_tx'?: string; + /** + * + * @type {TransactionReceipt} + * @memberof EthereumTransaction + */ + 'receipt'?: TransactionReceipt; } /** * @@ -1720,6 +1790,18 @@ export interface EthereumValidatorMetadata { * @memberof EthereumValidatorMetadata */ 'effective_balance': Balance; + /** + * The address for execution layer rewards (MEV & tx fees). If using a reward splitter plan, this is a smart contract address that splits rewards based on defined commissions and send a portion to the forwarded_fee_recipient_address. + * @type {string} + * @memberof EthereumValidatorMetadata + */ + 'fee_recipient_address': string; + /** + * If using a reward splitter plan, this address receives a defined percentage of the total execution layer rewards. + * @type {string} + * @memberof EthereumValidatorMetadata + */ + 'forwarded_fee_recipient_address'?: string; } /** * The faucet transaction @@ -3043,6 +3125,56 @@ export const SmartContractType = { export type SmartContractType = typeof SmartContractType[keyof typeof SmartContractType]; +/** + * + * @export + * @interface SmartWallet + */ +export interface SmartWallet { + /** + * The onchain address of the smart wallet. + * @type {string} + * @memberof SmartWallet + */ + 'address': string; + /** + * The list of owner addresses for the smart wallet. + * @type {Array} + * @memberof SmartWallet + */ + 'owners': Array; +} +/** + * Paginated list of smart wallets + * @export + * @interface SmartWalletList + */ +export interface SmartWalletList { + /** + * + * @type {Array} + * @memberof SmartWalletList + */ + 'data': Array; + /** + * True if this list has another page of items after this one that can be fetched. + * @type {boolean} + * @memberof SmartWalletList + */ + 'has_more': boolean; + /** + * The page token to be used to fetch the next page. + * @type {string} + * @memberof SmartWalletList + */ + 'next_page': string; + /** + * The total number of wallets + * @type {number} + * @memberof SmartWalletList + */ + 'total_count': number; +} /** * * @export @@ -3261,6 +3393,12 @@ export interface StakingContextContext { * @memberof StakingContextContext */ 'unstakeable_balance': Balance; + /** + * + * @type {Balance} + * @memberof StakingContextContext + */ + 'pending_claimable_balance': Balance; /** * * @type {Balance} @@ -3653,6 +3791,62 @@ export type TransactionStatusEnum = typeof TransactionStatusEnum[keyof typeof Tr */ export type TransactionContent = EthereumTransaction; +/** + * A log emitted from an onchain transaction. + * @export + * @interface TransactionLog + */ +export interface TransactionLog { + /** + * An onchain address of a contract. + * @type {string} + * @memberof TransactionLog + */ + 'address': string; + /** + * + * @type {Array} + * @memberof TransactionLog + */ + 'topics': Array; + /** + * The data included in this log. + * @type {string} + * @memberof TransactionLog + */ + 'data': string; +} +/** + * The receipt of an onchain transaction\'s execution. + * @export + * @interface TransactionReceipt + */ +export interface TransactionReceipt { + /** + * The status of a transaction is 1 if successful or 0 if it was reverted. + * @type {number} + * @memberof TransactionReceipt + */ + 'status': number; + /** + * + * @type {Array} + * @memberof TransactionReceipt + */ + 'logs': Array; + /** + * The amount of gas actually used by this transaction. + * @type {string} + * @memberof TransactionReceipt + */ + 'gas_used': string; + /** + * The effective gas price the transaction was charged at. + * @type {string} + * @memberof TransactionReceipt + */ + 'effective_gas_price': string; +} /** * * @export @@ -3870,6 +4064,66 @@ export interface User { */ 'display_name'?: string; } +/** + * + * @export + * @interface UserOperation + */ +export interface UserOperation { + /** + * The ID of the user operation. + * @type {string} + * @memberof UserOperation + */ + 'id': string; + /** + * The ID of the network the user operation is being created on. + * @type {string} + * @memberof UserOperation + */ + 'network_id': string; + /** + * The list of calls to make from the smart wallet. + * @type {Array} + * @memberof UserOperation + */ + 'calls': Array; + /** + * The hex-encoded hash that must be signed by the user. + * @type {string} + * @memberof UserOperation + */ + 'unsigned_payload': string; + /** + * The hex-encoded signature of the user operation. + * @type {string} + * @memberof UserOperation + */ + 'signature'?: string; + /** + * The hash of the transaction that was broadcast. + * @type {string} + * @memberof UserOperation + */ + 'transaction_hash'?: string; + /** + * The status of the user operation. + * @type {string} + * @memberof UserOperation + */ + 'status': UserOperationStatusEnum; +} + +export const UserOperationStatusEnum = { + Pending: 'pending', + Signed: 'signed', + Broadcast: 'broadcast', + Complete: 'complete', + Failed: 'failed' +} as const; + +export type UserOperationStatusEnum = typeof UserOperationStatusEnum[keyof typeof UserOperationStatusEnum]; + /** * A validator onchain. * @export @@ -9716,6 +9970,604 @@ export class SmartContractsApi extends BaseAPI implements SmartContractsApiInter +/** + * SmartWalletsApi - axios parameter creator + * @export + */ +export const SmartWalletsApiAxiosParamCreator = function (configuration?: Configuration) { + return { + /** + * Broadcast a user operation + * @summary Broadcast a user operation + * @param {string} smartWalletAddress The address of the smart wallet to broadcast the user operation from. + * @param {string} userOperationId The ID of the user operation to broadcast. + * @param {BroadcastUserOperationRequest} [broadcastUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + broadcastUserOperation: async (smartWalletAddress: string, userOperationId: string, broadcastUserOperationRequest?: BroadcastUserOperationRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'smartWalletAddress' is not null or undefined + assertParamExists('broadcastUserOperation', 'smartWalletAddress', smartWalletAddress) + // verify required parameter 'userOperationId' is not null or undefined + assertParamExists('broadcastUserOperation', 'userOperationId', userOperationId) + const localVarPath = `/v1/smart_wallets/{smart_wallet_address}/user_operations/{user_operation_id}/broadcast` + .replace(`{${"smart_wallet_address"}}`, encodeURIComponent(String(smartWalletAddress))) + .replace(`{${"user_operation_id"}}`, encodeURIComponent(String(userOperationId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication apiKey required + await setApiKeyToObject(localVarHeaderParameter, "Jwt", configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(broadcastUserOperationRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Create a new smart wallet, not scoped to a given network. + * @summary Create a new smart wallet + * @param {CreateSmartWalletRequest} [createSmartWalletRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createSmartWallet: async (createSmartWalletRequest?: CreateSmartWalletRequest, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/v1/smart_wallets`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication apiKey required + await setApiKeyToObject(localVarHeaderParameter, "Jwt", configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createSmartWalletRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Create a new user operation on a smart wallet. + * @summary Create a new user operation + * @param {string} smartWalletAddress The address of the smart wallet to create the user operation on. + * @param {string} networkId The ID of the network to create the user operation on. + * @param {CreateUserOperationRequest} [createUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createUserOperation: async (smartWalletAddress: string, networkId: string, createUserOperationRequest?: CreateUserOperationRequest, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'smartWalletAddress' is not null or undefined + assertParamExists('createUserOperation', 'smartWalletAddress', smartWalletAddress) + // verify required parameter 'networkId' is not null or undefined + assertParamExists('createUserOperation', 'networkId', networkId) + const localVarPath = `/v1/smart_wallets/{smart_wallet_address}/networks/{network_id}/user_operations` + .replace(`{${"smart_wallet_address"}}`, encodeURIComponent(String(smartWalletAddress))) + .replace(`{${"network_id"}}`, encodeURIComponent(String(networkId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication apiKey required + await setApiKeyToObject(localVarHeaderParameter, "Jwt", configuration) + + + + localVarHeaderParameter['Content-Type'] = 'application/json'; + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + localVarRequestOptions.data = serializeDataIfNeeded(createUserOperationRequest, localVarRequestOptions, configuration) + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Get smart wallet + * @summary Get smart wallet by address + * @param {string} smartWalletAddress The address of that smart wallet to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getSmartWallet: async (smartWalletAddress: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'smartWalletAddress' is not null or undefined + assertParamExists('getSmartWallet', 'smartWalletAddress', smartWalletAddress) + const localVarPath = `/v1/smart_wallets/{smart_wallet_address}` + .replace(`{${"smart_wallet_address"}}`, encodeURIComponent(String(smartWalletAddress))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication apiKey required + await setApiKeyToObject(localVarHeaderParameter, "Jwt", configuration) + + // authentication session required + await setApiKeyToObject(localVarHeaderParameter, "Jwt", configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * Get user operation + * @summary Get user operation + * @param {string} smartWalletAddress The address of the smart wallet the user operation belongs to. + * @param {string} userOperationId The ID of the user operation to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserOperation: async (smartWalletAddress: string, userOperationId: string, options: RawAxiosRequestConfig = {}): Promise => { + // verify required parameter 'smartWalletAddress' is not null or undefined + assertParamExists('getUserOperation', 'smartWalletAddress', smartWalletAddress) + // verify required parameter 'userOperationId' is not null or undefined + assertParamExists('getUserOperation', 'userOperationId', userOperationId) + const localVarPath = `/v1/smart_wallets/{smart_wallet_address}/user_operations/{user_operation_id}` + .replace(`{${"smart_wallet_address"}}`, encodeURIComponent(String(smartWalletAddress))) + .replace(`{${"user_operation_id"}}`, encodeURIComponent(String(userOperationId))); + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication apiKey required + await setApiKeyToObject(localVarHeaderParameter, "Jwt", configuration) + + // authentication session required + await setApiKeyToObject(localVarHeaderParameter, "Jwt", configuration) + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + /** + * List smart wallets + * @summary List smart wallets + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listSmartWallets: async (limit?: number, page?: string, options: RawAxiosRequestConfig = {}): Promise => { + const localVarPath = `/v1/smart_wallets`; + // use dummy base URL string because the URL constructor only accepts absolute URLs. + const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); + let baseOptions; + if (configuration) { + baseOptions = configuration.baseOptions; + } + + const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options}; + const localVarHeaderParameter = {} as any; + const localVarQueryParameter = {} as any; + + // authentication apiKey required + await setApiKeyToObject(localVarHeaderParameter, "Jwt", configuration) + + // authentication session required + await setApiKeyToObject(localVarHeaderParameter, "Jwt", configuration) + + if (limit !== undefined) { + localVarQueryParameter['limit'] = limit; + } + + if (page !== undefined) { + localVarQueryParameter['page'] = page; + } + + + + setSearchParams(localVarUrlObj, localVarQueryParameter); + let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {}; + localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers}; + + return { + url: toPathString(localVarUrlObj), + options: localVarRequestOptions, + }; + }, + } +}; + +/** + * SmartWalletsApi - functional programming interface + * @export + */ +export const SmartWalletsApiFp = function(configuration?: Configuration) { + const localVarAxiosParamCreator = SmartWalletsApiAxiosParamCreator(configuration) + return { + /** + * Broadcast a user operation + * @summary Broadcast a user operation + * @param {string} smartWalletAddress The address of the smart wallet to broadcast the user operation from. + * @param {string} userOperationId The ID of the user operation to broadcast. + * @param {BroadcastUserOperationRequest} [broadcastUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async broadcastUserOperation(smartWalletAddress: string, userOperationId: string, broadcastUserOperationRequest?: BroadcastUserOperationRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.broadcastUserOperation(smartWalletAddress, userOperationId, broadcastUserOperationRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['SmartWalletsApi.broadcastUserOperation']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Create a new smart wallet, not scoped to a given network. + * @summary Create a new smart wallet + * @param {CreateSmartWalletRequest} [createSmartWalletRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createSmartWallet(createSmartWalletRequest?: CreateSmartWalletRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createSmartWallet(createSmartWalletRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['SmartWalletsApi.createSmartWallet']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Create a new user operation on a smart wallet. + * @summary Create a new user operation + * @param {string} smartWalletAddress The address of the smart wallet to create the user operation on. + * @param {string} networkId The ID of the network to create the user operation on. + * @param {CreateUserOperationRequest} [createUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async createUserOperation(smartWalletAddress: string, networkId: string, createUserOperationRequest?: CreateUserOperationRequest, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.createUserOperation(smartWalletAddress, networkId, createUserOperationRequest, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['SmartWalletsApi.createUserOperation']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Get smart wallet + * @summary Get smart wallet by address + * @param {string} smartWalletAddress The address of that smart wallet to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getSmartWallet(smartWalletAddress: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getSmartWallet(smartWalletAddress, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['SmartWalletsApi.getSmartWallet']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * Get user operation + * @summary Get user operation + * @param {string} smartWalletAddress The address of the smart wallet the user operation belongs to. + * @param {string} userOperationId The ID of the user operation to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async getUserOperation(smartWalletAddress: string, userOperationId: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getUserOperation(smartWalletAddress, userOperationId, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['SmartWalletsApi.getUserOperation']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + /** + * List smart wallets + * @summary List smart wallets + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + async listSmartWallets(limit?: number, page?: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.listSmartWallets(limit, page, options); + const localVarOperationServerIndex = configuration?.serverIndex ?? 0; + const localVarOperationServerBasePath = operationServerMap['SmartWalletsApi.listSmartWallets']?.[localVarOperationServerIndex]?.url; + return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath); + }, + } +}; + +/** + * SmartWalletsApi - factory interface + * @export + */ +export const SmartWalletsApiFactory = function (configuration?: Configuration, basePath?: string, axios?: AxiosInstance) { + const localVarFp = SmartWalletsApiFp(configuration) + return { + /** + * Broadcast a user operation + * @summary Broadcast a user operation + * @param {string} smartWalletAddress The address of the smart wallet to broadcast the user operation from. + * @param {string} userOperationId The ID of the user operation to broadcast. + * @param {BroadcastUserOperationRequest} [broadcastUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + broadcastUserOperation(smartWalletAddress: string, userOperationId: string, broadcastUserOperationRequest?: BroadcastUserOperationRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.broadcastUserOperation(smartWalletAddress, userOperationId, broadcastUserOperationRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Create a new smart wallet, not scoped to a given network. + * @summary Create a new smart wallet + * @param {CreateSmartWalletRequest} [createSmartWalletRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createSmartWallet(createSmartWalletRequest?: CreateSmartWalletRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.createSmartWallet(createSmartWalletRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Create a new user operation on a smart wallet. + * @summary Create a new user operation + * @param {string} smartWalletAddress The address of the smart wallet to create the user operation on. + * @param {string} networkId The ID of the network to create the user operation on. + * @param {CreateUserOperationRequest} [createUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + createUserOperation(smartWalletAddress: string, networkId: string, createUserOperationRequest?: CreateUserOperationRequest, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.createUserOperation(smartWalletAddress, networkId, createUserOperationRequest, options).then((request) => request(axios, basePath)); + }, + /** + * Get smart wallet + * @summary Get smart wallet by address + * @param {string} smartWalletAddress The address of that smart wallet to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getSmartWallet(smartWalletAddress: string, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.getSmartWallet(smartWalletAddress, options).then((request) => request(axios, basePath)); + }, + /** + * Get user operation + * @summary Get user operation + * @param {string} smartWalletAddress The address of the smart wallet the user operation belongs to. + * @param {string} userOperationId The ID of the user operation to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + getUserOperation(smartWalletAddress: string, userOperationId: string, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.getUserOperation(smartWalletAddress, userOperationId, options).then((request) => request(axios, basePath)); + }, + /** + * List smart wallets + * @summary List smart wallets + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + */ + listSmartWallets(limit?: number, page?: string, options?: RawAxiosRequestConfig): AxiosPromise { + return localVarFp.listSmartWallets(limit, page, options).then((request) => request(axios, basePath)); + }, + }; +}; + +/** + * SmartWalletsApi - interface + * @export + * @interface SmartWalletsApi + */ +export interface SmartWalletsApiInterface { + /** + * Broadcast a user operation + * @summary Broadcast a user operation + * @param {string} smartWalletAddress The address of the smart wallet to broadcast the user operation from. + * @param {string} userOperationId The ID of the user operation to broadcast. + * @param {BroadcastUserOperationRequest} [broadcastUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApiInterface + */ + broadcastUserOperation(smartWalletAddress: string, userOperationId: string, broadcastUserOperationRequest?: BroadcastUserOperationRequest, options?: RawAxiosRequestConfig): AxiosPromise; + + /** + * Create a new smart wallet, not scoped to a given network. + * @summary Create a new smart wallet + * @param {CreateSmartWalletRequest} [createSmartWalletRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApiInterface + */ + createSmartWallet(createSmartWalletRequest?: CreateSmartWalletRequest, options?: RawAxiosRequestConfig): AxiosPromise; + + /** + * Create a new user operation on a smart wallet. + * @summary Create a new user operation + * @param {string} smartWalletAddress The address of the smart wallet to create the user operation on. + * @param {string} networkId The ID of the network to create the user operation on. + * @param {CreateUserOperationRequest} [createUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApiInterface + */ + createUserOperation(smartWalletAddress: string, networkId: string, createUserOperationRequest?: CreateUserOperationRequest, options?: RawAxiosRequestConfig): AxiosPromise; + + /** + * Get smart wallet + * @summary Get smart wallet by address + * @param {string} smartWalletAddress The address of that smart wallet to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApiInterface + */ + getSmartWallet(smartWalletAddress: string, options?: RawAxiosRequestConfig): AxiosPromise; + + /** + * Get user operation + * @summary Get user operation + * @param {string} smartWalletAddress The address of the smart wallet the user operation belongs to. + * @param {string} userOperationId The ID of the user operation to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApiInterface + */ + getUserOperation(smartWalletAddress: string, userOperationId: string, options?: RawAxiosRequestConfig): AxiosPromise; + + /** + * List smart wallets + * @summary List smart wallets + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApiInterface + */ + listSmartWallets(limit?: number, page?: string, options?: RawAxiosRequestConfig): AxiosPromise; + +} + +/** + * SmartWalletsApi - object-oriented interface + * @export + * @class SmartWalletsApi + * @extends {BaseAPI} + */ +export class SmartWalletsApi extends BaseAPI implements SmartWalletsApiInterface { + /** + * Broadcast a user operation + * @summary Broadcast a user operation + * @param {string} smartWalletAddress The address of the smart wallet to broadcast the user operation from. + * @param {string} userOperationId The ID of the user operation to broadcast. + * @param {BroadcastUserOperationRequest} [broadcastUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApi + */ + public broadcastUserOperation(smartWalletAddress: string, userOperationId: string, broadcastUserOperationRequest?: BroadcastUserOperationRequest, options?: RawAxiosRequestConfig) { + return SmartWalletsApiFp(this.configuration).broadcastUserOperation(smartWalletAddress, userOperationId, broadcastUserOperationRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Create a new smart wallet, not scoped to a given network. + * @summary Create a new smart wallet + * @param {CreateSmartWalletRequest} [createSmartWalletRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApi + */ + public createSmartWallet(createSmartWalletRequest?: CreateSmartWalletRequest, options?: RawAxiosRequestConfig) { + return SmartWalletsApiFp(this.configuration).createSmartWallet(createSmartWalletRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Create a new user operation on a smart wallet. + * @summary Create a new user operation + * @param {string} smartWalletAddress The address of the smart wallet to create the user operation on. + * @param {string} networkId The ID of the network to create the user operation on. + * @param {CreateUserOperationRequest} [createUserOperationRequest] + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApi + */ + public createUserOperation(smartWalletAddress: string, networkId: string, createUserOperationRequest?: CreateUserOperationRequest, options?: RawAxiosRequestConfig) { + return SmartWalletsApiFp(this.configuration).createUserOperation(smartWalletAddress, networkId, createUserOperationRequest, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Get smart wallet + * @summary Get smart wallet by address + * @param {string} smartWalletAddress The address of that smart wallet to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApi + */ + public getSmartWallet(smartWalletAddress: string, options?: RawAxiosRequestConfig) { + return SmartWalletsApiFp(this.configuration).getSmartWallet(smartWalletAddress, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * Get user operation + * @summary Get user operation + * @param {string} smartWalletAddress The address of the smart wallet the user operation belongs to. + * @param {string} userOperationId The ID of the user operation to fetch. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApi + */ + public getUserOperation(smartWalletAddress: string, userOperationId: string, options?: RawAxiosRequestConfig) { + return SmartWalletsApiFp(this.configuration).getUserOperation(smartWalletAddress, userOperationId, options).then((request) => request(this.axios, this.basePath)); + } + + /** + * List smart wallets + * @summary List smart wallets + * @param {number} [limit] A limit on the number of objects to be returned. Limit can range between 1 and 100, and the default is 10. + * @param {string} [page] A cursor for pagination across multiple pages of results. Don\'t include this parameter on the first call. Use the next_page value returned in a previous response to request subsequent results. + * @param {*} [options] Override http request option. + * @throws {RequiredError} + * @memberof SmartWalletsApi + */ + public listSmartWallets(limit?: number, page?: string, options?: RawAxiosRequestConfig) { + return SmartWalletsApiFp(this.configuration).listSmartWallets(limit, page, options).then((request) => request(this.axios, this.basePath)); + } +} + + + /** * StakeApi - axios parameter creator * @export diff --git a/src/client/configuration.ts b/src/client/configuration.ts index 1fc8a134..a1a0c93e 100644 --- a/src/client/configuration.ts +++ b/src/client/configuration.ts @@ -89,7 +89,13 @@ export class Configuration { this.accessToken = param.accessToken; this.basePath = param.basePath; this.serverIndex = param.serverIndex; - this.baseOptions = param.baseOptions; + this.baseOptions = { + headers: { + ...param.baseOptions?.headers, + 'User-Agent': "OpenAPI-Generator/typescript-axios" + }, + ...param.baseOptions + }; this.formDataCtor = param.formDataCtor; } diff --git a/src/tests/e2e.ts b/src/tests/e2e.ts index 18f32647..d258ceaa 100644 --- a/src/tests/e2e.ts +++ b/src/tests/e2e.ts @@ -151,6 +151,58 @@ describe("Coinbase SDK E2E Test", () => { }); }, 60000); + it("Should be able to invoke a contract and retrieve the transaction receipt", async() => { + const seedFile = JSON.parse(process.env.WALLET_DATA || ""); + const walletId = Object.keys(seedFile)[0]; + const seed = seedFile[walletId].seed; + + const importedWallet = await Wallet.import({ + seed, + walletId, + networkId: Coinbase.networks.BaseSepolia, + }); + + const faucetTransaction = await importedWallet.faucet(Coinbase.assets.Usdc); + await faucetTransaction.wait(); + + const secondWallet = await Wallet.create(); + const secondWalletAddress = (await secondWallet.getDefaultAddress()).getId(); + + const transferArgs = { + to: secondWalletAddress, + value: "1" + } + + const contractInvocation = await importedWallet.invokeContract({ + contractAddress: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", + method: "transfer", + args: transferArgs, + }); + + await contractInvocation.wait(); + + const transactionContent = contractInvocation.getTransaction().content(); + const receipt = transactionContent!.receipt; + + expect(receipt).toBeDefined(); + + if (!receipt?.logs) { + fail("No logs found in receipt"); + } + + const logs = receipt.logs; + + expect(logs).toBeDefined(); + expect(logs.length).toEqual(1); + + const log = logs[0]; + expect(log.address).toEqual("0x036CbD53842c5426634e7929541eC2318f3dCF7e"); + expect(log.topics?.[0]).toEqual("Transfer"); + expect(log.topics?.[1]).toEqual(`from: ${(await importedWallet.getDefaultAddress()).getId()}`); + expect(log.topics?.[2]).toEqual(`to: ${(await secondWallet.getDefaultAddress()).getId()}`); + expect(log.data).toEqual("0x0000000000000000000000000000000000000000000000000000000000000001"); + }, 60000); + it.skip("should be able to make gasless transfers", async () => { // Import wallet with balance const seedFile = JSON.parse(process.env.WALLET_DATA || ""); diff --git a/src/tests/external_address_test.ts b/src/tests/external_address_test.ts index a9175244..a2bf9a30 100644 --- a/src/tests/external_address_test.ts +++ b/src/tests/external_address_test.ts @@ -63,6 +63,15 @@ describe("ExternalAddress", () => { contract_address: "0x", }, }, + pending_claimable_balance: { + amount: "1000000000000000000", + asset: { + asset_id: Coinbase.assets.Eth, + network_id: Coinbase.networks.EthereumHolesky, + decimals: 18, + contract_address: "0x", + } + } }, }; const STAKING_OPERATION_MODEL: StakingOperationModel = { diff --git a/src/tests/utils.ts b/src/tests/utils.ts index c924383c..f76c5118 100644 --- a/src/tests/utils.ts +++ b/src/tests/utils.ts @@ -627,6 +627,7 @@ export function mockEthereumValidator( index: index, public_key: public_key, withdrawal_address: "0xwithdrawal_address_1", + fee_recipient_address: "0xfee_recipient_address_1", slashed: false, activationEpoch: "10", exitEpoch: "10", diff --git a/src/tests/validator_test.ts b/src/tests/validator_test.ts index fcb3c3d6..614f4897 100644 --- a/src/tests/validator_test.ts +++ b/src/tests/validator_test.ts @@ -18,6 +18,7 @@ describe("Validator", () => { amount: "100", asset: { network_id: Coinbase.networks.EthereumHolesky, asset_id: Coinbase.assets.Eth }, }, + fee_recipient_address: "fee-recipient-address-123", balance: { amount: "200", asset: { network_id: Coinbase.networks.EthereumHolesky, asset_id: Coinbase.assets.Eth }, diff --git a/src/tests/wallet_address_test.ts b/src/tests/wallet_address_test.ts index 474ad525..22b99195 100644 --- a/src/tests/wallet_address_test.ts +++ b/src/tests/wallet_address_test.ts @@ -397,6 +397,15 @@ describe("WalletAddress", () => { contract_address: "0x", }, }, + pending_claimable_balance: { + amount: "1000000000000000000", + asset: { + asset_id: Coinbase.assets.Eth, + network_id: Coinbase.networks.EthereumHolesky, + decimals: 18, + contract_address: "0x", + } + } }, }; diff --git a/src/tests/wallet_test.ts b/src/tests/wallet_test.ts index 1036b897..0cfa6385 100644 --- a/src/tests/wallet_test.ts +++ b/src/tests/wallet_test.ts @@ -174,6 +174,15 @@ describe("Wallet Class", () => { contract_address: "0x", }, }, + pending_claimable_balance: { + amount: "1000000000000000000", + asset: { + asset_id: Coinbase.assets.Eth, + network_id: Coinbase.networks.EthereumHolesky, + decimals: 18, + contract_address: "0x", + } + } }, };