@coinbase/agentkit
Version:
Coinbase AgentKit core primitives
459 lines (458 loc) • 21.1 kB
JavaScript
"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 _LegacyCdpWalletProvider_cdpWallet, _LegacyCdpWalletProvider_address, _LegacyCdpWalletProvider_network, _LegacyCdpWalletProvider_publicClient, _LegacyCdpWalletProvider_gasLimitMultiplier, _LegacyCdpWalletProvider_feePerGasMultiplier, _LegacyCdpWalletProvider_transactionQueue;
Object.defineProperty(exports, "__esModule", { value: true });
exports.LegacyCdpWalletProvider = void 0;
const package_json_1 = require("../../package.json");
const decimal_js_1 = require("decimal.js");
const viem_1 = require("viem");
const evmWalletProvider_1 = require("./evmWalletProvider");
const coinbase_sdk_1 = require("@coinbase/coinbase-sdk");
const network_1 = require("../network/network");
const utils_1 = require("../utils");
/**
* A legacy wallet provider that uses the old Coinbase SDK.
*
* @deprecated Use CdpEvmWalletProvider or CdpSmartWalletProvider instead
*/
class LegacyCdpWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
/**
* Constructs a new LegacyCdpWalletProvider.
*
* @param config - The configuration options for the LegacyCdpWalletProvider.
*/
constructor(config) {
super();
_LegacyCdpWalletProvider_cdpWallet.set(this, void 0);
_LegacyCdpWalletProvider_address.set(this, void 0);
_LegacyCdpWalletProvider_network.set(this, void 0);
_LegacyCdpWalletProvider_publicClient.set(this, void 0);
_LegacyCdpWalletProvider_gasLimitMultiplier.set(this, void 0);
_LegacyCdpWalletProvider_feePerGasMultiplier.set(this, void 0);
_LegacyCdpWalletProvider_transactionQueue.set(this, void 0);
__classPrivateFieldSet(this, _LegacyCdpWalletProvider_cdpWallet, config.wallet, "f");
__classPrivateFieldSet(this, _LegacyCdpWalletProvider_address, config.address, "f");
__classPrivateFieldSet(this, _LegacyCdpWalletProvider_network, config.network, "f");
const rpcUrl = config.rpcUrl || process.env.RPC_URL;
__classPrivateFieldSet(this, _LegacyCdpWalletProvider_publicClient, (0, viem_1.createPublicClient)({
chain: network_1.NETWORK_ID_TO_VIEM_CHAIN[config.network.networkId],
transport: rpcUrl ? (0, viem_1.http)(rpcUrl) : (0, viem_1.http)(),
}), "f");
__classPrivateFieldSet(this, _LegacyCdpWalletProvider_gasLimitMultiplier, Math.max(config.gas?.gasLimitMultiplier ?? 1.2, 1), "f");
__classPrivateFieldSet(this, _LegacyCdpWalletProvider_feePerGasMultiplier, Math.max(config.gas?.feePerGasMultiplier ?? 1, 1), "f");
}
/**
* Configures a new LegacyCdpWalletProvider with a wallet.
*
* @param config - Optional configuration parameters
* @returns A Promise that resolves to a new LegacyCdpWalletProvider instance
* @throws Error if required environment variables are missing or wallet initialization fails
*/
static async configureWithWallet(config = {}) {
if (config.apiKeyId && config.apiKeySecret) {
coinbase_sdk_1.Coinbase.configure({
apiKeyName: config.apiKeyId,
privateKey: config.apiKeySecret?.replace(/\\n/g, "\n"),
source: "agentkit",
sourceVersion: package_json_1.version,
});
}
else {
coinbase_sdk_1.Coinbase.configureFromJson({ source: "agentkit", sourceVersion: package_json_1.version });
}
let wallet;
const mnemonicPhrase = config.mnemonicPhrase || process.env.MNEMONIC_PHRASE;
let networkId = config.networkId || process.env.NETWORK_ID || coinbase_sdk_1.Coinbase.networks.BaseSepolia;
try {
if (config.wallet) {
wallet = config.wallet;
}
else if (config.cdpWalletData) {
const walletData = JSON.parse(config.cdpWalletData);
wallet = await coinbase_sdk_1.Wallet.import(walletData);
networkId = wallet.getNetworkId();
}
else if (mnemonicPhrase) {
wallet = await coinbase_sdk_1.Wallet.import({ mnemonicPhrase: mnemonicPhrase }, networkId);
}
else {
wallet = await coinbase_sdk_1.Wallet.create({ networkId: networkId });
}
}
catch (error) {
throw new Error(`Failed to initialize wallet: ${error}`);
}
const address = (await wallet.getDefaultAddress())?.getId();
const network = {
protocolFamily: "evm",
chainId: network_1.NETWORK_ID_TO_CHAIN_ID[networkId],
networkId: networkId,
};
const cdpWalletProvider = new LegacyCdpWalletProvider({
wallet,
address,
network,
gas: config.gas,
});
return cdpWalletProvider;
}
/**
* Signs a raw hash.
*
* @param hash - The hash to sign.
* @returns The signed hash.
*/
async sign(hash) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
const payload = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").createPayloadSignature(hash);
if (payload.getStatus() === "pending" && payload?.wait) {
await payload.wait(); // needed for Server-Signers
}
return payload.getSignature();
}
/**
* Signs a message.
*
* @param message - The message to sign.
* @returns The signed message.
*/
async signMessage(message) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
const messageHash = (0, viem_1.hashMessage)(message);
const payload = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").createPayloadSignature(messageHash);
if (payload.getStatus() === "pending" && payload?.wait) {
await payload.wait(); // needed for Server-Signers
}
return payload.getSignature();
}
/**
* Signs a typed data object.
*
* @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) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
const messageHash = (0, coinbase_sdk_1.hashTypedDataMessage)(typedData.domain, typedData.types, typedData.message);
const payload = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").createPayloadSignature(messageHash);
if (payload.getStatus() === "pending" && payload?.wait) {
await payload.wait(); // needed for Server-Signers
}
return payload.getSignature();
}
/**
* Signs a transaction.
*
* @param transaction - The transaction to sign.
* @returns The signed transaction.
*/
async signTransaction(transaction) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
const serializedTx = (0, viem_1.serializeTransaction)(transaction);
const transactionHash = (0, viem_1.keccak256)(serializedTx);
const payload = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").createPayloadSignature(transactionHash);
if (payload.getStatus() === "pending" && payload?.wait) {
await payload.wait(); // needed for Server-Signers
}
return payload.getSignature();
}
/**
* Sends a transaction.
*
* @param transaction - The transaction to send.
* @returns The hash of the transaction.
*/
async sendTransaction(transaction) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
const sendPromise = (async () => {
if (__classPrivateFieldGet(this, _LegacyCdpWalletProvider_transactionQueue, "f"))
await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_transactionQueue, "f");
const preparedTransaction = await this.prepareTransaction(transaction.to, transaction.value, transaction.data);
const signature = await this.signTransaction({
...preparedTransaction,
});
const signedPayload = await this.addSignatureAndSerialize(preparedTransaction, signature);
const externalAddress = new coinbase_sdk_1.ExternalAddress(__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").getNetworkId(), __classPrivateFieldGet(this, _LegacyCdpWalletProvider_address, "f"));
const tx = await externalAddress.broadcastExternalTransaction(signedPayload.slice(2));
return tx.transactionHash;
})();
__classPrivateFieldSet(this, _LegacyCdpWalletProvider_transactionQueue, sendPromise
.then(txHash => this.waitForTransactionReceipt(txHash))
.catch(() => { }), "f");
return await sendPromise;
}
/**
* Prepares a transaction.
*
* @param to - The address to send the transaction to.
* @param value - The value of the transaction.
* @param data - The data of the transaction.
* @returns The prepared transaction.
*/
async prepareTransaction(to, value, data) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
const nonce = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_publicClient, "f").getTransactionCount({
address: __classPrivateFieldGet(this, _LegacyCdpWalletProvider_address, "f"),
blockTag: "pending",
});
const feeData = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_publicClient, "f").estimateFeesPerGas();
const maxFeePerGas = (0, utils_1.applyGasMultiplier)(feeData.maxFeePerGas, __classPrivateFieldGet(this, _LegacyCdpWalletProvider_feePerGasMultiplier, "f"));
const maxPriorityFeePerGas = (0, utils_1.applyGasMultiplier)(feeData.maxPriorityFeePerGas, __classPrivateFieldGet(this, _LegacyCdpWalletProvider_feePerGasMultiplier, "f"));
const gasLimit = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_publicClient, "f").estimateGas({
account: __classPrivateFieldGet(this, _LegacyCdpWalletProvider_address, "f"),
to,
value,
data,
});
const gas = BigInt(Math.round(Number(gasLimit) * __classPrivateFieldGet(this, _LegacyCdpWalletProvider_gasLimitMultiplier, "f")));
const chainId = parseInt(__classPrivateFieldGet(this, _LegacyCdpWalletProvider_network, "f").chainId, 10);
return {
to,
value,
data,
nonce,
maxFeePerGas,
maxPriorityFeePerGas,
gas,
chainId,
type: "eip1559",
};
}
/**
* Adds signature to a transaction and serializes it for broadcast.
*
* @param transaction - The transaction to sign.
* @param signature - The signature to add to the transaction.
* @returns A serialized transaction.
*/
async addSignatureAndSerialize(transaction, signature) {
// Decode the signature into its components
const r = `0x${signature.slice(2, 66)}`; // First 32 bytes
const s = `0x${signature.slice(66, 130)}`; // Next 32 bytes
const v = BigInt(parseInt(signature.slice(130, 132), 16)); // Last byte
return (0, viem_1.serializeTransaction)(transaction, { r, s, v });
}
/**
* Gets the address of the wallet.
*
* @returns The address of the wallet.
*/
getAddress() {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_address, "f")) {
throw new Error("Address not initialized");
}
return __classPrivateFieldGet(this, _LegacyCdpWalletProvider_address, "f");
}
/**
* Gets the network of the wallet.
*
* @returns The network of the wallet.
*/
getNetwork() {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_network, "f")) {
throw new Error("Network not initialized");
}
return __classPrivateFieldGet(this, _LegacyCdpWalletProvider_network, "f");
}
/**
* Gets the name of the wallet provider.
*
* @returns The name of the wallet provider.
*/
getName() {
return "legacy_cdp_wallet_provider";
}
/**
* Gets the Viem PublicClient used for read-only operations.
*
* @returns The Viem PublicClient instance used for read-only operations.
*/
getPublicClient() {
return __classPrivateFieldGet(this, _LegacyCdpWalletProvider_publicClient, "f");
}
/**
* Gets the balance of the wallet.
*
* @returns The balance of the wallet in wei
*/
async getBalance() {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
const balance = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").getBalance("eth");
return BigInt(balance.mul(10 ** 18).toString());
}
/**
* 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
async waitForTransactionReceipt(txHash) {
return await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_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, _LegacyCdpWalletProvider_publicClient, "f").readContract(params);
}
/**
* Creates a trade.
*
* @param options - The options for the trade.
* @returns The trade.
*/
async createTrade(options) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
return __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").createTrade(options);
}
/**
* Deploys a token.
*
* @param options - The options for the token deployment.
* @returns The deployed token.
*/
async deployToken(options) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
return __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").deployToken(options);
}
/**
* Deploys a contract.
*
* @param options - The options for contract deployment
* @param options.solidityVersion - The version of the Solidity compiler to use (e.g. "0.8.0+commit.c7dfd78e")
* @param options.solidityInputJson - The JSON input for the Solidity compiler containing contract source and settings
* @param options.contractName - The name of the contract to deploy
* @param options.constructorArgs - Key-value map of constructor args
*
* @returns A Promise that resolves to the deployed contract instance
* @throws Error if wallet is not initialized
*/
async deployContract(options) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
return __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").deployContract(options);
}
/**
* Deploys a new NFT (ERC-721) smart contract.
*
* @param options - Configuration options for the NFT contract deployment
* @param options.name - The name of the collection
* @param options.symbol - The token symbol for the collection
* @param options.baseURI - The base URI for token metadata.
*
* @returns A Promise that resolves to the deployed SmartContract instance
* @throws Error if the wallet is not properly initialized
* @throws Error if the deployment fails for any reason (network issues, insufficient funds, etc.)
*/
async deployNFT(options) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
return __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").deployNFT(options);
}
/**
* Transfer the native asset of the network.
*
* @param to - The destination address.
* @param value - The amount to transfer in atomic units (Wei).
* @returns The transaction hash.
*/
async nativeTransfer(to, value) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
const transferResult = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").createTransfer({
amount: new decimal_js_1.Decimal(value),
assetId: coinbase_sdk_1.Coinbase.assets.Eth,
destination: to,
gasless: false,
});
const result = await transferResult.wait();
if (!result.getTransactionHash()) {
throw new Error("Transaction hash not found");
}
return result.getTransactionHash();
}
/**
* Exports the wallet.
*
* @returns The wallet's data.
*/
async exportWallet() {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
return __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").export();
}
/**
* Gets the wallet.
*
* @returns The wallet.
*/
getWallet() {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
return __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f");
}
/**
* ERC20 transfer method
*
* @param assetId - The asset ID to transfer. Either USDC, CBBTC or EURC
* @param destination - The destination address
* @param amount - The amount to transfer
* @returns The transaction hash
*/
async gaslessERC20Transfer(assetId, destination, amount) {
if (!__classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f")) {
throw new Error("Wallet not initialized");
}
const transferResult = await __classPrivateFieldGet(this, _LegacyCdpWalletProvider_cdpWallet, "f").createTransfer({
amount,
assetId,
destination,
gasless: true,
});
const result = await transferResult.wait();
if (!result.getTransactionHash()) {
throw new Error("Transaction hash not found");
}
return result.getTransactionHash();
}
}
exports.LegacyCdpWalletProvider = LegacyCdpWalletProvider;
_LegacyCdpWalletProvider_cdpWallet = new WeakMap(), _LegacyCdpWalletProvider_address = new WeakMap(), _LegacyCdpWalletProvider_network = new WeakMap(), _LegacyCdpWalletProvider_publicClient = new WeakMap(), _LegacyCdpWalletProvider_gasLimitMultiplier = new WeakMap(), _LegacyCdpWalletProvider_feePerGasMultiplier = new WeakMap(), _LegacyCdpWalletProvider_transactionQueue = new WeakMap();