@coinbase/agentkit
Version:
Coinbase AgentKit core primitives
302 lines (301 loc) • 13.3 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 _ZeroDevWalletProvider_signer, _ZeroDevWalletProvider_projectId, _ZeroDevWalletProvider_network, _ZeroDevWalletProvider_address, _ZeroDevWalletProvider_publicClient, _ZeroDevWalletProvider_kernelAccount, _ZeroDevWalletProvider_intentClient;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZeroDevWalletProvider = void 0;
const sdk_1 = require("@zerodev/sdk");
const constants_1 = require("@zerodev/sdk/constants");
const ecdsa_validator_1 = require("@zerodev/ecdsa-validator");
const intent_1 = require("@zerodev/intent");
const viem_1 = require("viem");
const evmWalletProvider_1 = require("./evmWalletProvider");
const network_1 = require("../network");
/**
* A wallet provider that uses ZeroDev's account abstraction.
*/
class ZeroDevWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
/**
* Constructs a new ZeroDevWalletProvider.
*
* @param config - The configuration options for the ZeroDevWalletProvider.
* @param kernelAccount - The kernel account.
* @param intentClient - The intent client.
*/
constructor(config, kernelAccount, intentClient) {
super();
_ZeroDevWalletProvider_signer.set(this, void 0);
_ZeroDevWalletProvider_projectId.set(this, void 0);
_ZeroDevWalletProvider_network.set(this, void 0);
_ZeroDevWalletProvider_address.set(this, void 0);
_ZeroDevWalletProvider_publicClient.set(this, void 0);
_ZeroDevWalletProvider_kernelAccount.set(this, void 0);
_ZeroDevWalletProvider_intentClient.set(this, void 0);
__classPrivateFieldSet(this, _ZeroDevWalletProvider_signer, config.signer, "f");
__classPrivateFieldSet(this, _ZeroDevWalletProvider_projectId, config.projectId, "f");
__classPrivateFieldSet(this, _ZeroDevWalletProvider_network, {
protocolFamily: "evm",
networkId: config.networkId,
chainId: network_1.NETWORK_ID_TO_VIEM_CHAIN[config.networkId].id.toString(),
}, "f");
__classPrivateFieldSet(this, _ZeroDevWalletProvider_address, kernelAccount.address, "f");
__classPrivateFieldSet(this, _ZeroDevWalletProvider_kernelAccount, kernelAccount, "f");
__classPrivateFieldSet(this, _ZeroDevWalletProvider_intentClient, intentClient, "f");
// Create public client
__classPrivateFieldSet(this, _ZeroDevWalletProvider_publicClient, (0, viem_1.createPublicClient)({
chain: network_1.NETWORK_ID_TO_VIEM_CHAIN[__classPrivateFieldGet(this, _ZeroDevWalletProvider_network, "f").networkId],
transport: (0, viem_1.http)(),
}), "f");
}
/**
* Configures a new ZeroDevWalletProvider with an existing wallet provider as the signer.
*
* @param config - The configuration options for the ZeroDevWalletProvider.
* @returns A Promise that resolves to a new ZeroDevWalletProvider instance.
*/
static async configureWithWallet(config) {
if (!config.signer) {
throw new Error("Signer is required");
}
if (!config.projectId) {
throw new Error("ZeroDev project ID is required");
}
const networkId = config.networkId || "base-sepolia";
const chain = network_1.NETWORK_ID_TO_VIEM_CHAIN[networkId];
const bundlerRpc = `https://rpc.zerodev.app/api/v3/bundler/${config.projectId}`;
// Create public client
const publicClient = (0, viem_1.createPublicClient)({
chain,
transport: (0, viem_1.http)(),
});
// Create ECDSA validator
const entryPoint = (0, constants_1.getEntryPoint)(config.entryPointVersion || "0.7");
const ecdsaValidator = await (0, ecdsa_validator_1.signerToEcdsaValidator)(publicClient, {
signer: config.signer,
entryPoint,
kernelVersion: constants_1.KERNEL_V3_2,
});
// Create kernel account with intent executor
const kernelAccount = await (0, sdk_1.createKernelAccount)(publicClient, {
plugins: {
sudo: ecdsaValidator,
},
entryPoint,
kernelVersion: constants_1.KERNEL_V3_2,
address: config.address,
initConfig: [(0, intent_1.installIntentExecutor)(intent_1.INTENT_V0_3)],
});
// Create intent client
const intentClient = await (0, intent_1.createIntentClient)({
account: kernelAccount,
chain,
bundlerTransport: (0, viem_1.http)(bundlerRpc),
version: intent_1.INTENT_V0_3,
});
return new ZeroDevWalletProvider(config, kernelAccount, intentClient);
}
/**
* Signs a message using the Kernel account.
*
* @param message - The message to sign.
* @returns The signed message.
*/
async signMessage(message) {
// Convert Uint8Array to string if needed
const messageStr = typeof message === "string" ? message : new TextDecoder().decode(message);
return __classPrivateFieldGet(this, _ZeroDevWalletProvider_kernelAccount, "f").signMessage({
message: messageStr,
});
}
/**
* Signs a typed data object using the Kernel 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) {
return __classPrivateFieldGet(this, _ZeroDevWalletProvider_kernelAccount, "f").signTypedData(typedData);
}
/**
* Signs a transaction using the Kernel account.
*
* @param _transaction - The transaction to sign.
* @returns The signed transaction.
*/
async signTransaction(_transaction) {
throw new Error("signTransaction is not supported for ZeroDev Wallet Provider");
}
/**
* Sends a transaction using ZeroDev's Intent system.
*
* @param transaction - The transaction to send.
* @returns The hash of the transaction.
*/
async sendTransaction(transaction) {
// Get the chain ID from the network
const chainId = parseInt(__classPrivateFieldGet(this, _ZeroDevWalletProvider_network, "f").chainId);
// Determine if this is a native token transfer
const isNativeTransfer = transaction.value &&
BigInt(transaction.value) > 0 &&
(!transaction.data || transaction.data === "0x");
// For native token transfers, use ETH as the output token
if (isNativeTransfer) {
const intent = await __classPrivateFieldGet(this, _ZeroDevWalletProvider_intentClient, "f").sendUserIntent({
calls: [
{
to: transaction.to,
value: BigInt(transaction.value || 0),
data: transaction.data || "0x",
},
],
outputTokens: [
{
address: viem_1.zeroAddress,
chainId,
amount: BigInt(transaction.value || 0),
},
],
});
const receipt = await __classPrivateFieldGet(this, _ZeroDevWalletProvider_intentClient, "f").waitForUserIntentExecutionReceipt({
uiHash: intent.outputUiHash.uiHash,
});
return receipt?.receipt.transactionHash || "0x";
}
const intent = await __classPrivateFieldGet(this, _ZeroDevWalletProvider_intentClient, "f").sendUserIntent({
calls: [
{
to: transaction.to,
value: BigInt(transaction.value || 0),
data: transaction.data || "0x",
},
],
chainId: chainId,
});
const receipt = await __classPrivateFieldGet(this, _ZeroDevWalletProvider_intentClient, "f").waitForUserIntentExecutionReceipt({
uiHash: intent.outputUiHash.uiHash,
});
return receipt?.receipt.transactionHash || "0x";
}
/**
* Waits for a transaction receipt.
*
* @param txHash - The hash of the transaction to wait for.
* @returns The transaction receipt.
*/
async waitForTransactionReceipt(txHash) {
return __classPrivateFieldGet(this, _ZeroDevWalletProvider_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, _ZeroDevWalletProvider_publicClient, "f").readContract(params);
}
/**
* Gets the address of the wallet.
*
* @returns The address of the wallet.
*/
getAddress() {
return __classPrivateFieldGet(this, _ZeroDevWalletProvider_address, "f");
}
/**
* Gets the network of the wallet.
*
* @returns The network of the wallet.
*/
getNetwork() {
return __classPrivateFieldGet(this, _ZeroDevWalletProvider_network, "f");
}
/**
* Gets the name of the wallet provider.
*
* @returns The name of the wallet provider.
*/
getName() {
return "zerodev_wallet_provider";
}
/**
* Gets the balance of the wallet.
*
* @returns The balance of the wallet in wei.
*/
async getBalance() {
return __classPrivateFieldGet(this, _ZeroDevWalletProvider_publicClient, "f").getBalance({
address: __classPrivateFieldGet(this, _ZeroDevWalletProvider_address, "f"),
});
}
/**
* Transfer the native asset of the network.
*
* @param to - The destination address.
* @param value - The amount to transfer in whole units (e.g. ETH).
* @returns The transaction hash.
*/
async nativeTransfer(to, value) {
// Convert value to wei (assuming value is in whole units)
const valueInWei = BigInt(parseFloat(value) * 10 ** 18);
// Get the chain ID from the network
const chainId = parseInt(__classPrivateFieldGet(this, _ZeroDevWalletProvider_network, "f").chainId || "1");
const intent = await __classPrivateFieldGet(this, _ZeroDevWalletProvider_intentClient, "f").sendUserIntent({
calls: [
{
to: to,
value: valueInWei,
data: "0x",
},
],
outputTokens: [
{
address: viem_1.zeroAddress,
chainId,
amount: valueInWei,
},
],
});
const receipt = await __classPrivateFieldGet(this, _ZeroDevWalletProvider_intentClient, "f").waitForUserIntentExecutionReceipt({
uiHash: intent.outputUiHash.uiHash,
});
return receipt?.receipt.transactionHash || "";
}
/**
* Gets the ZeroDev Kernel account.
*
* @returns The ZeroDev Kernel account.
*/
getKernelAccount() {
return __classPrivateFieldGet(this, _ZeroDevWalletProvider_kernelAccount, "f");
}
/**
* Gets the ZeroDev Intent client.
*
* @returns The ZeroDev Intent client.
*/
getIntentClient() {
return __classPrivateFieldGet(this, _ZeroDevWalletProvider_intentClient, "f");
}
/**
* Gets chain abstracted balance.
*
* @param options - The options for the get CAB.
* @returns The chain abstracted balance.
*/
async getCAB(options) {
return __classPrivateFieldGet(this, _ZeroDevWalletProvider_intentClient, "f").getCAB(options);
}
}
exports.ZeroDevWalletProvider = ZeroDevWalletProvider;
_ZeroDevWalletProvider_signer = new WeakMap(), _ZeroDevWalletProvider_projectId = new WeakMap(), _ZeroDevWalletProvider_network = new WeakMap(), _ZeroDevWalletProvider_address = new WeakMap(), _ZeroDevWalletProvider_publicClient = new WeakMap(), _ZeroDevWalletProvider_kernelAccount = new WeakMap(), _ZeroDevWalletProvider_intentClient = new WeakMap();