@coinbase/agentkit
Version:
Coinbase AgentKit core primitives
304 lines (303 loc) • 12.5 kB
JavaScript
;
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();