UNPKG

@coinbase/agentkit

Version:

Coinbase AgentKit core primitives

304 lines (303 loc) 12.5 kB
"use strict"; var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _LegacyCdpSmartWalletProvider_smartWallet, _LegacyCdpSmartWalletProvider_network, _LegacyCdpSmartWalletProvider_publicClient; Object.defineProperty(exports, "__esModule", { value: true }); exports.LegacyCdpSmartWalletProvider = void 0; const coinbase_sdk_1 = require("@coinbase/coinbase-sdk"); const viem_1 = require("viem"); const network_1 = require("../network"); const evmWalletProvider_1 = require("./evmWalletProvider"); const package_json_1 = require("../../package.json"); /** * A wallet provider that uses Smart Wallets from the Coinbase SDK. */ class LegacyCdpSmartWalletProvider extends evmWalletProvider_1.EvmWalletProvider { /** * Constructs a new CdpWalletProvider. * * @param config - The configuration options for the CdpWalletProvider. */ constructor(config) { super(); _LegacyCdpSmartWalletProvider_smartWallet.set(this, void 0); _LegacyCdpSmartWalletProvider_network.set(this, void 0); _LegacyCdpSmartWalletProvider_publicClient.set(this, void 0); __classPrivateFieldSet(this, _LegacyCdpSmartWalletProvider_network, config.network, "f"); __classPrivateFieldSet(this, _LegacyCdpSmartWalletProvider_smartWallet, config.smartWallet, "f"); __classPrivateFieldSet(this, _LegacyCdpSmartWalletProvider_publicClient, (0, viem_1.createPublicClient)({ chain: network_1.NETWORK_ID_TO_VIEM_CHAIN[config.network.networkId], transport: (0, viem_1.http)(), }), "f"); } /** * Configures and returns a `SmartWalletProvider` instance using the provided configuration options. * This method initializes a smart wallet based on the given network and credentials. * * @param {ConfigureSmartWalletOptions} config * - Configuration parameters for setting up the smart wallet. * * @returns {Promise<SmartWalletProvider>} * - A promise that resolves to an instance of `SmartWalletProvider` configured with the provided settings. * * @throws {Error} * - If networkId is not a supported network. * * @example * ```typescript * const smartWalletProvider = await SmartWalletProvider.configureWithWallet({ * networkId: "base-sepolia", * signer: privateKeyToAccount("0xethprivatekey"), * cdpApiKeyId: "my-api-key", * cdpApiKeySecret: "my-private-key", * smartWalletAddress: "0x123456...", * }); * ``` */ static async configureWithWallet(config) { const networkId = config.networkId || process.env.NETWORK_ID || coinbase_sdk_1.Coinbase.networks.BaseSepolia; const network = { protocolFamily: "evm", chainId: network_1.NETWORK_ID_TO_CHAIN_ID[networkId], networkId, }; if (!network.chainId) { throw new Error(`Unable to determine chainId for network ${networkId}`); } const supportedChainIds = Object.keys(coinbase_sdk_1.CHAIN_ID_TO_NETWORK_ID); if (!supportedChainIds.includes(network.chainId)) { throw new Error(`Invalid chain id ${network.chainId}. Chain id must be one of ${supportedChainIds.join(", ")}`); } const cdpApiKeyId = config.cdpApiKeyId || process.env.CDP_API_KEY_ID; const cdpApiKeySecret = config.cdpApiKeySecret || process.env.CDP_API_KEY_SECRET; if (cdpApiKeyId && cdpApiKeySecret) { coinbase_sdk_1.Coinbase.configure({ apiKeyName: cdpApiKeyId, privateKey: cdpApiKeySecret?.replace(/\\n/g, "\n"), source: "agentkit", sourceVersion: package_json_1.version, }); } else { coinbase_sdk_1.Coinbase.configureFromJson({ source: "agentkit", sourceVersion: package_json_1.version }); } const smartWallet = config.smartWalletAddress ? (0, coinbase_sdk_1.toSmartWallet)({ signer: config.signer, smartWalletAddress: config.smartWalletAddress, }) : await (0, coinbase_sdk_1.createSmartWallet)({ signer: config.signer, }); const networkScopedSmartWallet = smartWallet.useNetwork({ chainId: Number(network.chainId), paymasterUrl: config.paymasterUrl, }); const legacyCdpSmartWalletProvider = new LegacyCdpSmartWalletProvider({ smartWallet: networkScopedSmartWallet, network, chainId: network.chainId, }); return legacyCdpSmartWalletProvider; } /** * Stub for message signing * * @throws as signing messages is not implemented for SmartWallets. * * @param _ - The message to sign. * @returns The signed message. */ async signMessage(_) { throw new Error("Not implemented"); } /** * Stub for typed data signing * * @throws as signing typed data is not implemented for SmartWallets. * * @param _ - The typed data object to sign. * @returns The signed typed data object. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any async signTypedData(_) { throw new Error("Not implemented"); } /** * Stub for transaction signing * * @throws as signing transactions is not implemented for SmartWallets. * * @param _ - The transaction to sign. * @returns The signed transaction. */ async signTransaction(_) { throw new Error("Not implemented"); } /** * Sends a transaction using the smart wallet. * * Unlike traditional Ethereum transactions, this method submits a **User Operation** * instead of directly broadcasting a transaction. The smart wallet handles execution, * but a standard transaction hash is still returned upon completion. * * @param {TransactionRequest} transaction - The transaction details, including: * - `to`: The recipient address. * - `value`: The amount of ETH (or native token) to send. * - `data`: Optional calldata for contract interactions. * * @returns A promise resolving to the transaction hash (`0x...`). * * @throws {Error} If the transaction does not complete successfully. * * @example * ```typescript * const txHash = await smartWallet.sendTransaction({ * to: "0x123...", * value: parseEther("0.1"), * data: "0x", * }); * console.log(`Transaction sent: ${txHash}`); * ``` */ sendTransaction(transaction) { const { to, value, data } = transaction; return this.sendUserOperation({ calls: [ { to: to, value, data, }, ], }); } /** * Sends a **User Operation** to the smart wallet. * * This method directly exposes the **sendUserOperation** functionality, allowing * **SmartWallet-aware tools** to fully leverage its capabilities, including batching multiple calls. * Unlike `sendTransaction`, which wraps calls in a single operation, this method allows * direct execution of arbitrary operations within a **User Operation**. * * @param {Omit<SendUserOperationOptions<T>, "chainId" | "paymasterUrl">} operation * - The user operation configuration, omitting `chainId` and `paymasterUrl`, * which are managed internally by the smart wallet. * * @returns A promise resolving to the transaction hash (`0x...`) if the operation completes successfully. * * @throws {Error} If the operation does not complete successfully. * * @example * ```typescript * const txHash = await smartWallet.sendUserOperation({ * calls: [ * { to: "0x123...", value: parseEther("0.1"), data: "0x" }, * { to: "0x456...", value: parseEther("0.05"), data: "0x" } * ], * }); * console.log(`User Operation sent: ${txHash}`); * ``` */ async sendUserOperation(operation) { const sendUserOperationResult = await __classPrivateFieldGet(this, _LegacyCdpSmartWalletProvider_smartWallet, "f").sendUserOperation(operation); const result = await (0, coinbase_sdk_1.waitForUserOperation)(sendUserOperationResult); if (result.status === "complete") { return result.transactionHash; } else { throw new Error(`Transaction failed with status ${result.status}`); } } /** * Gets the address of the smart wallet. * * @returns The address of the smart wallet. */ getAddress() { return __classPrivateFieldGet(this, _LegacyCdpSmartWalletProvider_smartWallet, "f").address; } /** * Gets the network of the wallet. * * @returns The network of the wallet. */ getNetwork() { return __classPrivateFieldGet(this, _LegacyCdpSmartWalletProvider_network, "f"); } /** * Gets the name of the wallet provider. * * @returns The name of the wallet provider. */ getName() { return "legacy_cdp_smart_wallet_provider"; } /** * Gets the balance of the wallet. * * @returns The balance of the wallet in wei */ async getBalance() { const balance = await __classPrivateFieldGet(this, _LegacyCdpSmartWalletProvider_publicClient, "f").getBalance({ address: this.getAddress(), }); return balance; } /** * Waits for a transaction receipt. * * @param txHash - The hash of the transaction to wait for. * @returns The transaction receipt. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any waitForTransactionReceipt(txHash) { return __classPrivateFieldGet(this, _LegacyCdpSmartWalletProvider_publicClient, "f").waitForTransactionReceipt({ hash: txHash, }); } /** * Reads a contract. * * @param params - The parameters to read the contract. * @returns The response from the contract. */ async readContract(params) { return __classPrivateFieldGet(this, _LegacyCdpSmartWalletProvider_publicClient, "f").readContract(params); } /** * Transfer the native asset of the network. * * @param to - The destination address. * @param value - The amount to transfer in Wei. * @returns The transaction hash. */ async nativeTransfer(to, value) { const sendUserOperationResult = await __classPrivateFieldGet(this, _LegacyCdpSmartWalletProvider_smartWallet, "f").sendUserOperation({ calls: [ { to, value: BigInt(value), }, ], }); const result = await (0, coinbase_sdk_1.waitForUserOperation)(sendUserOperationResult); if (result.status === "complete") { return result.transactionHash; } else { throw new Error(`Transfer failed with status ${result.status}`); } } } exports.LegacyCdpSmartWalletProvider = LegacyCdpSmartWalletProvider; _LegacyCdpSmartWalletProvider_smartWallet = new WeakMap(), _LegacyCdpSmartWalletProvider_network = new WeakMap(), _LegacyCdpSmartWalletProvider_publicClient = new WeakMap();