@coinbase/agentkit 0.8.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +373 -234
- package/dist/action-providers/cdp/cdpApiActionProvider.d.ts +15 -15
- package/dist/action-providers/cdp/cdpApiActionProvider.js +110 -63
- package/dist/action-providers/cdp/cdpApiActionProvider.test.js +205 -124
- package/dist/action-providers/cdp/index.d.ts +0 -1
- package/dist/action-providers/cdp/index.js +0 -1
- package/dist/action-providers/cdp/schemas.d.ts +9 -70
- package/dist/action-providers/cdp/schemas.js +12 -61
- package/dist/action-providers/cdp-legacy/index.d.ts +3 -0
- package/dist/action-providers/{cdp-v2 → cdp-legacy}/index.js +2 -1
- package/dist/action-providers/cdp-legacy/legacyCdpApiActionProvider.d.ts +45 -0
- package/dist/action-providers/cdp-legacy/legacyCdpApiActionProvider.js +130 -0
- package/dist/action-providers/cdp-legacy/legacyCdpApiActionProvider.test.js +146 -0
- package/dist/action-providers/{cdp/cdpWalletActionProvider.d.ts → cdp-legacy/legacyCdpWalletActionProvider.d.ts} +8 -8
- package/dist/action-providers/{cdp/cdpWalletActionProvider.js → cdp-legacy/legacyCdpWalletActionProvider.js} +14 -14
- package/dist/action-providers/{cdp/cdpWalletActionProvider.test.js → cdp-legacy/legacyCdpWalletActionProvider.test.js} +3 -3
- package/dist/action-providers/cdp-legacy/schemas.d.ts +91 -0
- package/dist/action-providers/cdp-legacy/schemas.js +77 -0
- package/dist/action-providers/erc20/erc20ActionProvider.js +1 -1
- package/dist/action-providers/index.d.ts +1 -1
- package/dist/action-providers/index.js +1 -1
- package/dist/action-providers/jupiter/jupiterActionProvider.test.js +2 -4
- package/dist/action-providers/x402/schemas.d.ts +58 -11
- package/dist/action-providers/x402/schemas.js +60 -8
- package/dist/action-providers/x402/x402ActionProvider.d.ts +33 -16
- package/dist/action-providers/x402/x402ActionProvider.js +203 -153
- package/dist/action-providers/x402/x402ActionProvider.test.js +78 -225
- package/dist/agentkit.d.ts +1 -0
- package/dist/agentkit.js +3 -2
- package/dist/wallet-providers/{cdpV2EvmWalletProvider.d.ts → cdpEvmWalletProvider.d.ts} +16 -7
- package/dist/wallet-providers/{cdpV2EvmWalletProvider.js → cdpEvmWalletProvider.js} +50 -39
- package/dist/wallet-providers/{cdpV2EvmWalletProvider.test.js → cdpEvmWalletProvider.test.js} +7 -7
- package/dist/wallet-providers/{cdpV2Shared.d.ts → cdpShared.d.ts} +15 -4
- package/dist/wallet-providers/cdpSmartWalletProvider.d.ts +115 -0
- package/dist/wallet-providers/cdpSmartWalletProvider.js +263 -0
- package/dist/wallet-providers/cdpSmartWalletProvider.test.js +287 -0
- package/dist/wallet-providers/{cdpV2SolanaWalletProvider.d.ts → cdpSolanaWalletProvider.d.ts} +16 -7
- package/dist/wallet-providers/{cdpV2SolanaWalletProvider.js → cdpSolanaWalletProvider.js} +43 -32
- package/dist/wallet-providers/{cdpV2SolanaWalletProvider.test.js → cdpSolanaWalletProvider.test.js} +7 -7
- package/dist/wallet-providers/index.d.ts +6 -6
- package/dist/wallet-providers/index.js +6 -6
- package/dist/wallet-providers/{smartWalletProvider.d.ts → legacyCdpSmartWalletProvider.d.ts} +3 -3
- package/dist/wallet-providers/{smartWalletProvider.js → legacyCdpSmartWalletProvider.js} +21 -21
- package/dist/wallet-providers/legacyCdpSmartWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/{smartWalletProvider.test.js → legacyCdpSmartWalletProvider.test.js} +2 -2
- package/dist/wallet-providers/{cdpWalletProvider.d.ts → legacyCdpWalletProvider.d.ts} +15 -11
- package/dist/wallet-providers/{cdpWalletProvider.js → legacyCdpWalletProvider.js} +72 -70
- package/dist/wallet-providers/legacyCdpWalletProvider.test.d.ts +1 -0
- package/dist/wallet-providers/{cdpWalletProvider.test.js → legacyCdpWalletProvider.test.js} +10 -10
- package/package.json +3 -2
- package/dist/action-providers/cdp-v2/cdpApiV2ActionProvider.d.ts +0 -34
- package/dist/action-providers/cdp-v2/cdpApiV2ActionProvider.js +0 -98
- package/dist/action-providers/cdp-v2/index.d.ts +0 -2
- package/dist/action-providers/cdp-v2/schemas.d.ts +0 -11
- package/dist/action-providers/cdp-v2/schemas.js +0 -13
- package/dist/wallet-providers/cdpV2WalletProvider.d.ts +0 -35
- package/dist/wallet-providers/cdpV2WalletProvider.js +0 -42
- /package/dist/action-providers/{cdp → cdp-legacy}/constants.d.ts +0 -0
- /package/dist/action-providers/{cdp → cdp-legacy}/constants.js +0 -0
- /package/dist/action-providers/{cdp/cdpWalletActionProvider.test.d.ts → cdp-legacy/legacyCdpApiActionProvider.test.d.ts} +0 -0
- /package/dist/{wallet-providers/cdpV2EvmWalletProvider.test.d.ts → action-providers/cdp-legacy/legacyCdpWalletActionProvider.test.d.ts} +0 -0
- /package/dist/wallet-providers/{cdpV2SolanaWalletProvider.test.d.ts → cdpEvmWalletProvider.test.d.ts} +0 -0
- /package/dist/wallet-providers/{cdpV2Shared.js → cdpShared.js} +0 -0
- /package/dist/wallet-providers/{cdpWalletProvider.test.d.ts → cdpSmartWalletProvider.test.d.ts} +0 -0
- /package/dist/wallet-providers/{smartWalletProvider.test.d.ts → cdpSolanaWalletProvider.test.d.ts} +0 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
3
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
4
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
5
|
+
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");
|
|
6
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
7
|
+
};
|
|
8
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
10
|
+
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");
|
|
11
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
12
|
+
};
|
|
13
|
+
var _CdpSmartWalletProvider_instances, _CdpSmartWalletProvider_publicClient, _CdpSmartWalletProvider_smartAccount, _CdpSmartWalletProvider_ownerAccount, _CdpSmartWalletProvider_cdp, _CdpSmartWalletProvider_network, _CdpSmartWalletProvider_getCdpSdkNetwork;
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CdpSmartWalletProvider = void 0;
|
|
16
|
+
const cdp_sdk_1 = require("@coinbase/cdp-sdk");
|
|
17
|
+
const viem_1 = require("viem");
|
|
18
|
+
const network_1 = require("../network");
|
|
19
|
+
const evmWalletProvider_1 = require("./evmWalletProvider");
|
|
20
|
+
/**
|
|
21
|
+
* A wallet provider that uses the Coinbase CDP SDK smart wallets.
|
|
22
|
+
*/
|
|
23
|
+
class CdpSmartWalletProvider extends evmWalletProvider_1.EvmWalletProvider {
|
|
24
|
+
/**
|
|
25
|
+
* Constructs a new CdpSmartWalletProvider.
|
|
26
|
+
*
|
|
27
|
+
* @param config - The configuration options for the CdpSmartWalletProvider.
|
|
28
|
+
*/
|
|
29
|
+
constructor(config) {
|
|
30
|
+
super();
|
|
31
|
+
_CdpSmartWalletProvider_instances.add(this);
|
|
32
|
+
_CdpSmartWalletProvider_publicClient.set(this, void 0);
|
|
33
|
+
_CdpSmartWalletProvider_smartAccount.set(this, void 0);
|
|
34
|
+
_CdpSmartWalletProvider_ownerAccount.set(this, void 0);
|
|
35
|
+
_CdpSmartWalletProvider_cdp.set(this, void 0);
|
|
36
|
+
_CdpSmartWalletProvider_network.set(this, void 0);
|
|
37
|
+
__classPrivateFieldSet(this, _CdpSmartWalletProvider_smartAccount, config.smartAccount, "f");
|
|
38
|
+
__classPrivateFieldSet(this, _CdpSmartWalletProvider_ownerAccount, config.ownerAccount, "f");
|
|
39
|
+
__classPrivateFieldSet(this, _CdpSmartWalletProvider_cdp, config.cdp, "f");
|
|
40
|
+
__classPrivateFieldSet(this, _CdpSmartWalletProvider_publicClient, config.publicClient, "f");
|
|
41
|
+
__classPrivateFieldSet(this, _CdpSmartWalletProvider_network, config.network, "f");
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Configures a new CdpSmartWalletProvider with a smart wallet.
|
|
45
|
+
*
|
|
46
|
+
* @param config - Optional configuration parameters
|
|
47
|
+
* @returns A Promise that resolves to a new CdpSmartWalletProvider instance
|
|
48
|
+
* @throws Error if required environment variables are missing or wallet initialization fails
|
|
49
|
+
*/
|
|
50
|
+
static async configureWithWallet(config = {}) {
|
|
51
|
+
const apiKeyId = config.apiKeyId || process.env.CDP_API_KEY_ID;
|
|
52
|
+
const apiKeySecret = config.apiKeySecret || process.env.CDP_API_KEY_SECRET;
|
|
53
|
+
const walletSecret = config.walletSecret || process.env.CDP_WALLET_SECRET;
|
|
54
|
+
const idempotencyKey = config.idempotencyKey || process.env.IDEMPOTENCY_KEY;
|
|
55
|
+
if (!apiKeyId || !apiKeySecret || !walletSecret) {
|
|
56
|
+
throw new Error("Missing required environment variables. CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET are required.");
|
|
57
|
+
}
|
|
58
|
+
const networkId = config.networkId || process.env.NETWORK_ID || "base-sepolia";
|
|
59
|
+
// Smart wallets are currently only supported on Base networks
|
|
60
|
+
if (!networkId.startsWith("base-")) {
|
|
61
|
+
throw new Error(`Smart wallets are only supported on Base networks. Got: ${networkId}`);
|
|
62
|
+
}
|
|
63
|
+
const network = {
|
|
64
|
+
protocolFamily: "evm",
|
|
65
|
+
chainId: network_1.NETWORK_ID_TO_CHAIN_ID[networkId],
|
|
66
|
+
networkId: networkId,
|
|
67
|
+
};
|
|
68
|
+
const cdpClient = new cdp_sdk_1.CdpClient({
|
|
69
|
+
apiKeyId,
|
|
70
|
+
apiKeySecret,
|
|
71
|
+
walletSecret,
|
|
72
|
+
});
|
|
73
|
+
// Create or get the owner account
|
|
74
|
+
const ownerAccount = await (() => {
|
|
75
|
+
if (typeof config.owner === "string") {
|
|
76
|
+
return cdpClient.evm.getAccount({ address: config.owner });
|
|
77
|
+
}
|
|
78
|
+
if (typeof config.owner === "object") {
|
|
79
|
+
return config.owner;
|
|
80
|
+
}
|
|
81
|
+
return cdpClient.evm.createAccount({ idempotencyKey });
|
|
82
|
+
})();
|
|
83
|
+
// Create or get the smart account
|
|
84
|
+
const smartAccount = await (config.address || config.smartAccountName
|
|
85
|
+
? cdpClient.evm.getSmartAccount({
|
|
86
|
+
address: config.address,
|
|
87
|
+
name: config.smartAccountName,
|
|
88
|
+
owner: ownerAccount,
|
|
89
|
+
})
|
|
90
|
+
: cdpClient.evm.createSmartAccount({
|
|
91
|
+
owner: ownerAccount,
|
|
92
|
+
}));
|
|
93
|
+
const publicClient = (0, viem_1.createPublicClient)({
|
|
94
|
+
chain: network_1.NETWORK_ID_TO_VIEM_CHAIN[networkId],
|
|
95
|
+
transport: (0, viem_1.http)(),
|
|
96
|
+
});
|
|
97
|
+
return new CdpSmartWalletProvider({
|
|
98
|
+
publicClient,
|
|
99
|
+
cdp: cdpClient,
|
|
100
|
+
smartAccount,
|
|
101
|
+
ownerAccount,
|
|
102
|
+
network,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Exports the wallet.
|
|
107
|
+
*
|
|
108
|
+
* @returns The wallet's data.
|
|
109
|
+
*/
|
|
110
|
+
async exportWallet() {
|
|
111
|
+
return {
|
|
112
|
+
name: __classPrivateFieldGet(this, _CdpSmartWalletProvider_smartAccount, "f").name,
|
|
113
|
+
address: __classPrivateFieldGet(this, _CdpSmartWalletProvider_smartAccount, "f").address,
|
|
114
|
+
ownerAddress: __classPrivateFieldGet(this, _CdpSmartWalletProvider_ownerAccount, "f").address,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Signs a message using the owner account.
|
|
119
|
+
*
|
|
120
|
+
* @param _message - The message to sign.
|
|
121
|
+
* @returns The signed message.
|
|
122
|
+
*/
|
|
123
|
+
async signMessage(_message) {
|
|
124
|
+
throw new Error("Direct message signing not supported for smart wallets. Use sendTransaction instead.");
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Signs a typed data object using the owner account.
|
|
128
|
+
*
|
|
129
|
+
* @param typedData - The typed data object to sign.
|
|
130
|
+
* @returns The signed typed data object.
|
|
131
|
+
*/
|
|
132
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
133
|
+
async signTypedData(typedData) {
|
|
134
|
+
const { domain, types, primaryType, message } = typedData;
|
|
135
|
+
return await __classPrivateFieldGet(this, _CdpSmartWalletProvider_smartAccount, "f").signTypedData({
|
|
136
|
+
domain,
|
|
137
|
+
types,
|
|
138
|
+
primaryType,
|
|
139
|
+
message,
|
|
140
|
+
network: __classPrivateFieldGet(this, _CdpSmartWalletProvider_instances, "m", _CdpSmartWalletProvider_getCdpSdkNetwork).call(this),
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Signs a transaction using the owner account.
|
|
145
|
+
*
|
|
146
|
+
* @param _ - The transaction to sign.
|
|
147
|
+
* @returns The signed transaction.
|
|
148
|
+
*/
|
|
149
|
+
async signTransaction(_) {
|
|
150
|
+
throw new Error("Direct transaction signing not supported for smart wallets. Use sendTransaction instead.");
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Sends a user operation through the smart wallet.
|
|
154
|
+
*
|
|
155
|
+
* @param transaction - The transaction to send.
|
|
156
|
+
* @returns The user operation hash.
|
|
157
|
+
*/
|
|
158
|
+
async sendTransaction(transaction) {
|
|
159
|
+
const calls = [
|
|
160
|
+
{
|
|
161
|
+
to: transaction.to,
|
|
162
|
+
value: transaction.value ? BigInt(transaction.value.toString()) : 0n,
|
|
163
|
+
data: transaction.data || "0x",
|
|
164
|
+
},
|
|
165
|
+
];
|
|
166
|
+
const userOperation = await __classPrivateFieldGet(this, _CdpSmartWalletProvider_cdp, "f").evm.sendUserOperation({
|
|
167
|
+
smartAccount: __classPrivateFieldGet(this, _CdpSmartWalletProvider_smartAccount, "f"),
|
|
168
|
+
network: __classPrivateFieldGet(this, _CdpSmartWalletProvider_instances, "m", _CdpSmartWalletProvider_getCdpSdkNetwork).call(this),
|
|
169
|
+
calls,
|
|
170
|
+
});
|
|
171
|
+
return userOperation.userOpHash;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Gets the address of the smart wallet.
|
|
175
|
+
*
|
|
176
|
+
* @returns The address of the smart wallet.
|
|
177
|
+
*/
|
|
178
|
+
getAddress() {
|
|
179
|
+
return __classPrivateFieldGet(this, _CdpSmartWalletProvider_smartAccount, "f").address;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Gets the network of the wallet.
|
|
183
|
+
*
|
|
184
|
+
* @returns The network of the wallet.
|
|
185
|
+
*/
|
|
186
|
+
getNetwork() {
|
|
187
|
+
return __classPrivateFieldGet(this, _CdpSmartWalletProvider_network, "f");
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Gets the name of the wallet provider.
|
|
191
|
+
*
|
|
192
|
+
* @returns The name of the wallet provider.
|
|
193
|
+
*/
|
|
194
|
+
getName() {
|
|
195
|
+
return "cdp_smart_wallet_provider";
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Gets the CDP client.
|
|
199
|
+
*
|
|
200
|
+
* @returns The CDP client.
|
|
201
|
+
*/
|
|
202
|
+
getClient() {
|
|
203
|
+
return __classPrivateFieldGet(this, _CdpSmartWalletProvider_cdp, "f");
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Gets the balance of the smart wallet.
|
|
207
|
+
*
|
|
208
|
+
* @returns The balance of the wallet in wei
|
|
209
|
+
*/
|
|
210
|
+
async getBalance() {
|
|
211
|
+
return await __classPrivateFieldGet(this, _CdpSmartWalletProvider_publicClient, "f").getBalance({ address: __classPrivateFieldGet(this, _CdpSmartWalletProvider_smartAccount, "f").address });
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Waits for a user operation receipt.
|
|
215
|
+
*
|
|
216
|
+
* @param userOpHash - The user operation hash to wait for.
|
|
217
|
+
* @returns The user operation receipt.
|
|
218
|
+
*/
|
|
219
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
220
|
+
async waitForTransactionReceipt(userOpHash) {
|
|
221
|
+
// For smart wallets, we need to wait for the user operation to be confirmed
|
|
222
|
+
// This is a simplified implementation - in practice you might want to poll
|
|
223
|
+
// the CDP API for user operation status
|
|
224
|
+
return __classPrivateFieldGet(this, _CdpSmartWalletProvider_cdp, "f").evm.waitForUserOperation({
|
|
225
|
+
smartAccountAddress: __classPrivateFieldGet(this, _CdpSmartWalletProvider_smartAccount, "f").address,
|
|
226
|
+
userOpHash,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Reads a contract.
|
|
231
|
+
*
|
|
232
|
+
* @param params - The parameters to read the contract.
|
|
233
|
+
* @returns The response from the contract.
|
|
234
|
+
*/
|
|
235
|
+
async readContract(params) {
|
|
236
|
+
return __classPrivateFieldGet(this, _CdpSmartWalletProvider_publicClient, "f").readContract(params);
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Transfer the native asset of the network using smart wallet.
|
|
240
|
+
*
|
|
241
|
+
* @param to - The destination address.
|
|
242
|
+
* @param value - The amount to transfer in Wei.
|
|
243
|
+
* @returns The user operation hash.
|
|
244
|
+
*/
|
|
245
|
+
async nativeTransfer(to, value) {
|
|
246
|
+
return this.sendTransaction({
|
|
247
|
+
to: to,
|
|
248
|
+
value: BigInt(value),
|
|
249
|
+
data: "0x",
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
exports.CdpSmartWalletProvider = CdpSmartWalletProvider;
|
|
254
|
+
_CdpSmartWalletProvider_publicClient = new WeakMap(), _CdpSmartWalletProvider_smartAccount = new WeakMap(), _CdpSmartWalletProvider_ownerAccount = new WeakMap(), _CdpSmartWalletProvider_cdp = new WeakMap(), _CdpSmartWalletProvider_network = new WeakMap(), _CdpSmartWalletProvider_instances = new WeakSet(), _CdpSmartWalletProvider_getCdpSdkNetwork = function _CdpSmartWalletProvider_getCdpSdkNetwork() {
|
|
255
|
+
switch (__classPrivateFieldGet(this, _CdpSmartWalletProvider_network, "f").networkId) {
|
|
256
|
+
case "base-sepolia":
|
|
257
|
+
return "base-sepolia";
|
|
258
|
+
case "base-mainnet":
|
|
259
|
+
return "base";
|
|
260
|
+
default:
|
|
261
|
+
throw new Error(`Unsupported network for smart wallets: ${__classPrivateFieldGet(this, _CdpSmartWalletProvider_network, "f").networkId}`);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const cdp_sdk_1 = require("@coinbase/cdp-sdk");
|
|
4
|
+
const cdpSmartWalletProvider_1 = require("./cdpSmartWalletProvider");
|
|
5
|
+
// =========================================================
|
|
6
|
+
// consts
|
|
7
|
+
// =========================================================
|
|
8
|
+
const mockPublicClient = {
|
|
9
|
+
readContract: jest.fn(),
|
|
10
|
+
getBalance: jest.fn(),
|
|
11
|
+
};
|
|
12
|
+
// =========================================================
|
|
13
|
+
// mocks
|
|
14
|
+
// =========================================================
|
|
15
|
+
jest.mock("../analytics", () => ({
|
|
16
|
+
sendAnalyticsEvent: jest.fn().mockImplementation(() => Promise.resolve()),
|
|
17
|
+
}));
|
|
18
|
+
jest.mock("../../package.json", () => ({
|
|
19
|
+
version: "1.0.0",
|
|
20
|
+
}));
|
|
21
|
+
jest.mock("viem", () => {
|
|
22
|
+
return {
|
|
23
|
+
createPublicClient: jest.fn(() => mockPublicClient),
|
|
24
|
+
http: jest.fn(),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
jest.mock("../network", () => {
|
|
28
|
+
return {
|
|
29
|
+
NETWORK_ID_TO_CHAIN_ID: {
|
|
30
|
+
"base-mainnet": "8453",
|
|
31
|
+
"base-sepolia": "84532",
|
|
32
|
+
},
|
|
33
|
+
NETWORK_ID_TO_VIEM_CHAIN: {
|
|
34
|
+
"base-mainnet": { id: 8453 },
|
|
35
|
+
"base-sepolia": { id: 84532 },
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
// Mock CdpClient
|
|
40
|
+
jest.mock("@coinbase/cdp-sdk", () => {
|
|
41
|
+
const MOCK_ADDRESS = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e";
|
|
42
|
+
const MOCK_SMART_ADDRESS = "0x1234567890123456789012345678901234567890";
|
|
43
|
+
const MOCK_SIGNATURE = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1b01";
|
|
44
|
+
const MOCK_USER_OP_HASH = "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890";
|
|
45
|
+
const mockCreateAccount = jest.fn().mockImplementation(() => Promise.resolve({
|
|
46
|
+
address: MOCK_ADDRESS,
|
|
47
|
+
signMessage: jest.fn().mockResolvedValue(MOCK_SIGNATURE),
|
|
48
|
+
signTypedData: jest.fn().mockResolvedValue(MOCK_SIGNATURE),
|
|
49
|
+
}));
|
|
50
|
+
const mockGetSmartAccount = jest.fn().mockImplementation(() => Promise.resolve({
|
|
51
|
+
address: MOCK_SMART_ADDRESS,
|
|
52
|
+
}));
|
|
53
|
+
const mockCreateSmartAccount = jest.fn().mockImplementation(() => Promise.resolve({
|
|
54
|
+
address: MOCK_SMART_ADDRESS,
|
|
55
|
+
}));
|
|
56
|
+
const mockGetOrCreateSmartAccount = jest.fn().mockImplementation(() => Promise.resolve({
|
|
57
|
+
address: MOCK_SMART_ADDRESS,
|
|
58
|
+
}));
|
|
59
|
+
const mockSendUserOperation = jest
|
|
60
|
+
.fn()
|
|
61
|
+
.mockImplementation(async () => ({ userOpHash: MOCK_USER_OP_HASH }));
|
|
62
|
+
const mockEvmClient = {
|
|
63
|
+
createAccount: mockCreateAccount,
|
|
64
|
+
getAccount: jest.fn(),
|
|
65
|
+
createSmartAccount: mockCreateSmartAccount,
|
|
66
|
+
getOrCreateSmartAccount: mockGetOrCreateSmartAccount,
|
|
67
|
+
getSmartAccount: mockGetSmartAccount,
|
|
68
|
+
sendUserOperation: mockSendUserOperation,
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
CdpClient: jest.fn().mockImplementation(() => ({
|
|
72
|
+
evm: mockEvmClient,
|
|
73
|
+
})),
|
|
74
|
+
EvmServerAccount: jest.fn().mockImplementation(() => ({
|
|
75
|
+
address: MOCK_ADDRESS,
|
|
76
|
+
signMessage: jest.fn().mockResolvedValue(MOCK_SIGNATURE),
|
|
77
|
+
signTypedData: jest.fn().mockResolvedValue(MOCK_SIGNATURE),
|
|
78
|
+
})),
|
|
79
|
+
EvmSmartAccount: jest.fn().mockImplementation(() => ({
|
|
80
|
+
address: MOCK_SMART_ADDRESS,
|
|
81
|
+
})),
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
// =========================================================
|
|
85
|
+
// test constants
|
|
86
|
+
// =========================================================
|
|
87
|
+
const MOCK_ADDRESS = "0x742d35Cc6634C0532925a3b844Bc454e4438f44e";
|
|
88
|
+
const MOCK_SMART_ADDRESS = "0x1234567890123456789012345678901234567890";
|
|
89
|
+
const MOCK_NETWORK_ID = "base-sepolia";
|
|
90
|
+
const MOCK_USER_OP_HASH = "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890";
|
|
91
|
+
const MOCK_SIGNATURE = "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1b01";
|
|
92
|
+
const MOCK_BALANCE = 1000000000000000000n;
|
|
93
|
+
const MOCK_NETWORK = {
|
|
94
|
+
protocolFamily: "evm",
|
|
95
|
+
networkId: MOCK_NETWORK_ID,
|
|
96
|
+
chainId: "84532",
|
|
97
|
+
};
|
|
98
|
+
describe("CdpSmartWalletProvider", () => {
|
|
99
|
+
let provider;
|
|
100
|
+
let mockCdpClient;
|
|
101
|
+
let mockSmartAccount;
|
|
102
|
+
let mockOwnerAccount;
|
|
103
|
+
beforeEach(async () => {
|
|
104
|
+
jest.clearAllMocks();
|
|
105
|
+
mockCdpClient = new cdp_sdk_1.CdpClient({
|
|
106
|
+
apiKeyId: "test-key-id",
|
|
107
|
+
apiKeySecret: "test-key-secret",
|
|
108
|
+
walletSecret: "test-wallet-secret",
|
|
109
|
+
});
|
|
110
|
+
mockOwnerAccount = {
|
|
111
|
+
address: MOCK_ADDRESS,
|
|
112
|
+
signMessage: jest.fn().mockResolvedValue(MOCK_SIGNATURE),
|
|
113
|
+
signTypedData: jest.fn().mockResolvedValue(MOCK_SIGNATURE),
|
|
114
|
+
};
|
|
115
|
+
mockSmartAccount = {
|
|
116
|
+
address: MOCK_SMART_ADDRESS,
|
|
117
|
+
};
|
|
118
|
+
// Set up the mock smart account for the provider
|
|
119
|
+
mockCdpClient.evm.createAccount.mockResolvedValue(mockOwnerAccount);
|
|
120
|
+
mockCdpClient.evm.createSmartAccount.mockResolvedValue(mockSmartAccount);
|
|
121
|
+
mockPublicClient.readContract.mockResolvedValue("mock_result");
|
|
122
|
+
mockPublicClient.getBalance.mockResolvedValue(MOCK_BALANCE);
|
|
123
|
+
provider = await cdpSmartWalletProvider_1.CdpSmartWalletProvider.configureWithWallet({
|
|
124
|
+
apiKeyId: "test-key-id",
|
|
125
|
+
apiKeySecret: "test-key-secret",
|
|
126
|
+
walletSecret: "test-wallet-secret",
|
|
127
|
+
networkId: MOCK_NETWORK_ID,
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
// =========================================================
|
|
131
|
+
// initialization tests
|
|
132
|
+
// =========================================================
|
|
133
|
+
describe("initialization", () => {
|
|
134
|
+
it("should initialize with API keys", async () => {
|
|
135
|
+
const provider = await cdpSmartWalletProvider_1.CdpSmartWalletProvider.configureWithWallet({
|
|
136
|
+
apiKeyId: "test-key-id",
|
|
137
|
+
apiKeySecret: "test-key-secret",
|
|
138
|
+
walletSecret: "test-wallet-secret",
|
|
139
|
+
networkId: MOCK_NETWORK_ID,
|
|
140
|
+
});
|
|
141
|
+
expect(provider.getAddress()).toBe(MOCK_SMART_ADDRESS);
|
|
142
|
+
expect(provider.getNetwork()).toEqual(MOCK_NETWORK);
|
|
143
|
+
});
|
|
144
|
+
it("should throw error for non-Base networks", async () => {
|
|
145
|
+
await expect(cdpSmartWalletProvider_1.CdpSmartWalletProvider.configureWithWallet({
|
|
146
|
+
apiKeyId: "test-key-id",
|
|
147
|
+
apiKeySecret: "test-key-secret",
|
|
148
|
+
walletSecret: "test-wallet-secret",
|
|
149
|
+
networkId: "ethereum-sepolia",
|
|
150
|
+
})).rejects.toThrow("Smart wallets are only supported on Base networks");
|
|
151
|
+
});
|
|
152
|
+
it("should create smart account with name", async () => {
|
|
153
|
+
await cdpSmartWalletProvider_1.CdpSmartWalletProvider.configureWithWallet({
|
|
154
|
+
apiKeyId: "test-key-id",
|
|
155
|
+
apiKeySecret: "test-key-secret",
|
|
156
|
+
walletSecret: "test-wallet-secret",
|
|
157
|
+
networkId: MOCK_NETWORK_ID,
|
|
158
|
+
smartAccountName: "MySmartWallet",
|
|
159
|
+
});
|
|
160
|
+
expect(mockCdpClient.evm.getSmartAccount).toHaveBeenCalledWith({
|
|
161
|
+
name: "MySmartWallet",
|
|
162
|
+
owner: mockOwnerAccount,
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
// =========================================================
|
|
167
|
+
// basic wallet method tests
|
|
168
|
+
// =========================================================
|
|
169
|
+
describe("basic wallet methods", () => {
|
|
170
|
+
it("should get the smart wallet address", () => {
|
|
171
|
+
expect(provider.getAddress()).toBe(MOCK_SMART_ADDRESS);
|
|
172
|
+
});
|
|
173
|
+
it("should get the network", () => {
|
|
174
|
+
expect(provider.getNetwork()).toEqual(MOCK_NETWORK);
|
|
175
|
+
});
|
|
176
|
+
it("should get the name", () => {
|
|
177
|
+
expect(provider.getName()).toBe("cdp_smart_wallet_provider");
|
|
178
|
+
});
|
|
179
|
+
it("should get the balance", async () => {
|
|
180
|
+
const balance = await provider.getBalance();
|
|
181
|
+
expect(balance).toBe(MOCK_BALANCE);
|
|
182
|
+
expect(mockPublicClient.getBalance).toHaveBeenCalledWith({
|
|
183
|
+
address: MOCK_SMART_ADDRESS,
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
// =========================================================
|
|
188
|
+
// signing operation tests
|
|
189
|
+
// =========================================================
|
|
190
|
+
describe("signing operations", () => {
|
|
191
|
+
it("should throw error for direct message signing", async () => {
|
|
192
|
+
await expect(provider.signMessage("Hello, world!")).rejects.toThrow("Direct message signing not supported for smart wallets. Use sendTransaction instead.");
|
|
193
|
+
});
|
|
194
|
+
it("should sign typed data using smart account", async () => {
|
|
195
|
+
const typedData = {
|
|
196
|
+
domain: {
|
|
197
|
+
name: "Example",
|
|
198
|
+
version: "1",
|
|
199
|
+
chainId: 1,
|
|
200
|
+
verifyingContract: "0x1234567890123456789012345678901234567890",
|
|
201
|
+
},
|
|
202
|
+
types: {
|
|
203
|
+
Person: [
|
|
204
|
+
{ name: "name", type: "string" },
|
|
205
|
+
{ name: "wallet", type: "address" },
|
|
206
|
+
],
|
|
207
|
+
},
|
|
208
|
+
primaryType: "Person",
|
|
209
|
+
message: {
|
|
210
|
+
name: "Bob",
|
|
211
|
+
wallet: "0x1234567890123456789012345678901234567890",
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
// Mock the smart account's signTypedData method
|
|
215
|
+
mockSmartAccount.signTypedData = jest.fn().mockResolvedValue(MOCK_SIGNATURE);
|
|
216
|
+
const signature = await provider.signTypedData(typedData);
|
|
217
|
+
// Verify the smart account was called with the correct parameters
|
|
218
|
+
expect(mockSmartAccount.signTypedData).toHaveBeenCalledWith({
|
|
219
|
+
domain: typedData.domain,
|
|
220
|
+
types: typedData.types,
|
|
221
|
+
primaryType: typedData.primaryType,
|
|
222
|
+
message: typedData.message,
|
|
223
|
+
network: MOCK_NETWORK.networkId,
|
|
224
|
+
});
|
|
225
|
+
expect(signature).toBe(MOCK_SIGNATURE);
|
|
226
|
+
});
|
|
227
|
+
it("should throw error for direct transaction signing", async () => {
|
|
228
|
+
const tx = {
|
|
229
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
230
|
+
value: BigInt(1000000000000000000),
|
|
231
|
+
};
|
|
232
|
+
await expect(provider.signTransaction(tx)).rejects.toThrow("Direct transaction signing not supported for smart wallets. Use sendTransaction instead.");
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
// =========================================================
|
|
236
|
+
// user operation tests
|
|
237
|
+
// =========================================================
|
|
238
|
+
describe("user operations", () => {
|
|
239
|
+
it("should send user operations", async () => {
|
|
240
|
+
const transaction = {
|
|
241
|
+
to: "0x1234567890123456789012345678901234567890",
|
|
242
|
+
value: BigInt(1000000000000000000),
|
|
243
|
+
};
|
|
244
|
+
const userOpHash = await provider.sendTransaction(transaction);
|
|
245
|
+
expect(mockCdpClient.evm.sendUserOperation).toHaveBeenCalledWith({
|
|
246
|
+
smartAccount: mockSmartAccount,
|
|
247
|
+
network: "base-sepolia",
|
|
248
|
+
calls: [
|
|
249
|
+
{
|
|
250
|
+
to: transaction.to,
|
|
251
|
+
value: BigInt(transaction.value.toString()),
|
|
252
|
+
data: "0x",
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
});
|
|
256
|
+
expect(userOpHash).toBe(MOCK_USER_OP_HASH);
|
|
257
|
+
});
|
|
258
|
+
it("should handle native transfers", async () => {
|
|
259
|
+
const userOpHash = await provider.nativeTransfer("0x1234567890123456789012345678901234567890", "1000000000000000000");
|
|
260
|
+
expect(userOpHash).toBe(MOCK_USER_OP_HASH);
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
// =========================================================
|
|
264
|
+
// contract interaction tests
|
|
265
|
+
// =========================================================
|
|
266
|
+
describe("contract interactions", () => {
|
|
267
|
+
it("should read contract data", async () => {
|
|
268
|
+
const abi = [
|
|
269
|
+
{
|
|
270
|
+
name: "balanceOf",
|
|
271
|
+
type: "function",
|
|
272
|
+
inputs: [{ name: "account", type: "address" }],
|
|
273
|
+
outputs: [{ name: "balance", type: "uint256" }],
|
|
274
|
+
stateMutability: "view",
|
|
275
|
+
},
|
|
276
|
+
];
|
|
277
|
+
const result = await provider.readContract({
|
|
278
|
+
address: "0x1234567890123456789012345678901234567890",
|
|
279
|
+
abi,
|
|
280
|
+
functionName: "balanceOf",
|
|
281
|
+
args: [MOCK_SMART_ADDRESS],
|
|
282
|
+
});
|
|
283
|
+
expect(result).toBe("mock_result");
|
|
284
|
+
expect(mockPublicClient.readContract).toHaveBeenCalled();
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
});
|
package/dist/wallet-providers/{cdpV2SolanaWalletProvider.d.ts → cdpSolanaWalletProvider.d.ts}
RENAMED
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
import { CdpClient } from "@coinbase/cdp-sdk";
|
|
2
2
|
import { Connection, PublicKey, RpcResponseAndContext, SignatureResult, SignatureStatus, SignatureStatusConfig, VersionedTransaction } from "@solana/web3.js";
|
|
3
3
|
import { Network } from "../network";
|
|
4
|
-
import { WalletProviderWithClient,
|
|
4
|
+
import { WalletProviderWithClient, CdpWalletProviderConfig } from "./cdpShared";
|
|
5
5
|
import { SvmWalletProvider } from "./svmWalletProvider";
|
|
6
6
|
/**
|
|
7
7
|
* A wallet provider that uses the Coinbase SDK.
|
|
8
8
|
*/
|
|
9
|
-
export declare class
|
|
9
|
+
export declare class CdpSolanaWalletProvider extends SvmWalletProvider implements WalletProviderWithClient {
|
|
10
10
|
#private;
|
|
11
11
|
/**
|
|
12
|
-
* Constructs a new
|
|
12
|
+
* Constructs a new CdpSolanaWalletProvider.
|
|
13
13
|
*
|
|
14
|
-
* @param config - The configuration options for the
|
|
14
|
+
* @param config - The configuration options for the CdpSolanaWalletProvider.
|
|
15
15
|
*/
|
|
16
16
|
private constructor();
|
|
17
17
|
/**
|
|
18
|
-
* Configures a new
|
|
18
|
+
* Configures a new CdpSolanaWalletProvider with a wallet.
|
|
19
19
|
*
|
|
20
20
|
* @param config - Optional configuration parameters
|
|
21
|
-
* @returns A Promise that resolves to a new
|
|
21
|
+
* @returns A Promise that resolves to a new CdpSolanaWalletProvider instance
|
|
22
22
|
* @throws Error if required environment variables are missing or wallet initialization fails
|
|
23
23
|
*/
|
|
24
|
-
static configureWithWallet(config?:
|
|
24
|
+
static configureWithWallet(config?: CdpWalletProviderConfig): Promise<CdpSolanaWalletProvider>;
|
|
25
|
+
/**
|
|
26
|
+
* Exports the wallet.
|
|
27
|
+
*
|
|
28
|
+
* @returns The wallet's data.
|
|
29
|
+
*/
|
|
30
|
+
exportWallet(): Promise<{
|
|
31
|
+
name: string | undefined;
|
|
32
|
+
address: `0x${string}`;
|
|
33
|
+
}>;
|
|
25
34
|
/**
|
|
26
35
|
* Get the connection instance
|
|
27
36
|
*
|