UNPKG

@coinbase/agentkit

Version:

Coinbase AgentKit core primitives

315 lines (314 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 _CdpSmartWalletProvider_publicClient, _CdpSmartWalletProvider_cdp, _CdpSmartWalletProvider_network, _CdpSmartWalletProvider_paymasterUrl; Object.defineProperty(exports, "__esModule", { value: true }); exports.CdpSmartWalletProvider = void 0; const cdp_sdk_1 = require("@coinbase/cdp-sdk"); const viem_1 = require("viem"); const network_1 = require("../network"); const evmWalletProvider_1 = require("./evmWalletProvider"); /** * A wallet provider that uses the Coinbase CDP SDK smart wallets. */ class CdpSmartWalletProvider extends evmWalletProvider_1.EvmWalletProvider { /** * Constructs a new CdpSmartWalletProvider. * * @param config - The configuration options for the CdpSmartWalletProvider. */ constructor(config) { super(); _CdpSmartWalletProvider_publicClient.set(this, void 0); _CdpSmartWalletProvider_cdp.set(this, void 0); _CdpSmartWalletProvider_network.set(this, void 0); _CdpSmartWalletProvider_paymasterUrl.set(this, void 0); this.smartAccount = config.smartAccount; this.ownerAccount = config.ownerAccount; __classPrivateFieldSet(this, _CdpSmartWalletProvider_cdp, config.cdp, "f"); __classPrivateFieldSet(this, _CdpSmartWalletProvider_publicClient, config.publicClient, "f"); __classPrivateFieldSet(this, _CdpSmartWalletProvider_network, config.network, "f"); __classPrivateFieldSet(this, _CdpSmartWalletProvider_paymasterUrl, config.paymasterUrl, "f"); } /** * Configures a new CdpSmartWalletProvider with a smart wallet. * * @param config - Optional configuration parameters * @returns A Promise that resolves to a new CdpSmartWalletProvider instance * @throws Error if required environment variables are missing or wallet initialization fails */ static async configureWithWallet(config = {}) { const apiKeyId = config.apiKeyId || process.env.CDP_API_KEY_ID; const apiKeySecret = config.apiKeySecret || process.env.CDP_API_KEY_SECRET; const walletSecret = config.walletSecret || process.env.CDP_WALLET_SECRET; const idempotencyKey = config.idempotencyKey || process.env.IDEMPOTENCY_KEY; const paymasterUrl = config.paymasterUrl || process.env.PAYMASTER_URL; if (!apiKeyId || !apiKeySecret || !walletSecret) { throw new Error("Missing required environment variables. CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET are required."); } const networkId = config.networkId || process.env.NETWORK_ID || "base-sepolia"; const network = { protocolFamily: "evm", chainId: network_1.NETWORK_ID_TO_CHAIN_ID[networkId], networkId: networkId, }; const cdpClient = new cdp_sdk_1.CdpClient({ apiKeyId, apiKeySecret, walletSecret, }); // Create or get the owner account const ownerAccount = await (() => { if (typeof config.owner === "string") { return cdpClient.evm.getAccount({ address: config.owner }); } if (typeof config.owner === "object") { return config.owner; } return cdpClient.evm.createAccount({ idempotencyKey }); })(); // Create or get the smart account const smartAccount = await (config.address || config.smartAccountName ? cdpClient.evm.getSmartAccount({ address: config.address, name: config.smartAccountName, owner: ownerAccount, }) : cdpClient.evm.createSmartAccount({ owner: ownerAccount, })); const rpcUrl = config.rpcUrl || process.env.RPC_URL; const publicClient = (0, viem_1.createPublicClient)({ chain: network_1.NETWORK_ID_TO_VIEM_CHAIN[networkId], transport: rpcUrl ? (0, viem_1.http)(rpcUrl) : (0, viem_1.http)(), }); return new CdpSmartWalletProvider({ publicClient, cdp: cdpClient, smartAccount, ownerAccount, network, paymasterUrl, }); } /** * Exports the wallet. * * @returns The wallet's data. */ async exportWallet() { return { name: this.smartAccount.name, address: this.smartAccount.address, ownerAddress: this.ownerAccount.address, }; } /** * Signs a raw hash using the owner account. * * @param _hash - The hash to sign. * @returns The signed hash. */ async sign(_hash) { if (!this.ownerAccount.sign) { throw new Error("Owner account does not support raw hash signing"); } return this.ownerAccount.sign({ hash: _hash }); } /** * Signs a message using the owner account. * * @param _message - The message to sign. * @returns The signed message. */ async signMessage(_message) { return this.ownerAccount.signMessage({ message: _message }); } /** * Signs a typed data object using the owner account. * * @param typedData - The typed data object to sign. * @returns The signed typed data object. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any async signTypedData(typedData) { const { domain, types, primaryType, message } = typedData; return await this.smartAccount.signTypedData({ domain, types, primaryType, message, network: this.getCdpSdkNetwork(), }); } /** * Signs a transaction using the owner account. * * @param _ - The transaction to sign. * @returns The signed transaction. */ async signTransaction(_) { throw new Error("Direct transaction signing not supported for smart wallets. Use sendTransaction instead."); } /** * Sends a user operation through the smart wallet. * * @param transaction - The transaction to send. * @returns The user operation hash. */ async sendTransaction(transaction) { const calls = [ { to: transaction.to, value: transaction.value ? BigInt(transaction.value.toString()) : 0n, data: transaction.data || "0x", }, ]; const userOperation = await __classPrivateFieldGet(this, _CdpSmartWalletProvider_cdp, "f").evm.sendUserOperation({ smartAccount: this.smartAccount, network: this.getCdpSdkNetwork(), calls, paymasterUrl: __classPrivateFieldGet(this, _CdpSmartWalletProvider_paymasterUrl, "f"), }); return userOperation.userOpHash; } /** * Gets the address of the smart wallet. * * @returns The address of the smart wallet. */ getAddress() { return this.smartAccount.address; } /** * Gets the network of the wallet. * * @returns The network of the wallet. */ getNetwork() { return __classPrivateFieldGet(this, _CdpSmartWalletProvider_network, "f"); } /** * Gets the name of the wallet provider. * * @returns The name of the wallet provider. */ getName() { return "cdp_smart_wallet_provider"; } /** * Gets the CDP client. * * @returns The CDP client. */ getClient() { return __classPrivateFieldGet(this, _CdpSmartWalletProvider_cdp, "f"); } /** * Gets the paymaster URL for gasless transactions. * * @returns The paymaster URL if configured, undefined otherwise. */ getPaymasterUrl() { return __classPrivateFieldGet(this, _CdpSmartWalletProvider_paymasterUrl, "f"); } /** * Gets the Viem PublicClient used for read-only operations. * * @returns The Viem PublicClient instance used for read-only operations. */ getPublicClient() { return __classPrivateFieldGet(this, _CdpSmartWalletProvider_publicClient, "f"); } /** * Gets the balance of the smart wallet. * * @returns The balance of the wallet in wei */ async getBalance() { return await __classPrivateFieldGet(this, _CdpSmartWalletProvider_publicClient, "f").getBalance({ address: this.smartAccount.address }); } /** * Waits for a user operation receipt. * * @param userOpHash - The user operation hash to wait for. * @returns The user operation receipt. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any async waitForTransactionReceipt(userOpHash) { // For smart wallets, we need to wait for the user operation to be confirmed const receipt = await __classPrivateFieldGet(this, _CdpSmartWalletProvider_cdp, "f").evm.waitForUserOperation({ smartAccountAddress: this.smartAccount.address, userOpHash, }); // Append transaction logs if available if (receipt.status === "complete") { const receiptTx = await __classPrivateFieldGet(this, _CdpSmartWalletProvider_publicClient, "f").waitForTransactionReceipt({ hash: receipt.transactionHash, }); if (receiptTx.logs) return { ...receipt, logs: receiptTx.logs }; } return receipt; } /** * Reads a contract. * * @param params - The parameters to read the contract. * @returns The response from the contract. */ async readContract(params) { return __classPrivateFieldGet(this, _CdpSmartWalletProvider_publicClient, "f").readContract(params); } /** * Transfer the native asset of the network using smart wallet. * * @param to - The destination address. * @param value - The amount to transfer in atomic units (Wei). * @returns The user operation hash. */ async nativeTransfer(to, value) { return this.sendTransaction({ to: to, value: BigInt(value), data: "0x", }); } /** * Converts the internal network ID to the format expected by the CDP SDK. * * @returns The network ID in CDP SDK format * @throws Error if the network is not supported */ getCdpSdkNetwork() { switch (__classPrivateFieldGet(this, _CdpSmartWalletProvider_network, "f").networkId) { case "base-sepolia": return "base-sepolia"; case "base-mainnet": return "base"; case "ethereum-mainnet": return "ethereum"; case "ethereum-sepolia": return "ethereum-sepolia"; case "polygon-mainnet": return "polygon"; case "arbitrum-mainnet": return "arbitrum"; case "optimism-mainnet": return "optimism"; default: throw new Error(`Unsupported network for smart wallets: ${__classPrivateFieldGet(this, _CdpSmartWalletProvider_network, "f").networkId}`); } } } exports.CdpSmartWalletProvider = CdpSmartWalletProvider; _CdpSmartWalletProvider_publicClient = new WeakMap(), _CdpSmartWalletProvider_cdp = new WeakMap(), _CdpSmartWalletProvider_network = new WeakMap(), _CdpSmartWalletProvider_paymasterUrl = new WeakMap();