UNPKG

@coinbase/agentkit

Version:

Coinbase AgentKit core primitives

259 lines (258 loc) 11.2 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 _CdpSolanaWalletProvider_connection, _CdpSolanaWalletProvider_serverAccount, _CdpSolanaWalletProvider_cdp, _CdpSolanaWalletProvider_network; Object.defineProperty(exports, "__esModule", { value: true }); exports.CdpSolanaWalletProvider = void 0; const cdp_sdk_1 = require("@coinbase/cdp-sdk"); const web3_js_1 = require("@solana/web3.js"); const svm_1 = require("../network/svm"); const svmWalletProvider_1 = require("./svmWalletProvider"); /** * A wallet provider that uses the Coinbase SDK. */ class CdpSolanaWalletProvider extends svmWalletProvider_1.SvmWalletProvider { /** * Constructs a new CdpSolanaWalletProvider. * * @param config - The configuration options for the CdpSolanaWalletProvider. */ constructor(config) { super(); _CdpSolanaWalletProvider_connection.set(this, void 0); _CdpSolanaWalletProvider_serverAccount.set(this, void 0); _CdpSolanaWalletProvider_cdp.set(this, void 0); _CdpSolanaWalletProvider_network.set(this, void 0); __classPrivateFieldSet(this, _CdpSolanaWalletProvider_serverAccount, config.serverAccount, "f"); __classPrivateFieldSet(this, _CdpSolanaWalletProvider_cdp, config.cdp, "f"); __classPrivateFieldSet(this, _CdpSolanaWalletProvider_connection, config.connection, "f"); __classPrivateFieldSet(this, _CdpSolanaWalletProvider_network, config.network, "f"); } /** * Configures a new CdpSolanaWalletProvider with a wallet. * * @param config - Optional configuration parameters * @returns A Promise that resolves to a new CdpSolanaWalletProvider 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; 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 || "solana-devnet"; let network; let rpcUrl; switch (networkId) { case svm_1.SOLANA_MAINNET_NETWORK_ID: network = svm_1.SOLANA_MAINNET_NETWORK; rpcUrl = (0, web3_js_1.clusterApiUrl)("mainnet-beta"); break; case svm_1.SOLANA_DEVNET_NETWORK_ID: network = svm_1.SOLANA_DEVNET_NETWORK; rpcUrl = (0, web3_js_1.clusterApiUrl)("devnet"); break; case svm_1.SOLANA_TESTNET_NETWORK_ID: network = svm_1.SOLANA_TESTNET_NETWORK; rpcUrl = (0, web3_js_1.clusterApiUrl)("testnet"); break; default: throw new Error(`${networkId} is not a valid SVM networkId`); } const cdpClient = new cdp_sdk_1.CdpClient({ apiKeyId, apiKeySecret, walletSecret, }); const connection = new web3_js_1.Connection(rpcUrl); const serverAccount = await (config.address ? cdpClient.solana.getAccount({ address: config.address }) : cdpClient.solana.createAccount({ idempotencyKey })); return new CdpSolanaWalletProvider({ connection, cdp: cdpClient, serverAccount, network, }); } /** * Exports the wallet. * * @returns The wallet's data. */ async exportWallet() { return { name: __classPrivateFieldGet(this, _CdpSolanaWalletProvider_serverAccount, "f").name, address: __classPrivateFieldGet(this, _CdpSolanaWalletProvider_serverAccount, "f").address, }; } /** * Get the connection instance * * @returns The Solana connection instance */ getConnection() { return __classPrivateFieldGet(this, _CdpSolanaWalletProvider_connection, "f"); } /** * Get the public key of the wallet * * @returns The wallet's public key */ getPublicKey() { return new web3_js_1.PublicKey(__classPrivateFieldGet(this, _CdpSolanaWalletProvider_serverAccount, "f").address); } /** * Get the address of the wallet * * @returns The base58 encoded address of the wallet */ getAddress() { return __classPrivateFieldGet(this, _CdpSolanaWalletProvider_serverAccount, "f").address; } /** * Get the network * * @returns The network */ getNetwork() { return __classPrivateFieldGet(this, _CdpSolanaWalletProvider_network, "f"); } /** * Gets the name of the wallet provider. * * @returns The name of the wallet provider. */ getName() { return "cdp_solana_wallet_provider"; } /** * Sign a transaction * * @param transaction - The transaction to sign * @returns The signed transaction */ async signTransaction(transaction) { const serializedTransaction = transaction.serialize(); const encodedSerializedTransaction = Buffer.from(serializedTransaction).toString("base64"); const signedTransaction = await __classPrivateFieldGet(this, _CdpSolanaWalletProvider_cdp, "f").solana.signTransaction({ transaction: encodedSerializedTransaction, address: __classPrivateFieldGet(this, _CdpSolanaWalletProvider_serverAccount, "f").address, }); transaction.addSignature(this.getPublicKey(), Buffer.from(signedTransaction.signature, "base64")); return transaction; } /** * Send a transaction * * @param transaction - The transaction to send * @returns The signature */ async sendTransaction(transaction) { const signature = await __classPrivateFieldGet(this, _CdpSolanaWalletProvider_connection, "f").sendTransaction(transaction); await this.waitForSignatureResult(signature); return signature; } /** * Sign and send a transaction * * @param transaction - The transaction to sign and send * @returns The signature */ async signAndSendTransaction(transaction) { const signedTransaction = await this.signTransaction(transaction); return this.sendTransaction(signedTransaction); } /** * Get the status of a transaction * * @param signature - The signature * @param options - The options for the status * @returns The status */ async getSignatureStatus(signature, options) { return __classPrivateFieldGet(this, _CdpSolanaWalletProvider_connection, "f").getSignatureStatus(signature, options); } /** * Wait for signature receipt * * @param signature - The signature * @returns The confirmation response */ async waitForSignatureResult(signature) { const { blockhash, lastValidBlockHeight } = await __classPrivateFieldGet(this, _CdpSolanaWalletProvider_connection, "f").getLatestBlockhash(); return __classPrivateFieldGet(this, _CdpSolanaWalletProvider_connection, "f").confirmTransaction({ signature: signature, lastValidBlockHeight, blockhash, }); } /** * Get the balance of the wallet * * @returns The balance of the wallet */ getBalance() { return __classPrivateFieldGet(this, _CdpSolanaWalletProvider_connection, "f").getBalance(this.getPublicKey()).then(balance => BigInt(balance)); } /** * Gets the CDP client. * * @returns The CDP client. */ getClient() { return __classPrivateFieldGet(this, _CdpSolanaWalletProvider_cdp, "f"); } /** * Transfer SOL from the wallet to another address * * @param to - The base58 encoded address to transfer the SOL to * @param value - The amount of SOL to transfer (as a decimal string, e.g. "0.0001") * @returns The signature */ async nativeTransfer(to, value) { const initialBalance = await this.getBalance(); const solAmount = parseFloat(value); const lamports = BigInt(Math.floor(solAmount * web3_js_1.LAMPORTS_PER_SOL)); // Check if we have enough balance (including estimated fees) if (initialBalance < lamports + BigInt(5000)) { throw new Error(`Insufficient balance. Have ${Number(initialBalance) / web3_js_1.LAMPORTS_PER_SOL} SOL, need ${solAmount + 0.000005} SOL (including fees)`); } const toPubkey = new web3_js_1.PublicKey(to); const instructions = [ web3_js_1.ComputeBudgetProgram.setComputeUnitPrice({ microLamports: 10000, }), web3_js_1.ComputeBudgetProgram.setComputeUnitLimit({ units: 2000, }), web3_js_1.SystemProgram.transfer({ fromPubkey: this.getPublicKey(), toPubkey: toPubkey, lamports: lamports, }), ]; const tx = new web3_js_1.VersionedTransaction(web3_js_1.MessageV0.compile({ payerKey: this.getPublicKey(), instructions: instructions, recentBlockhash: (await __classPrivateFieldGet(this, _CdpSolanaWalletProvider_connection, "f").getLatestBlockhash()).blockhash, })); const signature = await this.signAndSendTransaction(tx); await this.waitForSignatureResult(signature); return signature; } } exports.CdpSolanaWalletProvider = CdpSolanaWalletProvider; _CdpSolanaWalletProvider_connection = new WeakMap(), _CdpSolanaWalletProvider_serverAccount = new WeakMap(), _CdpSolanaWalletProvider_cdp = new WeakMap(), _CdpSolanaWalletProvider_network = new WeakMap();