@smartagentkit/testing 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SmartAgentKit Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # @smartagentkit/testing
2
+
3
+ Mock client for SmartAgentKit that simulates the full SDK API in-memory. Run examples and integration tests without funded wallets, deployed contracts, or network access.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install --save-dev @smartagentkit/testing
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { MockSmartAgentKitClient } from "@smartagentkit/testing";
15
+
16
+ const client = new MockSmartAgentKitClient({ preset: "defi-trader" });
17
+
18
+ const wallet = await client.createWallet({
19
+ owner: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
20
+ ownerPrivateKey: "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
21
+ preset: "defi-trader",
22
+ });
23
+
24
+ // Spending limits, allowlist, and pause are all enforced in-memory
25
+ await client.execute(wallet, {
26
+ target: "0x...",
27
+ value: 1000000000000000n,
28
+ });
29
+ ```
30
+
31
+ ## Features
32
+
33
+ - **Full API parity** with `SmartAgentKitClient` via `ISmartAgentKitClient` interface
34
+ - **In-memory policy enforcement** - spending limits, allowlist, pause state
35
+ - **Preset support** - defi-trader, treasury-agent, payment-agent, minimal
36
+ - **Test helpers** - `getLog()`, `setState()`, `getWalletState()` for setup and assertions
37
+
38
+ ## Documentation
39
+
40
+ See the [main repository](https://github.com/smartagentkit/smartagentkit) for full documentation and examples.
41
+
42
+ ## License
43
+
44
+ MIT
@@ -0,0 +1,97 @@
1
+ import { Address, Hex } from 'viem';
2
+ import { PolicyConfig, ActiveSession, ISmartAgentKitClient, CreateWalletParams, AgentWallet, SignerKey, ExecuteParams, ExecuteBatchParams, CreateSessionParams } from '@smartagentkit/sdk';
3
+
4
+ interface MockClientOptions {
5
+ /** Initial ETH balance in wei (default: 10 ETH) */
6
+ initialBalance?: bigint;
7
+ /** Initial token balances (address → wei) */
8
+ tokenBalances?: Record<string, bigint>;
9
+ /** Whether to log all operations (default: false) */
10
+ verbose?: boolean;
11
+ }
12
+ interface MockLogEntry {
13
+ timestamp: number;
14
+ operation: string;
15
+ details: Record<string, unknown>;
16
+ }
17
+ interface MockWalletState {
18
+ address: Address;
19
+ owner: Address;
20
+ isDeployed: boolean;
21
+ paused: boolean;
22
+ ethBalance: bigint;
23
+ tokenBalances: Map<string, bigint>;
24
+ spendingUsed: Map<string, bigint>;
25
+ spendingLimits: Map<string, {
26
+ limit: bigint;
27
+ window: number;
28
+ }>;
29
+ allowlistMode: "allow" | "block" | null;
30
+ allowlistTargets: Set<string>;
31
+ policies: PolicyConfig[];
32
+ sessions: ActiveSession[];
33
+ guardian: Address | null;
34
+ }
35
+
36
+ /**
37
+ * In-memory mock of SmartAgentKitClient for running examples
38
+ * without funded wallets, deployed contracts, or RPC connections.
39
+ *
40
+ * Mirrors the real client's public API but operates entirely in memory.
41
+ */
42
+ declare class MockSmartAgentKitClient implements ISmartAgentKitClient {
43
+ private wallets;
44
+ private log;
45
+ private verbose;
46
+ private defaultBalance;
47
+ private defaultTokenBalances;
48
+ private walletCounter;
49
+ constructor(options?: MockClientOptions);
50
+ createWallet(params: CreateWalletParams): Promise<AgentWallet>;
51
+ connectWallet(walletAddress: Address, _ownerKey: SignerKey): Promise<void>;
52
+ execute(wallet: AgentWallet, params: ExecuteParams): Promise<Hex>;
53
+ executeBatch(wallet: AgentWallet, params: ExecuteBatchParams): Promise<Hex>;
54
+ getRemainingAllowance(walletAddress: Address, token: Address): Promise<bigint>;
55
+ isPaused(walletAddress: Address): Promise<boolean>;
56
+ getBalances(walletAddress: Address): Promise<{
57
+ eth: bigint;
58
+ tokens: {
59
+ address: Address;
60
+ symbol: string;
61
+ balance: bigint;
62
+ }[];
63
+ }>;
64
+ pause(walletAddress: Address, _guardianKey: SignerKey): Promise<Hex>;
65
+ unpause(walletAddress: Address, _guardianKey: SignerKey): Promise<Hex>;
66
+ createSession(wallet: AgentWallet, params: CreateSessionParams, _ownerKey: SignerKey): Promise<{
67
+ sessionKey: Address;
68
+ privateKey: Hex;
69
+ permissionId: Hex;
70
+ }>;
71
+ revokeSession(wallet: AgentWallet, permissionId: Hex, _ownerKey: SignerKey): Promise<void>;
72
+ getActiveSessions(walletAddress: Address): ActiveSession[];
73
+ /** Get the full operation log for inspection */
74
+ getLog(): MockLogEntry[];
75
+ /** Directly manipulate wallet state for test setup */
76
+ setState(walletAddress: Address, updates: Partial<MockWalletState>): void;
77
+ /** Get current wallet state (read-only copy) */
78
+ getWalletState(walletAddress: Address): MockWalletState;
79
+ private getState;
80
+ private enforceNotPaused;
81
+ private enforceAllowlist;
82
+ private enforceAndDeductSpending;
83
+ private deductTokenTransfer;
84
+ private resolvePolicies;
85
+ private resolvePreset;
86
+ private applyPolicy;
87
+ private stateToWallet;
88
+ private tokenSymbol;
89
+ private fakeTxHash;
90
+ private addLog;
91
+ }
92
+
93
+ declare function createDefaultState(address: Address, owner: Address, initialBalance?: bigint): MockWalletState;
94
+ /** Generate a deterministic mock address from a seed */
95
+ declare function deterministicAddress(seed: number): Address;
96
+
97
+ export { type MockClientOptions, type MockLogEntry, MockSmartAgentKitClient, type MockWalletState, createDefaultState, deterministicAddress };
@@ -0,0 +1,97 @@
1
+ import { Address, Hex } from 'viem';
2
+ import { PolicyConfig, ActiveSession, ISmartAgentKitClient, CreateWalletParams, AgentWallet, SignerKey, ExecuteParams, ExecuteBatchParams, CreateSessionParams } from '@smartagentkit/sdk';
3
+
4
+ interface MockClientOptions {
5
+ /** Initial ETH balance in wei (default: 10 ETH) */
6
+ initialBalance?: bigint;
7
+ /** Initial token balances (address → wei) */
8
+ tokenBalances?: Record<string, bigint>;
9
+ /** Whether to log all operations (default: false) */
10
+ verbose?: boolean;
11
+ }
12
+ interface MockLogEntry {
13
+ timestamp: number;
14
+ operation: string;
15
+ details: Record<string, unknown>;
16
+ }
17
+ interface MockWalletState {
18
+ address: Address;
19
+ owner: Address;
20
+ isDeployed: boolean;
21
+ paused: boolean;
22
+ ethBalance: bigint;
23
+ tokenBalances: Map<string, bigint>;
24
+ spendingUsed: Map<string, bigint>;
25
+ spendingLimits: Map<string, {
26
+ limit: bigint;
27
+ window: number;
28
+ }>;
29
+ allowlistMode: "allow" | "block" | null;
30
+ allowlistTargets: Set<string>;
31
+ policies: PolicyConfig[];
32
+ sessions: ActiveSession[];
33
+ guardian: Address | null;
34
+ }
35
+
36
+ /**
37
+ * In-memory mock of SmartAgentKitClient for running examples
38
+ * without funded wallets, deployed contracts, or RPC connections.
39
+ *
40
+ * Mirrors the real client's public API but operates entirely in memory.
41
+ */
42
+ declare class MockSmartAgentKitClient implements ISmartAgentKitClient {
43
+ private wallets;
44
+ private log;
45
+ private verbose;
46
+ private defaultBalance;
47
+ private defaultTokenBalances;
48
+ private walletCounter;
49
+ constructor(options?: MockClientOptions);
50
+ createWallet(params: CreateWalletParams): Promise<AgentWallet>;
51
+ connectWallet(walletAddress: Address, _ownerKey: SignerKey): Promise<void>;
52
+ execute(wallet: AgentWallet, params: ExecuteParams): Promise<Hex>;
53
+ executeBatch(wallet: AgentWallet, params: ExecuteBatchParams): Promise<Hex>;
54
+ getRemainingAllowance(walletAddress: Address, token: Address): Promise<bigint>;
55
+ isPaused(walletAddress: Address): Promise<boolean>;
56
+ getBalances(walletAddress: Address): Promise<{
57
+ eth: bigint;
58
+ tokens: {
59
+ address: Address;
60
+ symbol: string;
61
+ balance: bigint;
62
+ }[];
63
+ }>;
64
+ pause(walletAddress: Address, _guardianKey: SignerKey): Promise<Hex>;
65
+ unpause(walletAddress: Address, _guardianKey: SignerKey): Promise<Hex>;
66
+ createSession(wallet: AgentWallet, params: CreateSessionParams, _ownerKey: SignerKey): Promise<{
67
+ sessionKey: Address;
68
+ privateKey: Hex;
69
+ permissionId: Hex;
70
+ }>;
71
+ revokeSession(wallet: AgentWallet, permissionId: Hex, _ownerKey: SignerKey): Promise<void>;
72
+ getActiveSessions(walletAddress: Address): ActiveSession[];
73
+ /** Get the full operation log for inspection */
74
+ getLog(): MockLogEntry[];
75
+ /** Directly manipulate wallet state for test setup */
76
+ setState(walletAddress: Address, updates: Partial<MockWalletState>): void;
77
+ /** Get current wallet state (read-only copy) */
78
+ getWalletState(walletAddress: Address): MockWalletState;
79
+ private getState;
80
+ private enforceNotPaused;
81
+ private enforceAllowlist;
82
+ private enforceAndDeductSpending;
83
+ private deductTokenTransfer;
84
+ private resolvePolicies;
85
+ private resolvePreset;
86
+ private applyPolicy;
87
+ private stateToWallet;
88
+ private tokenSymbol;
89
+ private fakeTxHash;
90
+ private addLog;
91
+ }
92
+
93
+ declare function createDefaultState(address: Address, owner: Address, initialBalance?: bigint): MockWalletState;
94
+ /** Generate a deterministic mock address from a seed */
95
+ declare function deterministicAddress(seed: number): Address;
96
+
97
+ export { type MockClientOptions, type MockLogEntry, MockSmartAgentKitClient, type MockWalletState, createDefaultState, deterministicAddress };
package/dist/index.js ADDED
@@ -0,0 +1,451 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ MockSmartAgentKitClient: () => MockSmartAgentKitClient,
24
+ createDefaultState: () => createDefaultState,
25
+ deterministicAddress: () => deterministicAddress
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/mock-client.ts
30
+ var import_viem2 = require("viem");
31
+ var import_sdk = require("@smartagentkit/sdk");
32
+
33
+ // src/mock-state.ts
34
+ var import_viem = require("viem");
35
+ function createDefaultState(address, owner, initialBalance = (0, import_viem.parseEther)("10")) {
36
+ return {
37
+ address,
38
+ owner,
39
+ isDeployed: true,
40
+ paused: false,
41
+ ethBalance: initialBalance,
42
+ tokenBalances: /* @__PURE__ */ new Map(),
43
+ spendingUsed: /* @__PURE__ */ new Map(),
44
+ spendingLimits: /* @__PURE__ */ new Map(),
45
+ allowlistMode: null,
46
+ allowlistTargets: /* @__PURE__ */ new Set(),
47
+ policies: [],
48
+ sessions: [],
49
+ guardian: null
50
+ };
51
+ }
52
+ function deterministicAddress(seed) {
53
+ const hex = seed.toString(16).padStart(40, "0");
54
+ return `0x${hex}`;
55
+ }
56
+
57
+ // src/mock-client.ts
58
+ var NATIVE_TOKEN = "0x0000000000000000000000000000000000000000";
59
+ var TRANSFER_SELECTOR = "0xa9059cbb";
60
+ var MockSmartAgentKitClient = class {
61
+ wallets = /* @__PURE__ */ new Map();
62
+ log = [];
63
+ verbose;
64
+ defaultBalance;
65
+ defaultTokenBalances;
66
+ walletCounter = 1;
67
+ constructor(options = {}) {
68
+ this.verbose = options.verbose ?? false;
69
+ this.defaultBalance = options.initialBalance ?? (0, import_viem2.parseEther)("10");
70
+ this.defaultTokenBalances = options.tokenBalances ?? {};
71
+ }
72
+ // ─── Wallet Management ────────────────────────────────────────
73
+ async createWallet(params) {
74
+ const address = deterministicAddress(this.walletCounter++);
75
+ const state = createDefaultState(address, params.owner, this.defaultBalance);
76
+ for (const [token, balance] of Object.entries(this.defaultTokenBalances)) {
77
+ state.tokenBalances.set(token.toLowerCase(), balance);
78
+ }
79
+ const policies = this.resolvePolicies(params);
80
+ state.policies = policies;
81
+ for (const policy of policies) {
82
+ this.applyPolicy(state, policy);
83
+ }
84
+ this.wallets.set(address.toLowerCase(), state);
85
+ this.addLog("createWallet", { address, owner: params.owner, preset: params.preset });
86
+ return this.stateToWallet(state);
87
+ }
88
+ async connectWallet(walletAddress, _ownerKey) {
89
+ const key = walletAddress.toLowerCase();
90
+ if (!this.wallets.has(key)) {
91
+ const state = createDefaultState(walletAddress, walletAddress, this.defaultBalance);
92
+ for (const [token, balance] of Object.entries(this.defaultTokenBalances)) {
93
+ state.tokenBalances.set(token.toLowerCase(), balance);
94
+ }
95
+ this.wallets.set(key, state);
96
+ }
97
+ this.addLog("connectWallet", { address: walletAddress });
98
+ }
99
+ // ─── Execution ────────────────────────────────────────────────
100
+ async execute(wallet, params) {
101
+ const state = this.getState(wallet.address);
102
+ this.enforceNotPaused(state);
103
+ const value = params.value ?? 0n;
104
+ this.enforceAllowlist(state, params.target);
105
+ if (value > 0n) {
106
+ this.enforceAndDeductSpending(state, NATIVE_TOKEN, value);
107
+ state.ethBalance -= value;
108
+ }
109
+ if (params.data && params.data.startsWith(TRANSFER_SELECTOR)) {
110
+ this.deductTokenTransfer(state, params.target, params.data);
111
+ }
112
+ const txHash = this.fakeTxHash();
113
+ this.addLog("execute", {
114
+ target: params.target,
115
+ value: value.toString(),
116
+ txHash
117
+ });
118
+ return txHash;
119
+ }
120
+ async executeBatch(wallet, params) {
121
+ const state = this.getState(wallet.address);
122
+ this.enforceNotPaused(state);
123
+ const deductions = [];
124
+ for (const call of params.calls) {
125
+ const value = call.value ?? 0n;
126
+ this.enforceAllowlist(state, call.target);
127
+ if (value > 0n) {
128
+ const tokenKey = NATIVE_TOKEN.toLowerCase();
129
+ const limitEntry = state.spendingLimits.get(tokenKey);
130
+ if (limitEntry) {
131
+ const used = state.spendingUsed.get(tokenKey) ?? 0n;
132
+ const totalPending = deductions.filter((d) => d.token === tokenKey).reduce((sum, d) => sum + d.amount, 0n);
133
+ const remaining = limitEntry.limit - used - totalPending;
134
+ if (value > remaining) {
135
+ throw new import_sdk.SpendingLimitExceededError(NATIVE_TOKEN, value, remaining);
136
+ }
137
+ }
138
+ deductions.push({ token: tokenKey, amount: value });
139
+ }
140
+ }
141
+ for (const { token, amount } of deductions) {
142
+ const used = state.spendingUsed.get(token) ?? 0n;
143
+ state.spendingUsed.set(token, used + amount);
144
+ if (token === NATIVE_TOKEN.toLowerCase()) {
145
+ state.ethBalance -= amount;
146
+ }
147
+ }
148
+ const txHash = this.fakeTxHash();
149
+ this.addLog("executeBatch", {
150
+ callCount: params.calls.length,
151
+ txHash
152
+ });
153
+ return txHash;
154
+ }
155
+ // ─── Query Functions ──────────────────────────────────────────
156
+ async getRemainingAllowance(walletAddress, token) {
157
+ const state = this.getState(walletAddress);
158
+ const tokenKey = token.toLowerCase();
159
+ const limitEntry = state.spendingLimits.get(tokenKey);
160
+ if (!limitEntry) return (0, import_viem2.parseEther)("999999");
161
+ const used = state.spendingUsed.get(tokenKey) ?? 0n;
162
+ return limitEntry.limit - used;
163
+ }
164
+ async isPaused(walletAddress) {
165
+ const state = this.getState(walletAddress);
166
+ return state.paused;
167
+ }
168
+ async getBalances(walletAddress) {
169
+ const state = this.getState(walletAddress);
170
+ const tokens = [];
171
+ for (const [addr, balance] of state.tokenBalances) {
172
+ tokens.push({
173
+ address: addr,
174
+ symbol: this.tokenSymbol(addr),
175
+ balance
176
+ });
177
+ }
178
+ return { eth: state.ethBalance, tokens };
179
+ }
180
+ // ─── Guardian Actions ─────────────────────────────────────────
181
+ async pause(walletAddress, _guardianKey) {
182
+ const state = this.getState(walletAddress);
183
+ state.paused = true;
184
+ const txHash = this.fakeTxHash();
185
+ this.addLog("pause", { address: walletAddress, txHash });
186
+ return txHash;
187
+ }
188
+ async unpause(walletAddress, _guardianKey) {
189
+ const state = this.getState(walletAddress);
190
+ state.paused = false;
191
+ const txHash = this.fakeTxHash();
192
+ this.addLog("unpause", { address: walletAddress, txHash });
193
+ return txHash;
194
+ }
195
+ // ─── Session Management ───────────────────────────────────────
196
+ async createSession(wallet, params, _ownerKey) {
197
+ const state = this.getState(wallet.address);
198
+ const sessionKey = deterministicAddress(Date.now() % 1e5);
199
+ const privateKey = `0x${"ab".repeat(32)}`;
200
+ const permissionId = `0x${"cd".repeat(32)}`;
201
+ const session = {
202
+ sessionKey,
203
+ actions: params.actions,
204
+ expiresAt: params.expiresAt,
205
+ isActive: true
206
+ };
207
+ state.sessions.push(session);
208
+ this.addLog("createSession", {
209
+ wallet: wallet.address,
210
+ sessionKey,
211
+ expiresAt: params.expiresAt
212
+ });
213
+ return { sessionKey, privateKey, permissionId };
214
+ }
215
+ async revokeSession(wallet, permissionId, _ownerKey) {
216
+ const state = this.getState(wallet.address);
217
+ state.sessions = state.sessions.filter((s) => s.isActive);
218
+ if (state.sessions.length > 0) {
219
+ state.sessions[state.sessions.length - 1].isActive = false;
220
+ }
221
+ this.addLog("revokeSession", { wallet: wallet.address, permissionId });
222
+ }
223
+ getActiveSessions(walletAddress) {
224
+ const state = this.getState(walletAddress);
225
+ const now = Math.floor(Date.now() / 1e3);
226
+ return state.sessions.filter((s) => s.isActive && s.expiresAt > now);
227
+ }
228
+ // ─── Mock-Specific Methods ────────────────────────────────────
229
+ /** Get the full operation log for inspection */
230
+ getLog() {
231
+ return [...this.log];
232
+ }
233
+ /** Directly manipulate wallet state for test setup */
234
+ setState(walletAddress, updates) {
235
+ const state = this.getState(walletAddress);
236
+ if (updates.ethBalance !== void 0) state.ethBalance = updates.ethBalance;
237
+ if (updates.paused !== void 0) state.paused = updates.paused;
238
+ if (updates.tokenBalances !== void 0) state.tokenBalances = updates.tokenBalances;
239
+ if (updates.spendingUsed !== void 0) state.spendingUsed = updates.spendingUsed;
240
+ if (updates.allowlistMode !== void 0) state.allowlistMode = updates.allowlistMode;
241
+ if (updates.allowlistTargets !== void 0) state.allowlistTargets = updates.allowlistTargets;
242
+ if (updates.spendingLimits !== void 0) state.spendingLimits = updates.spendingLimits;
243
+ if (updates.guardian !== void 0) state.guardian = updates.guardian;
244
+ }
245
+ /** Get current wallet state (read-only copy) */
246
+ getWalletState(walletAddress) {
247
+ return { ...this.getState(walletAddress) };
248
+ }
249
+ // ─── Private Helpers ──────────────────────────────────────────
250
+ getState(walletAddress) {
251
+ const state = this.wallets.get(walletAddress.toLowerCase());
252
+ if (!state) {
253
+ throw new import_sdk.ExecutionError(
254
+ `No wallet found at ${walletAddress}. Call createWallet() or connectWallet() first.`
255
+ );
256
+ }
257
+ return state;
258
+ }
259
+ enforceNotPaused(state) {
260
+ if (state.paused) {
261
+ throw new import_sdk.WalletPausedError(state.address);
262
+ }
263
+ }
264
+ enforceAllowlist(state, target) {
265
+ if (state.allowlistMode === "allow") {
266
+ if (!state.allowlistTargets.has(target.toLowerCase())) {
267
+ throw new import_sdk.ExecutionError(
268
+ `Target ${target} is not on the allowlist`
269
+ );
270
+ }
271
+ } else if (state.allowlistMode === "block") {
272
+ if (state.allowlistTargets.has(target.toLowerCase())) {
273
+ throw new import_sdk.ExecutionError(
274
+ `Target ${target} is on the blocklist`
275
+ );
276
+ }
277
+ }
278
+ }
279
+ enforceAndDeductSpending(state, token, amount) {
280
+ const tokenKey = token.toLowerCase();
281
+ const limitEntry = state.spendingLimits.get(tokenKey);
282
+ if (!limitEntry) return;
283
+ const used = state.spendingUsed.get(tokenKey) ?? 0n;
284
+ const remaining = limitEntry.limit - used;
285
+ if (amount > remaining) {
286
+ throw new import_sdk.SpendingLimitExceededError(token, amount, remaining);
287
+ }
288
+ state.spendingUsed.set(tokenKey, used + amount);
289
+ }
290
+ deductTokenTransfer(state, tokenAddress, data) {
291
+ if (data.length < 138) return;
292
+ const amountHex = "0x" + data.slice(74, 138);
293
+ const amount = BigInt(amountHex);
294
+ const tokenKey = tokenAddress.toLowerCase();
295
+ const balance = state.tokenBalances.get(tokenKey) ?? 0n;
296
+ state.tokenBalances.set(tokenKey, balance - amount);
297
+ this.enforceAndDeductSpending(state, tokenAddress, amount);
298
+ }
299
+ resolvePolicies(params) {
300
+ if (params.preset) {
301
+ return this.resolvePreset(params.preset, params.owner, params.presetParams);
302
+ }
303
+ return params.policies ?? [];
304
+ }
305
+ resolvePreset(preset, owner, params = {}) {
306
+ switch (preset) {
307
+ case "defi-trader":
308
+ return [
309
+ {
310
+ type: "spending-limit",
311
+ limits: [
312
+ {
313
+ token: NATIVE_TOKEN,
314
+ limit: params.dailyEthLimit ?? (0, import_viem2.parseEther)("1"),
315
+ window: 86400
316
+ }
317
+ ]
318
+ },
319
+ {
320
+ type: "emergency-pause",
321
+ guardian: params.guardian ?? owner,
322
+ autoUnpauseAfter: 86400
323
+ }
324
+ ];
325
+ case "treasury-agent":
326
+ return [
327
+ {
328
+ type: "spending-limit",
329
+ limits: [
330
+ {
331
+ token: NATIVE_TOKEN,
332
+ limit: params.weeklyEthLimit ?? (0, import_viem2.parseEther)("5"),
333
+ window: 604800
334
+ }
335
+ ]
336
+ },
337
+ {
338
+ type: "emergency-pause",
339
+ guardian: params.guardian ?? owner,
340
+ autoUnpauseAfter: 0
341
+ }
342
+ ];
343
+ case "payment-agent": {
344
+ const policies = [
345
+ {
346
+ type: "spending-limit",
347
+ limits: [
348
+ {
349
+ token: NATIVE_TOKEN,
350
+ limit: params.dailyLimit ?? (0, import_viem2.parseEther)("0.1"),
351
+ window: 86400
352
+ }
353
+ ]
354
+ }
355
+ ];
356
+ const recipients = params.approvedRecipients;
357
+ if (recipients?.length) {
358
+ policies.push({
359
+ type: "allowlist",
360
+ mode: "allow",
361
+ targets: recipients.map((addr) => ({ address: addr }))
362
+ });
363
+ }
364
+ policies.push({
365
+ type: "emergency-pause",
366
+ guardian: params.guardian ?? owner,
367
+ autoUnpauseAfter: 3600
368
+ });
369
+ return policies;
370
+ }
371
+ case "minimal":
372
+ return [
373
+ {
374
+ type: "emergency-pause",
375
+ guardian: params.guardian ?? owner,
376
+ autoUnpauseAfter: 0
377
+ }
378
+ ];
379
+ default:
380
+ return [];
381
+ }
382
+ }
383
+ applyPolicy(state, policy) {
384
+ switch (policy.type) {
385
+ case "spending-limit":
386
+ for (const limit of policy.limits) {
387
+ state.spendingLimits.set(limit.token.toLowerCase(), {
388
+ limit: limit.limit,
389
+ window: limit.window
390
+ });
391
+ }
392
+ break;
393
+ case "allowlist":
394
+ state.allowlistMode = policy.mode;
395
+ for (const target of policy.targets) {
396
+ state.allowlistTargets.add(target.address.toLowerCase());
397
+ }
398
+ break;
399
+ case "emergency-pause":
400
+ state.guardian = policy.guardian;
401
+ break;
402
+ case "automation":
403
+ break;
404
+ }
405
+ }
406
+ stateToWallet(state) {
407
+ return {
408
+ address: state.address,
409
+ owner: state.owner,
410
+ chain: { id: 84532, name: "Base Sepolia" },
411
+ isDeployed: state.isDeployed,
412
+ policies: state.policies.map((p) => ({
413
+ moduleAddress: NATIVE_TOKEN,
414
+ moduleType: 4,
415
+ name: p.type,
416
+ config: p
417
+ })),
418
+ sessions: state.sessions
419
+ };
420
+ }
421
+ tokenSymbol(address) {
422
+ const symbols = {
423
+ "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": "USDC",
424
+ "0xdac17f958d2ee523a2206206994597c13d831ec7": "USDT",
425
+ "0x6b175474e89094c44da98b954eedeac495271d0f": "DAI"
426
+ };
427
+ return symbols[address.toLowerCase()] ?? "TOKEN";
428
+ }
429
+ fakeTxHash() {
430
+ const rand = Math.random().toString(16).slice(2).padEnd(64, "0");
431
+ return `0x${rand}`;
432
+ }
433
+ addLog(operation, details) {
434
+ const entry = {
435
+ timestamp: Date.now(),
436
+ operation,
437
+ details
438
+ };
439
+ this.log.push(entry);
440
+ if (this.verbose) {
441
+ console.log(`[mock] ${operation}:`, JSON.stringify(details));
442
+ }
443
+ }
444
+ };
445
+ // Annotate the CommonJS export names for ESM import in node:
446
+ 0 && (module.exports = {
447
+ MockSmartAgentKitClient,
448
+ createDefaultState,
449
+ deterministicAddress
450
+ });
451
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/mock-client.ts","../src/mock-state.ts"],"sourcesContent":["export { MockSmartAgentKitClient } from \"./mock-client.js\";\nexport type { MockClientOptions, MockLogEntry, MockWalletState } from \"./types.js\";\nexport { createDefaultState, deterministicAddress } from \"./mock-state.js\";\n","import { parseEther, type Address, type Hex, type Chain } from \"viem\";\nimport type {\n AgentWallet,\n CreateWalletParams,\n ExecuteParams,\n ExecuteBatchParams,\n CreateSessionParams,\n ActiveSession,\n InstalledPolicy,\n PolicyConfig,\n TokenLimit,\n SignerKey,\n ISmartAgentKitClient,\n} from \"@smartagentkit/sdk\";\nimport {\n SpendingLimitExceededError,\n WalletPausedError,\n ExecutionError,\n SessionError,\n} from \"@smartagentkit/sdk\";\nimport type { MockClientOptions, MockLogEntry, MockWalletState } from \"./types.js\";\nimport { createDefaultState, deterministicAddress } from \"./mock-state.js\";\n\nconst NATIVE_TOKEN = \"0x0000000000000000000000000000000000000000\" as Address;\n\n// ERC-20 transfer selector: transfer(address,uint256)\nconst TRANSFER_SELECTOR = \"0xa9059cbb\";\n\n/**\n * In-memory mock of SmartAgentKitClient for running examples\n * without funded wallets, deployed contracts, or RPC connections.\n *\n * Mirrors the real client's public API but operates entirely in memory.\n */\nexport class MockSmartAgentKitClient implements ISmartAgentKitClient {\n private wallets: Map<string, MockWalletState> = new Map();\n private log: MockLogEntry[] = [];\n private verbose: boolean;\n private defaultBalance: bigint;\n private defaultTokenBalances: Record<string, bigint>;\n private walletCounter = 1;\n\n constructor(options: MockClientOptions = {}) {\n this.verbose = options.verbose ?? false;\n this.defaultBalance = options.initialBalance ?? parseEther(\"10\");\n this.defaultTokenBalances = options.tokenBalances ?? {};\n }\n\n // ─── Wallet Management ────────────────────────────────────────\n\n async createWallet(params: CreateWalletParams): Promise<AgentWallet> {\n const address = deterministicAddress(this.walletCounter++);\n const state = createDefaultState(address, params.owner, this.defaultBalance);\n\n // Apply default token balances\n for (const [token, balance] of Object.entries(this.defaultTokenBalances)) {\n state.tokenBalances.set(token.toLowerCase(), balance);\n }\n\n // Resolve policies\n const policies = this.resolvePolicies(params);\n state.policies = policies;\n\n // Apply policy effects to state\n for (const policy of policies) {\n this.applyPolicy(state, policy);\n }\n\n this.wallets.set(address.toLowerCase(), state);\n this.addLog(\"createWallet\", { address, owner: params.owner, preset: params.preset });\n\n return this.stateToWallet(state);\n }\n\n async connectWallet(walletAddress: Address, _ownerKey: SignerKey): Promise<void> {\n const key = walletAddress.toLowerCase();\n if (!this.wallets.has(key)) {\n // Create a minimal state for the connected wallet\n const state = createDefaultState(walletAddress, walletAddress, this.defaultBalance);\n for (const [token, balance] of Object.entries(this.defaultTokenBalances)) {\n state.tokenBalances.set(token.toLowerCase(), balance);\n }\n this.wallets.set(key, state);\n }\n this.addLog(\"connectWallet\", { address: walletAddress });\n }\n\n // ─── Execution ────────────────────────────────────────────────\n\n async execute(wallet: AgentWallet, params: ExecuteParams): Promise<Hex> {\n const state = this.getState(wallet.address);\n this.enforceNotPaused(state);\n\n const value = params.value ?? 0n;\n\n // Check allowlist\n this.enforceAllowlist(state, params.target);\n\n // Calculate spending (ETH value + token transfers)\n if (value > 0n) {\n this.enforceAndDeductSpending(state, NATIVE_TOKEN, value);\n state.ethBalance -= value;\n }\n\n // Detect ERC-20 transfer from calldata\n if (params.data && params.data.startsWith(TRANSFER_SELECTOR)) {\n this.deductTokenTransfer(state, params.target, params.data);\n }\n\n const txHash = this.fakeTxHash();\n this.addLog(\"execute\", {\n target: params.target,\n value: value.toString(),\n txHash,\n });\n return txHash;\n }\n\n async executeBatch(wallet: AgentWallet, params: ExecuteBatchParams): Promise<Hex> {\n const state = this.getState(wallet.address);\n this.enforceNotPaused(state);\n\n // Validate all calls first (atomic: all-or-nothing)\n const deductions: Array<{ token: string; amount: bigint }> = [];\n for (const call of params.calls) {\n const value = call.value ?? 0n;\n this.enforceAllowlist(state, call.target);\n\n if (value > 0n) {\n // Check spending limit without deducting yet\n const tokenKey = NATIVE_TOKEN.toLowerCase();\n const limitEntry = state.spendingLimits.get(tokenKey);\n if (limitEntry) {\n const used = state.spendingUsed.get(tokenKey) ?? 0n;\n const totalPending = deductions\n .filter((d) => d.token === tokenKey)\n .reduce((sum, d) => sum + d.amount, 0n);\n const remaining = limitEntry.limit - used - totalPending;\n if (value > remaining) {\n throw new SpendingLimitExceededError(NATIVE_TOKEN, value, remaining);\n }\n }\n deductions.push({ token: tokenKey, amount: value });\n }\n }\n\n // Apply all deductions\n for (const { token, amount } of deductions) {\n const used = state.spendingUsed.get(token) ?? 0n;\n state.spendingUsed.set(token, used + amount);\n if (token === NATIVE_TOKEN.toLowerCase()) {\n state.ethBalance -= amount;\n }\n }\n\n const txHash = this.fakeTxHash();\n this.addLog(\"executeBatch\", {\n callCount: params.calls.length,\n txHash,\n });\n return txHash;\n }\n\n // ─── Query Functions ──────────────────────────────────────────\n\n async getRemainingAllowance(walletAddress: Address, token: Address): Promise<bigint> {\n const state = this.getState(walletAddress);\n const tokenKey = token.toLowerCase();\n const limitEntry = state.spendingLimits.get(tokenKey);\n if (!limitEntry) return parseEther(\"999999\"); // No limit configured\n const used = state.spendingUsed.get(tokenKey) ?? 0n;\n return limitEntry.limit - used;\n }\n\n async isPaused(walletAddress: Address): Promise<boolean> {\n const state = this.getState(walletAddress);\n return state.paused;\n }\n\n async getBalances(walletAddress: Address): Promise<{\n eth: bigint;\n tokens: { address: Address; symbol: string; balance: bigint }[];\n }> {\n const state = this.getState(walletAddress);\n const tokens: { address: Address; symbol: string; balance: bigint }[] = [];\n for (const [addr, balance] of state.tokenBalances) {\n tokens.push({\n address: addr as Address,\n symbol: this.tokenSymbol(addr),\n balance,\n });\n }\n return { eth: state.ethBalance, tokens };\n }\n\n // ─── Guardian Actions ─────────────────────────────────────────\n\n async pause(walletAddress: Address, _guardianKey: SignerKey): Promise<Hex> {\n const state = this.getState(walletAddress);\n state.paused = true;\n const txHash = this.fakeTxHash();\n this.addLog(\"pause\", { address: walletAddress, txHash });\n return txHash;\n }\n\n async unpause(walletAddress: Address, _guardianKey: SignerKey): Promise<Hex> {\n const state = this.getState(walletAddress);\n state.paused = false;\n const txHash = this.fakeTxHash();\n this.addLog(\"unpause\", { address: walletAddress, txHash });\n return txHash;\n }\n\n // ─── Session Management ───────────────────────────────────────\n\n async createSession(\n wallet: AgentWallet,\n params: CreateSessionParams,\n _ownerKey: SignerKey,\n ): Promise<{ sessionKey: Address; privateKey: Hex; permissionId: Hex }> {\n const state = this.getState(wallet.address);\n\n const sessionKey = deterministicAddress(Date.now() % 100000);\n const privateKey = `0x${\"ab\".repeat(32)}` as Hex;\n const permissionId = `0x${\"cd\".repeat(32)}` as Hex;\n\n const session: ActiveSession = {\n sessionKey,\n actions: params.actions,\n expiresAt: params.expiresAt,\n isActive: true,\n };\n state.sessions.push(session);\n\n this.addLog(\"createSession\", {\n wallet: wallet.address,\n sessionKey,\n expiresAt: params.expiresAt,\n });\n\n return { sessionKey, privateKey, permissionId };\n }\n\n async revokeSession(\n wallet: AgentWallet,\n permissionId: Hex,\n _ownerKey: SignerKey,\n ): Promise<void> {\n const state = this.getState(wallet.address);\n // Remove the most recent session (simplified — real impl uses permissionId)\n state.sessions = state.sessions.filter((s) => s.isActive);\n if (state.sessions.length > 0) {\n state.sessions[state.sessions.length - 1].isActive = false;\n }\n this.addLog(\"revokeSession\", { wallet: wallet.address, permissionId });\n }\n\n getActiveSessions(walletAddress: Address): ActiveSession[] {\n const state = this.getState(walletAddress);\n const now = Math.floor(Date.now() / 1000);\n return state.sessions.filter((s) => s.isActive && s.expiresAt > now);\n }\n\n // ─── Mock-Specific Methods ────────────────────────────────────\n\n /** Get the full operation log for inspection */\n getLog(): MockLogEntry[] {\n return [...this.log];\n }\n\n /** Directly manipulate wallet state for test setup */\n setState(walletAddress: Address, updates: Partial<MockWalletState>): void {\n const state = this.getState(walletAddress);\n if (updates.ethBalance !== undefined) state.ethBalance = updates.ethBalance;\n if (updates.paused !== undefined) state.paused = updates.paused;\n if (updates.tokenBalances !== undefined) state.tokenBalances = updates.tokenBalances;\n if (updates.spendingUsed !== undefined) state.spendingUsed = updates.spendingUsed;\n if (updates.allowlistMode !== undefined) state.allowlistMode = updates.allowlistMode;\n if (updates.allowlistTargets !== undefined) state.allowlistTargets = updates.allowlistTargets;\n if (updates.spendingLimits !== undefined) state.spendingLimits = updates.spendingLimits;\n if (updates.guardian !== undefined) state.guardian = updates.guardian;\n }\n\n /** Get current wallet state (read-only copy) */\n getWalletState(walletAddress: Address): MockWalletState {\n return { ...this.getState(walletAddress) };\n }\n\n // ─── Private Helpers ──────────────────────────────────────────\n\n private getState(walletAddress: Address): MockWalletState {\n const state = this.wallets.get(walletAddress.toLowerCase());\n if (!state) {\n throw new ExecutionError(\n `No wallet found at ${walletAddress}. Call createWallet() or connectWallet() first.`,\n );\n }\n return state;\n }\n\n private enforceNotPaused(state: MockWalletState): void {\n if (state.paused) {\n throw new WalletPausedError(state.address);\n }\n }\n\n private enforceAllowlist(state: MockWalletState, target: Address): void {\n if (state.allowlistMode === \"allow\") {\n if (!state.allowlistTargets.has(target.toLowerCase())) {\n throw new ExecutionError(\n `Target ${target} is not on the allowlist`,\n );\n }\n } else if (state.allowlistMode === \"block\") {\n if (state.allowlistTargets.has(target.toLowerCase())) {\n throw new ExecutionError(\n `Target ${target} is on the blocklist`,\n );\n }\n }\n }\n\n private enforceAndDeductSpending(\n state: MockWalletState,\n token: Address,\n amount: bigint,\n ): void {\n const tokenKey = token.toLowerCase();\n const limitEntry = state.spendingLimits.get(tokenKey);\n if (!limitEntry) return; // No limit configured\n\n const used = state.spendingUsed.get(tokenKey) ?? 0n;\n const remaining = limitEntry.limit - used;\n\n if (amount > remaining) {\n throw new SpendingLimitExceededError(token, amount, remaining);\n }\n\n state.spendingUsed.set(tokenKey, used + amount);\n }\n\n private deductTokenTransfer(\n state: MockWalletState,\n tokenAddress: Address,\n data: Hex,\n ): void {\n // Extract amount from transfer(address,uint256) calldata\n // Selector (4 bytes) + address (32 bytes) + uint256 (32 bytes) = 68 bytes\n if (data.length < 138) return; // \"0x\" + 4 + 32 + 32 hex chars = 2 + 136\n const amountHex = \"0x\" + data.slice(74, 138);\n const amount = BigInt(amountHex);\n const tokenKey = tokenAddress.toLowerCase();\n\n // Deduct from token balance\n const balance = state.tokenBalances.get(tokenKey) ?? 0n;\n state.tokenBalances.set(tokenKey, balance - amount);\n\n // Enforce spending limit for token\n this.enforceAndDeductSpending(state, tokenAddress as Address, amount);\n }\n\n private resolvePolicies(params: CreateWalletParams): PolicyConfig[] {\n if (params.preset) {\n // Import and resolve presets from SDK\n return this.resolvePreset(params.preset, params.owner, params.presetParams);\n }\n return params.policies ?? [];\n }\n\n private resolvePreset(\n preset: string,\n owner: Address,\n params: Record<string, unknown> = {},\n ): PolicyConfig[] {\n // Simplified preset resolution matching SDK presets\n switch (preset) {\n case \"defi-trader\":\n return [\n {\n type: \"spending-limit\",\n limits: [\n {\n token: NATIVE_TOKEN,\n limit: (params.dailyEthLimit as bigint) ?? parseEther(\"1\"),\n window: 86400,\n },\n ],\n },\n {\n type: \"emergency-pause\",\n guardian: (params.guardian as Address) ?? owner,\n autoUnpauseAfter: 86400,\n },\n ];\n case \"treasury-agent\":\n return [\n {\n type: \"spending-limit\",\n limits: [\n {\n token: NATIVE_TOKEN,\n limit: (params.weeklyEthLimit as bigint) ?? parseEther(\"5\"),\n window: 604800,\n },\n ],\n },\n {\n type: \"emergency-pause\",\n guardian: (params.guardian as Address) ?? owner,\n autoUnpauseAfter: 0,\n },\n ];\n case \"payment-agent\": {\n const policies: PolicyConfig[] = [\n {\n type: \"spending-limit\",\n limits: [\n {\n token: NATIVE_TOKEN,\n limit: (params.dailyLimit as bigint) ?? parseEther(\"0.1\"),\n window: 86400,\n },\n ],\n },\n ];\n const recipients = params.approvedRecipients as Address[] | undefined;\n if (recipients?.length) {\n policies.push({\n type: \"allowlist\",\n mode: \"allow\",\n targets: recipients.map((addr) => ({ address: addr })),\n });\n }\n policies.push({\n type: \"emergency-pause\",\n guardian: (params.guardian as Address) ?? owner,\n autoUnpauseAfter: 3600,\n });\n return policies;\n }\n case \"minimal\":\n return [\n {\n type: \"emergency-pause\",\n guardian: (params.guardian as Address) ?? owner,\n autoUnpauseAfter: 0,\n },\n ];\n default:\n return [];\n }\n }\n\n private applyPolicy(state: MockWalletState, policy: PolicyConfig): void {\n switch (policy.type) {\n case \"spending-limit\":\n for (const limit of policy.limits) {\n state.spendingLimits.set(limit.token.toLowerCase(), {\n limit: limit.limit,\n window: limit.window,\n });\n }\n break;\n case \"allowlist\":\n state.allowlistMode = policy.mode;\n for (const target of policy.targets) {\n state.allowlistTargets.add(target.address.toLowerCase());\n }\n break;\n case \"emergency-pause\":\n state.guardian = policy.guardian;\n break;\n case \"automation\":\n // Not relevant for mock\n break;\n }\n }\n\n private stateToWallet(state: MockWalletState): AgentWallet {\n return {\n address: state.address,\n owner: state.owner,\n chain: { id: 84532, name: \"Base Sepolia\" } as Chain,\n isDeployed: state.isDeployed,\n policies: state.policies.map((p) => ({\n moduleAddress: NATIVE_TOKEN,\n moduleType: 4,\n name: p.type,\n config: p,\n })),\n sessions: state.sessions,\n };\n }\n\n private tokenSymbol(address: string): string {\n const symbols: Record<string, string> = {\n \"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\": \"USDC\",\n \"0xdac17f958d2ee523a2206206994597c13d831ec7\": \"USDT\",\n \"0x6b175474e89094c44da98b954eedeac495271d0f\": \"DAI\",\n };\n return symbols[address.toLowerCase()] ?? \"TOKEN\";\n }\n\n private fakeTxHash(): Hex {\n const rand = Math.random().toString(16).slice(2).padEnd(64, \"0\");\n return `0x${rand}` as Hex;\n }\n\n private addLog(operation: string, details: Record<string, unknown>): void {\n const entry: MockLogEntry = {\n timestamp: Date.now(),\n operation,\n details,\n };\n this.log.push(entry);\n if (this.verbose) {\n console.log(`[mock] ${operation}:`, JSON.stringify(details));\n }\n }\n}\n","import { parseEther, type Address } from \"viem\";\nimport type { MockWalletState } from \"./types.js\";\n\nconst ZERO_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\n\nexport function createDefaultState(\n address: Address,\n owner: Address,\n initialBalance: bigint = parseEther(\"10\"),\n): MockWalletState {\n return {\n address,\n owner,\n isDeployed: true,\n paused: false,\n ethBalance: initialBalance,\n tokenBalances: new Map(),\n spendingUsed: new Map(),\n spendingLimits: new Map(),\n allowlistMode: null,\n allowlistTargets: new Set(),\n policies: [],\n sessions: [],\n guardian: null,\n };\n}\n\n/** Generate a deterministic mock address from a seed */\nexport function deterministicAddress(seed: number): Address {\n const hex = seed.toString(16).padStart(40, \"0\");\n return `0x${hex}` as Address;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,eAA+D;AAc/D,iBAKO;;;ACnBP,kBAAyC;AAKlC,SAAS,mBACd,SACA,OACA,qBAAyB,wBAAW,IAAI,GACvB;AACjB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY;AAAA,IACZ,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,eAAe,oBAAI,IAAI;AAAA,IACvB,cAAc,oBAAI,IAAI;AAAA,IACtB,gBAAgB,oBAAI,IAAI;AAAA,IACxB,eAAe;AAAA,IACf,kBAAkB,oBAAI,IAAI;AAAA,IAC1B,UAAU,CAAC;AAAA,IACX,UAAU,CAAC;AAAA,IACX,UAAU;AAAA,EACZ;AACF;AAGO,SAAS,qBAAqB,MAAuB;AAC1D,QAAM,MAAM,KAAK,SAAS,EAAE,EAAE,SAAS,IAAI,GAAG;AAC9C,SAAO,KAAK,GAAG;AACjB;;;ADRA,IAAM,eAAe;AAGrB,IAAM,oBAAoB;AAQnB,IAAM,0BAAN,MAA8D;AAAA,EAC3D,UAAwC,oBAAI,IAAI;AAAA,EAChD,MAAsB,CAAC;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAExB,YAAY,UAA6B,CAAC,GAAG;AAC3C,SAAK,UAAU,QAAQ,WAAW;AAClC,SAAK,iBAAiB,QAAQ,sBAAkB,yBAAW,IAAI;AAC/D,SAAK,uBAAuB,QAAQ,iBAAiB,CAAC;AAAA,EACxD;AAAA;AAAA,EAIA,MAAM,aAAa,QAAkD;AACnE,UAAM,UAAU,qBAAqB,KAAK,eAAe;AACzD,UAAM,QAAQ,mBAAmB,SAAS,OAAO,OAAO,KAAK,cAAc;AAG3E,eAAW,CAAC,OAAO,OAAO,KAAK,OAAO,QAAQ,KAAK,oBAAoB,GAAG;AACxE,YAAM,cAAc,IAAI,MAAM,YAAY,GAAG,OAAO;AAAA,IACtD;AAGA,UAAM,WAAW,KAAK,gBAAgB,MAAM;AAC5C,UAAM,WAAW;AAGjB,eAAW,UAAU,UAAU;AAC7B,WAAK,YAAY,OAAO,MAAM;AAAA,IAChC;AAEA,SAAK,QAAQ,IAAI,QAAQ,YAAY,GAAG,KAAK;AAC7C,SAAK,OAAO,gBAAgB,EAAE,SAAS,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,CAAC;AAEnF,WAAO,KAAK,cAAc,KAAK;AAAA,EACjC;AAAA,EAEA,MAAM,cAAc,eAAwB,WAAqC;AAC/E,UAAM,MAAM,cAAc,YAAY;AACtC,QAAI,CAAC,KAAK,QAAQ,IAAI,GAAG,GAAG;AAE1B,YAAM,QAAQ,mBAAmB,eAAe,eAAe,KAAK,cAAc;AAClF,iBAAW,CAAC,OAAO,OAAO,KAAK,OAAO,QAAQ,KAAK,oBAAoB,GAAG;AACxE,cAAM,cAAc,IAAI,MAAM,YAAY,GAAG,OAAO;AAAA,MACtD;AACA,WAAK,QAAQ,IAAI,KAAK,KAAK;AAAA,IAC7B;AACA,SAAK,OAAO,iBAAiB,EAAE,SAAS,cAAc,CAAC;AAAA,EACzD;AAAA;AAAA,EAIA,MAAM,QAAQ,QAAqB,QAAqC;AACtE,UAAM,QAAQ,KAAK,SAAS,OAAO,OAAO;AAC1C,SAAK,iBAAiB,KAAK;AAE3B,UAAM,QAAQ,OAAO,SAAS;AAG9B,SAAK,iBAAiB,OAAO,OAAO,MAAM;AAG1C,QAAI,QAAQ,IAAI;AACd,WAAK,yBAAyB,OAAO,cAAc,KAAK;AACxD,YAAM,cAAc;AAAA,IACtB;AAGA,QAAI,OAAO,QAAQ,OAAO,KAAK,WAAW,iBAAiB,GAAG;AAC5D,WAAK,oBAAoB,OAAO,OAAO,QAAQ,OAAO,IAAI;AAAA,IAC5D;AAEA,UAAM,SAAS,KAAK,WAAW;AAC/B,SAAK,OAAO,WAAW;AAAA,MACrB,QAAQ,OAAO;AAAA,MACf,OAAO,MAAM,SAAS;AAAA,MACtB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,aAAa,QAAqB,QAA0C;AAChF,UAAM,QAAQ,KAAK,SAAS,OAAO,OAAO;AAC1C,SAAK,iBAAiB,KAAK;AAG3B,UAAM,aAAuD,CAAC;AAC9D,eAAW,QAAQ,OAAO,OAAO;AAC/B,YAAM,QAAQ,KAAK,SAAS;AAC5B,WAAK,iBAAiB,OAAO,KAAK,MAAM;AAExC,UAAI,QAAQ,IAAI;AAEd,cAAM,WAAW,aAAa,YAAY;AAC1C,cAAM,aAAa,MAAM,eAAe,IAAI,QAAQ;AACpD,YAAI,YAAY;AACd,gBAAM,OAAO,MAAM,aAAa,IAAI,QAAQ,KAAK;AACjD,gBAAM,eAAe,WAClB,OAAO,CAAC,MAAM,EAAE,UAAU,QAAQ,EAClC,OAAO,CAAC,KAAK,MAAM,MAAM,EAAE,QAAQ,EAAE;AACxC,gBAAM,YAAY,WAAW,QAAQ,OAAO;AAC5C,cAAI,QAAQ,WAAW;AACrB,kBAAM,IAAI,sCAA2B,cAAc,OAAO,SAAS;AAAA,UACrE;AAAA,QACF;AACA,mBAAW,KAAK,EAAE,OAAO,UAAU,QAAQ,MAAM,CAAC;AAAA,MACpD;AAAA,IACF;AAGA,eAAW,EAAE,OAAO,OAAO,KAAK,YAAY;AAC1C,YAAM,OAAO,MAAM,aAAa,IAAI,KAAK,KAAK;AAC9C,YAAM,aAAa,IAAI,OAAO,OAAO,MAAM;AAC3C,UAAI,UAAU,aAAa,YAAY,GAAG;AACxC,cAAM,cAAc;AAAA,MACtB;AAAA,IACF;AAEA,UAAM,SAAS,KAAK,WAAW;AAC/B,SAAK,OAAO,gBAAgB;AAAA,MAC1B,WAAW,OAAO,MAAM;AAAA,MACxB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,sBAAsB,eAAwB,OAAiC;AACnF,UAAM,QAAQ,KAAK,SAAS,aAAa;AACzC,UAAM,WAAW,MAAM,YAAY;AACnC,UAAM,aAAa,MAAM,eAAe,IAAI,QAAQ;AACpD,QAAI,CAAC,WAAY,YAAO,yBAAW,QAAQ;AAC3C,UAAM,OAAO,MAAM,aAAa,IAAI,QAAQ,KAAK;AACjD,WAAO,WAAW,QAAQ;AAAA,EAC5B;AAAA,EAEA,MAAM,SAAS,eAA0C;AACvD,UAAM,QAAQ,KAAK,SAAS,aAAa;AACzC,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,MAAM,YAAY,eAGf;AACD,UAAM,QAAQ,KAAK,SAAS,aAAa;AACzC,UAAM,SAAkE,CAAC;AACzE,eAAW,CAAC,MAAM,OAAO,KAAK,MAAM,eAAe;AACjD,aAAO,KAAK;AAAA,QACV,SAAS;AAAA,QACT,QAAQ,KAAK,YAAY,IAAI;AAAA,QAC7B;AAAA,MACF,CAAC;AAAA,IACH;AACA,WAAO,EAAE,KAAK,MAAM,YAAY,OAAO;AAAA,EACzC;AAAA;AAAA,EAIA,MAAM,MAAM,eAAwB,cAAuC;AACzE,UAAM,QAAQ,KAAK,SAAS,aAAa;AACzC,UAAM,SAAS;AACf,UAAM,SAAS,KAAK,WAAW;AAC/B,SAAK,OAAO,SAAS,EAAE,SAAS,eAAe,OAAO,CAAC;AACvD,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,QAAQ,eAAwB,cAAuC;AAC3E,UAAM,QAAQ,KAAK,SAAS,aAAa;AACzC,UAAM,SAAS;AACf,UAAM,SAAS,KAAK,WAAW;AAC/B,SAAK,OAAO,WAAW,EAAE,SAAS,eAAe,OAAO,CAAC;AACzD,WAAO;AAAA,EACT;AAAA;AAAA,EAIA,MAAM,cACJ,QACA,QACA,WACsE;AACtE,UAAM,QAAQ,KAAK,SAAS,OAAO,OAAO;AAE1C,UAAM,aAAa,qBAAqB,KAAK,IAAI,IAAI,GAAM;AAC3D,UAAM,aAAa,KAAK,KAAK,OAAO,EAAE,CAAC;AACvC,UAAM,eAAe,KAAK,KAAK,OAAO,EAAE,CAAC;AAEzC,UAAM,UAAyB;AAAA,MAC7B;AAAA,MACA,SAAS,OAAO;AAAA,MAChB,WAAW,OAAO;AAAA,MAClB,UAAU;AAAA,IACZ;AACA,UAAM,SAAS,KAAK,OAAO;AAE3B,SAAK,OAAO,iBAAiB;AAAA,MAC3B,QAAQ,OAAO;AAAA,MACf;AAAA,MACA,WAAW,OAAO;AAAA,IACpB,CAAC;AAED,WAAO,EAAE,YAAY,YAAY,aAAa;AAAA,EAChD;AAAA,EAEA,MAAM,cACJ,QACA,cACA,WACe;AACf,UAAM,QAAQ,KAAK,SAAS,OAAO,OAAO;AAE1C,UAAM,WAAW,MAAM,SAAS,OAAO,CAAC,MAAM,EAAE,QAAQ;AACxD,QAAI,MAAM,SAAS,SAAS,GAAG;AAC7B,YAAM,SAAS,MAAM,SAAS,SAAS,CAAC,EAAE,WAAW;AAAA,IACvD;AACA,SAAK,OAAO,iBAAiB,EAAE,QAAQ,OAAO,SAAS,aAAa,CAAC;AAAA,EACvE;AAAA,EAEA,kBAAkB,eAAyC;AACzD,UAAM,QAAQ,KAAK,SAAS,aAAa;AACzC,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,WAAO,MAAM,SAAS,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG;AAAA,EACrE;AAAA;AAAA;AAAA,EAKA,SAAyB;AACvB,WAAO,CAAC,GAAG,KAAK,GAAG;AAAA,EACrB;AAAA;AAAA,EAGA,SAAS,eAAwB,SAAyC;AACxE,UAAM,QAAQ,KAAK,SAAS,aAAa;AACzC,QAAI,QAAQ,eAAe,OAAW,OAAM,aAAa,QAAQ;AACjE,QAAI,QAAQ,WAAW,OAAW,OAAM,SAAS,QAAQ;AACzD,QAAI,QAAQ,kBAAkB,OAAW,OAAM,gBAAgB,QAAQ;AACvE,QAAI,QAAQ,iBAAiB,OAAW,OAAM,eAAe,QAAQ;AACrE,QAAI,QAAQ,kBAAkB,OAAW,OAAM,gBAAgB,QAAQ;AACvE,QAAI,QAAQ,qBAAqB,OAAW,OAAM,mBAAmB,QAAQ;AAC7E,QAAI,QAAQ,mBAAmB,OAAW,OAAM,iBAAiB,QAAQ;AACzE,QAAI,QAAQ,aAAa,OAAW,OAAM,WAAW,QAAQ;AAAA,EAC/D;AAAA;AAAA,EAGA,eAAe,eAAyC;AACtD,WAAO,EAAE,GAAG,KAAK,SAAS,aAAa,EAAE;AAAA,EAC3C;AAAA;AAAA,EAIQ,SAAS,eAAyC;AACxD,UAAM,QAAQ,KAAK,QAAQ,IAAI,cAAc,YAAY,CAAC;AAC1D,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR,sBAAsB,aAAa;AAAA,MACrC;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,iBAAiB,OAA8B;AACrD,QAAI,MAAM,QAAQ;AAChB,YAAM,IAAI,6BAAkB,MAAM,OAAO;AAAA,IAC3C;AAAA,EACF;AAAA,EAEQ,iBAAiB,OAAwB,QAAuB;AACtE,QAAI,MAAM,kBAAkB,SAAS;AACnC,UAAI,CAAC,MAAM,iBAAiB,IAAI,OAAO,YAAY,CAAC,GAAG;AACrD,cAAM,IAAI;AAAA,UACR,UAAU,MAAM;AAAA,QAClB;AAAA,MACF;AAAA,IACF,WAAW,MAAM,kBAAkB,SAAS;AAC1C,UAAI,MAAM,iBAAiB,IAAI,OAAO,YAAY,CAAC,GAAG;AACpD,cAAM,IAAI;AAAA,UACR,UAAU,MAAM;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,yBACN,OACA,OACA,QACM;AACN,UAAM,WAAW,MAAM,YAAY;AACnC,UAAM,aAAa,MAAM,eAAe,IAAI,QAAQ;AACpD,QAAI,CAAC,WAAY;AAEjB,UAAM,OAAO,MAAM,aAAa,IAAI,QAAQ,KAAK;AACjD,UAAM,YAAY,WAAW,QAAQ;AAErC,QAAI,SAAS,WAAW;AACtB,YAAM,IAAI,sCAA2B,OAAO,QAAQ,SAAS;AAAA,IAC/D;AAEA,UAAM,aAAa,IAAI,UAAU,OAAO,MAAM;AAAA,EAChD;AAAA,EAEQ,oBACN,OACA,cACA,MACM;AAGN,QAAI,KAAK,SAAS,IAAK;AACvB,UAAM,YAAY,OAAO,KAAK,MAAM,IAAI,GAAG;AAC3C,UAAM,SAAS,OAAO,SAAS;AAC/B,UAAM,WAAW,aAAa,YAAY;AAG1C,UAAM,UAAU,MAAM,cAAc,IAAI,QAAQ,KAAK;AACrD,UAAM,cAAc,IAAI,UAAU,UAAU,MAAM;AAGlD,SAAK,yBAAyB,OAAO,cAAyB,MAAM;AAAA,EACtE;AAAA,EAEQ,gBAAgB,QAA4C;AAClE,QAAI,OAAO,QAAQ;AAEjB,aAAO,KAAK,cAAc,OAAO,QAAQ,OAAO,OAAO,OAAO,YAAY;AAAA,IAC5E;AACA,WAAO,OAAO,YAAY,CAAC;AAAA,EAC7B;AAAA,EAEQ,cACN,QACA,OACA,SAAkC,CAAC,GACnB;AAEhB,YAAQ,QAAQ;AAAA,MACd,KAAK;AACH,eAAO;AAAA,UACL;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN;AAAA,gBACE,OAAO;AAAA,gBACP,OAAQ,OAAO,qBAA4B,yBAAW,GAAG;AAAA,gBACzD,QAAQ;AAAA,cACV;AAAA,YACF;AAAA,UACF;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,UAAW,OAAO,YAAwB;AAAA,YAC1C,kBAAkB;AAAA,UACpB;AAAA,QACF;AAAA,MACF,KAAK;AACH,eAAO;AAAA,UACL;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN;AAAA,gBACE,OAAO;AAAA,gBACP,OAAQ,OAAO,sBAA6B,yBAAW,GAAG;AAAA,gBAC1D,QAAQ;AAAA,cACV;AAAA,YACF;AAAA,UACF;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,UAAW,OAAO,YAAwB;AAAA,YAC1C,kBAAkB;AAAA,UACpB;AAAA,QACF;AAAA,MACF,KAAK,iBAAiB;AACpB,cAAM,WAA2B;AAAA,UAC/B;AAAA,YACE,MAAM;AAAA,YACN,QAAQ;AAAA,cACN;AAAA,gBACE,OAAO;AAAA,gBACP,OAAQ,OAAO,kBAAyB,yBAAW,KAAK;AAAA,gBACxD,QAAQ;AAAA,cACV;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,cAAM,aAAa,OAAO;AAC1B,YAAI,YAAY,QAAQ;AACtB,mBAAS,KAAK;AAAA,YACZ,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS,WAAW,IAAI,CAAC,UAAU,EAAE,SAAS,KAAK,EAAE;AAAA,UACvD,CAAC;AAAA,QACH;AACA,iBAAS,KAAK;AAAA,UACZ,MAAM;AAAA,UACN,UAAW,OAAO,YAAwB;AAAA,UAC1C,kBAAkB;AAAA,QACpB,CAAC;AACD,eAAO;AAAA,MACT;AAAA,MACA,KAAK;AACH,eAAO;AAAA,UACL;AAAA,YACE,MAAM;AAAA,YACN,UAAW,OAAO,YAAwB;AAAA,YAC1C,kBAAkB;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AACE,eAAO,CAAC;AAAA,IACZ;AAAA,EACF;AAAA,EAEQ,YAAY,OAAwB,QAA4B;AACtE,YAAQ,OAAO,MAAM;AAAA,MACnB,KAAK;AACH,mBAAW,SAAS,OAAO,QAAQ;AACjC,gBAAM,eAAe,IAAI,MAAM,MAAM,YAAY,GAAG;AAAA,YAClD,OAAO,MAAM;AAAA,YACb,QAAQ,MAAM;AAAA,UAChB,CAAC;AAAA,QACH;AACA;AAAA,MACF,KAAK;AACH,cAAM,gBAAgB,OAAO;AAC7B,mBAAW,UAAU,OAAO,SAAS;AACnC,gBAAM,iBAAiB,IAAI,OAAO,QAAQ,YAAY,CAAC;AAAA,QACzD;AACA;AAAA,MACF,KAAK;AACH,cAAM,WAAW,OAAO;AACxB;AAAA,MACF,KAAK;AAEH;AAAA,IACJ;AAAA,EACF;AAAA,EAEQ,cAAc,OAAqC;AACzD,WAAO;AAAA,MACL,SAAS,MAAM;AAAA,MACf,OAAO,MAAM;AAAA,MACb,OAAO,EAAE,IAAI,OAAO,MAAM,eAAe;AAAA,MACzC,YAAY,MAAM;AAAA,MAClB,UAAU,MAAM,SAAS,IAAI,CAAC,OAAO;AAAA,QACnC,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,MAAM,EAAE;AAAA,QACR,QAAQ;AAAA,MACV,EAAE;AAAA,MACF,UAAU,MAAM;AAAA,IAClB;AAAA,EACF;AAAA,EAEQ,YAAY,SAAyB;AAC3C,UAAM,UAAkC;AAAA,MACtC,8CAA8C;AAAA,MAC9C,8CAA8C;AAAA,MAC9C,8CAA8C;AAAA,IAChD;AACA,WAAO,QAAQ,QAAQ,YAAY,CAAC,KAAK;AAAA,EAC3C;AAAA,EAEQ,aAAkB;AACxB,UAAM,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO,IAAI,GAAG;AAC/D,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA,EAEQ,OAAO,WAAmB,SAAwC;AACxE,UAAM,QAAsB;AAAA,MAC1B,WAAW,KAAK,IAAI;AAAA,MACpB;AAAA,MACA;AAAA,IACF;AACA,SAAK,IAAI,KAAK,KAAK;AACnB,QAAI,KAAK,SAAS;AAChB,cAAQ,IAAI,UAAU,SAAS,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA,IAC7D;AAAA,EACF;AACF;","names":["import_viem"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,426 @@
1
+ // src/mock-client.ts
2
+ import { parseEther as parseEther2 } from "viem";
3
+ import {
4
+ SpendingLimitExceededError,
5
+ WalletPausedError,
6
+ ExecutionError
7
+ } from "@smartagentkit/sdk";
8
+
9
+ // src/mock-state.ts
10
+ import { parseEther } from "viem";
11
+ function createDefaultState(address, owner, initialBalance = parseEther("10")) {
12
+ return {
13
+ address,
14
+ owner,
15
+ isDeployed: true,
16
+ paused: false,
17
+ ethBalance: initialBalance,
18
+ tokenBalances: /* @__PURE__ */ new Map(),
19
+ spendingUsed: /* @__PURE__ */ new Map(),
20
+ spendingLimits: /* @__PURE__ */ new Map(),
21
+ allowlistMode: null,
22
+ allowlistTargets: /* @__PURE__ */ new Set(),
23
+ policies: [],
24
+ sessions: [],
25
+ guardian: null
26
+ };
27
+ }
28
+ function deterministicAddress(seed) {
29
+ const hex = seed.toString(16).padStart(40, "0");
30
+ return `0x${hex}`;
31
+ }
32
+
33
+ // src/mock-client.ts
34
+ var NATIVE_TOKEN = "0x0000000000000000000000000000000000000000";
35
+ var TRANSFER_SELECTOR = "0xa9059cbb";
36
+ var MockSmartAgentKitClient = class {
37
+ wallets = /* @__PURE__ */ new Map();
38
+ log = [];
39
+ verbose;
40
+ defaultBalance;
41
+ defaultTokenBalances;
42
+ walletCounter = 1;
43
+ constructor(options = {}) {
44
+ this.verbose = options.verbose ?? false;
45
+ this.defaultBalance = options.initialBalance ?? parseEther2("10");
46
+ this.defaultTokenBalances = options.tokenBalances ?? {};
47
+ }
48
+ // ─── Wallet Management ────────────────────────────────────────
49
+ async createWallet(params) {
50
+ const address = deterministicAddress(this.walletCounter++);
51
+ const state = createDefaultState(address, params.owner, this.defaultBalance);
52
+ for (const [token, balance] of Object.entries(this.defaultTokenBalances)) {
53
+ state.tokenBalances.set(token.toLowerCase(), balance);
54
+ }
55
+ const policies = this.resolvePolicies(params);
56
+ state.policies = policies;
57
+ for (const policy of policies) {
58
+ this.applyPolicy(state, policy);
59
+ }
60
+ this.wallets.set(address.toLowerCase(), state);
61
+ this.addLog("createWallet", { address, owner: params.owner, preset: params.preset });
62
+ return this.stateToWallet(state);
63
+ }
64
+ async connectWallet(walletAddress, _ownerKey) {
65
+ const key = walletAddress.toLowerCase();
66
+ if (!this.wallets.has(key)) {
67
+ const state = createDefaultState(walletAddress, walletAddress, this.defaultBalance);
68
+ for (const [token, balance] of Object.entries(this.defaultTokenBalances)) {
69
+ state.tokenBalances.set(token.toLowerCase(), balance);
70
+ }
71
+ this.wallets.set(key, state);
72
+ }
73
+ this.addLog("connectWallet", { address: walletAddress });
74
+ }
75
+ // ─── Execution ────────────────────────────────────────────────
76
+ async execute(wallet, params) {
77
+ const state = this.getState(wallet.address);
78
+ this.enforceNotPaused(state);
79
+ const value = params.value ?? 0n;
80
+ this.enforceAllowlist(state, params.target);
81
+ if (value > 0n) {
82
+ this.enforceAndDeductSpending(state, NATIVE_TOKEN, value);
83
+ state.ethBalance -= value;
84
+ }
85
+ if (params.data && params.data.startsWith(TRANSFER_SELECTOR)) {
86
+ this.deductTokenTransfer(state, params.target, params.data);
87
+ }
88
+ const txHash = this.fakeTxHash();
89
+ this.addLog("execute", {
90
+ target: params.target,
91
+ value: value.toString(),
92
+ txHash
93
+ });
94
+ return txHash;
95
+ }
96
+ async executeBatch(wallet, params) {
97
+ const state = this.getState(wallet.address);
98
+ this.enforceNotPaused(state);
99
+ const deductions = [];
100
+ for (const call of params.calls) {
101
+ const value = call.value ?? 0n;
102
+ this.enforceAllowlist(state, call.target);
103
+ if (value > 0n) {
104
+ const tokenKey = NATIVE_TOKEN.toLowerCase();
105
+ const limitEntry = state.spendingLimits.get(tokenKey);
106
+ if (limitEntry) {
107
+ const used = state.spendingUsed.get(tokenKey) ?? 0n;
108
+ const totalPending = deductions.filter((d) => d.token === tokenKey).reduce((sum, d) => sum + d.amount, 0n);
109
+ const remaining = limitEntry.limit - used - totalPending;
110
+ if (value > remaining) {
111
+ throw new SpendingLimitExceededError(NATIVE_TOKEN, value, remaining);
112
+ }
113
+ }
114
+ deductions.push({ token: tokenKey, amount: value });
115
+ }
116
+ }
117
+ for (const { token, amount } of deductions) {
118
+ const used = state.spendingUsed.get(token) ?? 0n;
119
+ state.spendingUsed.set(token, used + amount);
120
+ if (token === NATIVE_TOKEN.toLowerCase()) {
121
+ state.ethBalance -= amount;
122
+ }
123
+ }
124
+ const txHash = this.fakeTxHash();
125
+ this.addLog("executeBatch", {
126
+ callCount: params.calls.length,
127
+ txHash
128
+ });
129
+ return txHash;
130
+ }
131
+ // ─── Query Functions ──────────────────────────────────────────
132
+ async getRemainingAllowance(walletAddress, token) {
133
+ const state = this.getState(walletAddress);
134
+ const tokenKey = token.toLowerCase();
135
+ const limitEntry = state.spendingLimits.get(tokenKey);
136
+ if (!limitEntry) return parseEther2("999999");
137
+ const used = state.spendingUsed.get(tokenKey) ?? 0n;
138
+ return limitEntry.limit - used;
139
+ }
140
+ async isPaused(walletAddress) {
141
+ const state = this.getState(walletAddress);
142
+ return state.paused;
143
+ }
144
+ async getBalances(walletAddress) {
145
+ const state = this.getState(walletAddress);
146
+ const tokens = [];
147
+ for (const [addr, balance] of state.tokenBalances) {
148
+ tokens.push({
149
+ address: addr,
150
+ symbol: this.tokenSymbol(addr),
151
+ balance
152
+ });
153
+ }
154
+ return { eth: state.ethBalance, tokens };
155
+ }
156
+ // ─── Guardian Actions ─────────────────────────────────────────
157
+ async pause(walletAddress, _guardianKey) {
158
+ const state = this.getState(walletAddress);
159
+ state.paused = true;
160
+ const txHash = this.fakeTxHash();
161
+ this.addLog("pause", { address: walletAddress, txHash });
162
+ return txHash;
163
+ }
164
+ async unpause(walletAddress, _guardianKey) {
165
+ const state = this.getState(walletAddress);
166
+ state.paused = false;
167
+ const txHash = this.fakeTxHash();
168
+ this.addLog("unpause", { address: walletAddress, txHash });
169
+ return txHash;
170
+ }
171
+ // ─── Session Management ───────────────────────────────────────
172
+ async createSession(wallet, params, _ownerKey) {
173
+ const state = this.getState(wallet.address);
174
+ const sessionKey = deterministicAddress(Date.now() % 1e5);
175
+ const privateKey = `0x${"ab".repeat(32)}`;
176
+ const permissionId = `0x${"cd".repeat(32)}`;
177
+ const session = {
178
+ sessionKey,
179
+ actions: params.actions,
180
+ expiresAt: params.expiresAt,
181
+ isActive: true
182
+ };
183
+ state.sessions.push(session);
184
+ this.addLog("createSession", {
185
+ wallet: wallet.address,
186
+ sessionKey,
187
+ expiresAt: params.expiresAt
188
+ });
189
+ return { sessionKey, privateKey, permissionId };
190
+ }
191
+ async revokeSession(wallet, permissionId, _ownerKey) {
192
+ const state = this.getState(wallet.address);
193
+ state.sessions = state.sessions.filter((s) => s.isActive);
194
+ if (state.sessions.length > 0) {
195
+ state.sessions[state.sessions.length - 1].isActive = false;
196
+ }
197
+ this.addLog("revokeSession", { wallet: wallet.address, permissionId });
198
+ }
199
+ getActiveSessions(walletAddress) {
200
+ const state = this.getState(walletAddress);
201
+ const now = Math.floor(Date.now() / 1e3);
202
+ return state.sessions.filter((s) => s.isActive && s.expiresAt > now);
203
+ }
204
+ // ─── Mock-Specific Methods ────────────────────────────────────
205
+ /** Get the full operation log for inspection */
206
+ getLog() {
207
+ return [...this.log];
208
+ }
209
+ /** Directly manipulate wallet state for test setup */
210
+ setState(walletAddress, updates) {
211
+ const state = this.getState(walletAddress);
212
+ if (updates.ethBalance !== void 0) state.ethBalance = updates.ethBalance;
213
+ if (updates.paused !== void 0) state.paused = updates.paused;
214
+ if (updates.tokenBalances !== void 0) state.tokenBalances = updates.tokenBalances;
215
+ if (updates.spendingUsed !== void 0) state.spendingUsed = updates.spendingUsed;
216
+ if (updates.allowlistMode !== void 0) state.allowlistMode = updates.allowlistMode;
217
+ if (updates.allowlistTargets !== void 0) state.allowlistTargets = updates.allowlistTargets;
218
+ if (updates.spendingLimits !== void 0) state.spendingLimits = updates.spendingLimits;
219
+ if (updates.guardian !== void 0) state.guardian = updates.guardian;
220
+ }
221
+ /** Get current wallet state (read-only copy) */
222
+ getWalletState(walletAddress) {
223
+ return { ...this.getState(walletAddress) };
224
+ }
225
+ // ─── Private Helpers ──────────────────────────────────────────
226
+ getState(walletAddress) {
227
+ const state = this.wallets.get(walletAddress.toLowerCase());
228
+ if (!state) {
229
+ throw new ExecutionError(
230
+ `No wallet found at ${walletAddress}. Call createWallet() or connectWallet() first.`
231
+ );
232
+ }
233
+ return state;
234
+ }
235
+ enforceNotPaused(state) {
236
+ if (state.paused) {
237
+ throw new WalletPausedError(state.address);
238
+ }
239
+ }
240
+ enforceAllowlist(state, target) {
241
+ if (state.allowlistMode === "allow") {
242
+ if (!state.allowlistTargets.has(target.toLowerCase())) {
243
+ throw new ExecutionError(
244
+ `Target ${target} is not on the allowlist`
245
+ );
246
+ }
247
+ } else if (state.allowlistMode === "block") {
248
+ if (state.allowlistTargets.has(target.toLowerCase())) {
249
+ throw new ExecutionError(
250
+ `Target ${target} is on the blocklist`
251
+ );
252
+ }
253
+ }
254
+ }
255
+ enforceAndDeductSpending(state, token, amount) {
256
+ const tokenKey = token.toLowerCase();
257
+ const limitEntry = state.spendingLimits.get(tokenKey);
258
+ if (!limitEntry) return;
259
+ const used = state.spendingUsed.get(tokenKey) ?? 0n;
260
+ const remaining = limitEntry.limit - used;
261
+ if (amount > remaining) {
262
+ throw new SpendingLimitExceededError(token, amount, remaining);
263
+ }
264
+ state.spendingUsed.set(tokenKey, used + amount);
265
+ }
266
+ deductTokenTransfer(state, tokenAddress, data) {
267
+ if (data.length < 138) return;
268
+ const amountHex = "0x" + data.slice(74, 138);
269
+ const amount = BigInt(amountHex);
270
+ const tokenKey = tokenAddress.toLowerCase();
271
+ const balance = state.tokenBalances.get(tokenKey) ?? 0n;
272
+ state.tokenBalances.set(tokenKey, balance - amount);
273
+ this.enforceAndDeductSpending(state, tokenAddress, amount);
274
+ }
275
+ resolvePolicies(params) {
276
+ if (params.preset) {
277
+ return this.resolvePreset(params.preset, params.owner, params.presetParams);
278
+ }
279
+ return params.policies ?? [];
280
+ }
281
+ resolvePreset(preset, owner, params = {}) {
282
+ switch (preset) {
283
+ case "defi-trader":
284
+ return [
285
+ {
286
+ type: "spending-limit",
287
+ limits: [
288
+ {
289
+ token: NATIVE_TOKEN,
290
+ limit: params.dailyEthLimit ?? parseEther2("1"),
291
+ window: 86400
292
+ }
293
+ ]
294
+ },
295
+ {
296
+ type: "emergency-pause",
297
+ guardian: params.guardian ?? owner,
298
+ autoUnpauseAfter: 86400
299
+ }
300
+ ];
301
+ case "treasury-agent":
302
+ return [
303
+ {
304
+ type: "spending-limit",
305
+ limits: [
306
+ {
307
+ token: NATIVE_TOKEN,
308
+ limit: params.weeklyEthLimit ?? parseEther2("5"),
309
+ window: 604800
310
+ }
311
+ ]
312
+ },
313
+ {
314
+ type: "emergency-pause",
315
+ guardian: params.guardian ?? owner,
316
+ autoUnpauseAfter: 0
317
+ }
318
+ ];
319
+ case "payment-agent": {
320
+ const policies = [
321
+ {
322
+ type: "spending-limit",
323
+ limits: [
324
+ {
325
+ token: NATIVE_TOKEN,
326
+ limit: params.dailyLimit ?? parseEther2("0.1"),
327
+ window: 86400
328
+ }
329
+ ]
330
+ }
331
+ ];
332
+ const recipients = params.approvedRecipients;
333
+ if (recipients?.length) {
334
+ policies.push({
335
+ type: "allowlist",
336
+ mode: "allow",
337
+ targets: recipients.map((addr) => ({ address: addr }))
338
+ });
339
+ }
340
+ policies.push({
341
+ type: "emergency-pause",
342
+ guardian: params.guardian ?? owner,
343
+ autoUnpauseAfter: 3600
344
+ });
345
+ return policies;
346
+ }
347
+ case "minimal":
348
+ return [
349
+ {
350
+ type: "emergency-pause",
351
+ guardian: params.guardian ?? owner,
352
+ autoUnpauseAfter: 0
353
+ }
354
+ ];
355
+ default:
356
+ return [];
357
+ }
358
+ }
359
+ applyPolicy(state, policy) {
360
+ switch (policy.type) {
361
+ case "spending-limit":
362
+ for (const limit of policy.limits) {
363
+ state.spendingLimits.set(limit.token.toLowerCase(), {
364
+ limit: limit.limit,
365
+ window: limit.window
366
+ });
367
+ }
368
+ break;
369
+ case "allowlist":
370
+ state.allowlistMode = policy.mode;
371
+ for (const target of policy.targets) {
372
+ state.allowlistTargets.add(target.address.toLowerCase());
373
+ }
374
+ break;
375
+ case "emergency-pause":
376
+ state.guardian = policy.guardian;
377
+ break;
378
+ case "automation":
379
+ break;
380
+ }
381
+ }
382
+ stateToWallet(state) {
383
+ return {
384
+ address: state.address,
385
+ owner: state.owner,
386
+ chain: { id: 84532, name: "Base Sepolia" },
387
+ isDeployed: state.isDeployed,
388
+ policies: state.policies.map((p) => ({
389
+ moduleAddress: NATIVE_TOKEN,
390
+ moduleType: 4,
391
+ name: p.type,
392
+ config: p
393
+ })),
394
+ sessions: state.sessions
395
+ };
396
+ }
397
+ tokenSymbol(address) {
398
+ const symbols = {
399
+ "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48": "USDC",
400
+ "0xdac17f958d2ee523a2206206994597c13d831ec7": "USDT",
401
+ "0x6b175474e89094c44da98b954eedeac495271d0f": "DAI"
402
+ };
403
+ return symbols[address.toLowerCase()] ?? "TOKEN";
404
+ }
405
+ fakeTxHash() {
406
+ const rand = Math.random().toString(16).slice(2).padEnd(64, "0");
407
+ return `0x${rand}`;
408
+ }
409
+ addLog(operation, details) {
410
+ const entry = {
411
+ timestamp: Date.now(),
412
+ operation,
413
+ details
414
+ };
415
+ this.log.push(entry);
416
+ if (this.verbose) {
417
+ console.log(`[mock] ${operation}:`, JSON.stringify(details));
418
+ }
419
+ }
420
+ };
421
+ export {
422
+ MockSmartAgentKitClient,
423
+ createDefaultState,
424
+ deterministicAddress
425
+ };
426
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mock-client.ts","../src/mock-state.ts"],"sourcesContent":["import { parseEther, type Address, type Hex, type Chain } from \"viem\";\nimport type {\n AgentWallet,\n CreateWalletParams,\n ExecuteParams,\n ExecuteBatchParams,\n CreateSessionParams,\n ActiveSession,\n InstalledPolicy,\n PolicyConfig,\n TokenLimit,\n SignerKey,\n ISmartAgentKitClient,\n} from \"@smartagentkit/sdk\";\nimport {\n SpendingLimitExceededError,\n WalletPausedError,\n ExecutionError,\n SessionError,\n} from \"@smartagentkit/sdk\";\nimport type { MockClientOptions, MockLogEntry, MockWalletState } from \"./types.js\";\nimport { createDefaultState, deterministicAddress } from \"./mock-state.js\";\n\nconst NATIVE_TOKEN = \"0x0000000000000000000000000000000000000000\" as Address;\n\n// ERC-20 transfer selector: transfer(address,uint256)\nconst TRANSFER_SELECTOR = \"0xa9059cbb\";\n\n/**\n * In-memory mock of SmartAgentKitClient for running examples\n * without funded wallets, deployed contracts, or RPC connections.\n *\n * Mirrors the real client's public API but operates entirely in memory.\n */\nexport class MockSmartAgentKitClient implements ISmartAgentKitClient {\n private wallets: Map<string, MockWalletState> = new Map();\n private log: MockLogEntry[] = [];\n private verbose: boolean;\n private defaultBalance: bigint;\n private defaultTokenBalances: Record<string, bigint>;\n private walletCounter = 1;\n\n constructor(options: MockClientOptions = {}) {\n this.verbose = options.verbose ?? false;\n this.defaultBalance = options.initialBalance ?? parseEther(\"10\");\n this.defaultTokenBalances = options.tokenBalances ?? {};\n }\n\n // ─── Wallet Management ────────────────────────────────────────\n\n async createWallet(params: CreateWalletParams): Promise<AgentWallet> {\n const address = deterministicAddress(this.walletCounter++);\n const state = createDefaultState(address, params.owner, this.defaultBalance);\n\n // Apply default token balances\n for (const [token, balance] of Object.entries(this.defaultTokenBalances)) {\n state.tokenBalances.set(token.toLowerCase(), balance);\n }\n\n // Resolve policies\n const policies = this.resolvePolicies(params);\n state.policies = policies;\n\n // Apply policy effects to state\n for (const policy of policies) {\n this.applyPolicy(state, policy);\n }\n\n this.wallets.set(address.toLowerCase(), state);\n this.addLog(\"createWallet\", { address, owner: params.owner, preset: params.preset });\n\n return this.stateToWallet(state);\n }\n\n async connectWallet(walletAddress: Address, _ownerKey: SignerKey): Promise<void> {\n const key = walletAddress.toLowerCase();\n if (!this.wallets.has(key)) {\n // Create a minimal state for the connected wallet\n const state = createDefaultState(walletAddress, walletAddress, this.defaultBalance);\n for (const [token, balance] of Object.entries(this.defaultTokenBalances)) {\n state.tokenBalances.set(token.toLowerCase(), balance);\n }\n this.wallets.set(key, state);\n }\n this.addLog(\"connectWallet\", { address: walletAddress });\n }\n\n // ─── Execution ────────────────────────────────────────────────\n\n async execute(wallet: AgentWallet, params: ExecuteParams): Promise<Hex> {\n const state = this.getState(wallet.address);\n this.enforceNotPaused(state);\n\n const value = params.value ?? 0n;\n\n // Check allowlist\n this.enforceAllowlist(state, params.target);\n\n // Calculate spending (ETH value + token transfers)\n if (value > 0n) {\n this.enforceAndDeductSpending(state, NATIVE_TOKEN, value);\n state.ethBalance -= value;\n }\n\n // Detect ERC-20 transfer from calldata\n if (params.data && params.data.startsWith(TRANSFER_SELECTOR)) {\n this.deductTokenTransfer(state, params.target, params.data);\n }\n\n const txHash = this.fakeTxHash();\n this.addLog(\"execute\", {\n target: params.target,\n value: value.toString(),\n txHash,\n });\n return txHash;\n }\n\n async executeBatch(wallet: AgentWallet, params: ExecuteBatchParams): Promise<Hex> {\n const state = this.getState(wallet.address);\n this.enforceNotPaused(state);\n\n // Validate all calls first (atomic: all-or-nothing)\n const deductions: Array<{ token: string; amount: bigint }> = [];\n for (const call of params.calls) {\n const value = call.value ?? 0n;\n this.enforceAllowlist(state, call.target);\n\n if (value > 0n) {\n // Check spending limit without deducting yet\n const tokenKey = NATIVE_TOKEN.toLowerCase();\n const limitEntry = state.spendingLimits.get(tokenKey);\n if (limitEntry) {\n const used = state.spendingUsed.get(tokenKey) ?? 0n;\n const totalPending = deductions\n .filter((d) => d.token === tokenKey)\n .reduce((sum, d) => sum + d.amount, 0n);\n const remaining = limitEntry.limit - used - totalPending;\n if (value > remaining) {\n throw new SpendingLimitExceededError(NATIVE_TOKEN, value, remaining);\n }\n }\n deductions.push({ token: tokenKey, amount: value });\n }\n }\n\n // Apply all deductions\n for (const { token, amount } of deductions) {\n const used = state.spendingUsed.get(token) ?? 0n;\n state.spendingUsed.set(token, used + amount);\n if (token === NATIVE_TOKEN.toLowerCase()) {\n state.ethBalance -= amount;\n }\n }\n\n const txHash = this.fakeTxHash();\n this.addLog(\"executeBatch\", {\n callCount: params.calls.length,\n txHash,\n });\n return txHash;\n }\n\n // ─── Query Functions ──────────────────────────────────────────\n\n async getRemainingAllowance(walletAddress: Address, token: Address): Promise<bigint> {\n const state = this.getState(walletAddress);\n const tokenKey = token.toLowerCase();\n const limitEntry = state.spendingLimits.get(tokenKey);\n if (!limitEntry) return parseEther(\"999999\"); // No limit configured\n const used = state.spendingUsed.get(tokenKey) ?? 0n;\n return limitEntry.limit - used;\n }\n\n async isPaused(walletAddress: Address): Promise<boolean> {\n const state = this.getState(walletAddress);\n return state.paused;\n }\n\n async getBalances(walletAddress: Address): Promise<{\n eth: bigint;\n tokens: { address: Address; symbol: string; balance: bigint }[];\n }> {\n const state = this.getState(walletAddress);\n const tokens: { address: Address; symbol: string; balance: bigint }[] = [];\n for (const [addr, balance] of state.tokenBalances) {\n tokens.push({\n address: addr as Address,\n symbol: this.tokenSymbol(addr),\n balance,\n });\n }\n return { eth: state.ethBalance, tokens };\n }\n\n // ─── Guardian Actions ─────────────────────────────────────────\n\n async pause(walletAddress: Address, _guardianKey: SignerKey): Promise<Hex> {\n const state = this.getState(walletAddress);\n state.paused = true;\n const txHash = this.fakeTxHash();\n this.addLog(\"pause\", { address: walletAddress, txHash });\n return txHash;\n }\n\n async unpause(walletAddress: Address, _guardianKey: SignerKey): Promise<Hex> {\n const state = this.getState(walletAddress);\n state.paused = false;\n const txHash = this.fakeTxHash();\n this.addLog(\"unpause\", { address: walletAddress, txHash });\n return txHash;\n }\n\n // ─── Session Management ───────────────────────────────────────\n\n async createSession(\n wallet: AgentWallet,\n params: CreateSessionParams,\n _ownerKey: SignerKey,\n ): Promise<{ sessionKey: Address; privateKey: Hex; permissionId: Hex }> {\n const state = this.getState(wallet.address);\n\n const sessionKey = deterministicAddress(Date.now() % 100000);\n const privateKey = `0x${\"ab\".repeat(32)}` as Hex;\n const permissionId = `0x${\"cd\".repeat(32)}` as Hex;\n\n const session: ActiveSession = {\n sessionKey,\n actions: params.actions,\n expiresAt: params.expiresAt,\n isActive: true,\n };\n state.sessions.push(session);\n\n this.addLog(\"createSession\", {\n wallet: wallet.address,\n sessionKey,\n expiresAt: params.expiresAt,\n });\n\n return { sessionKey, privateKey, permissionId };\n }\n\n async revokeSession(\n wallet: AgentWallet,\n permissionId: Hex,\n _ownerKey: SignerKey,\n ): Promise<void> {\n const state = this.getState(wallet.address);\n // Remove the most recent session (simplified — real impl uses permissionId)\n state.sessions = state.sessions.filter((s) => s.isActive);\n if (state.sessions.length > 0) {\n state.sessions[state.sessions.length - 1].isActive = false;\n }\n this.addLog(\"revokeSession\", { wallet: wallet.address, permissionId });\n }\n\n getActiveSessions(walletAddress: Address): ActiveSession[] {\n const state = this.getState(walletAddress);\n const now = Math.floor(Date.now() / 1000);\n return state.sessions.filter((s) => s.isActive && s.expiresAt > now);\n }\n\n // ─── Mock-Specific Methods ────────────────────────────────────\n\n /** Get the full operation log for inspection */\n getLog(): MockLogEntry[] {\n return [...this.log];\n }\n\n /** Directly manipulate wallet state for test setup */\n setState(walletAddress: Address, updates: Partial<MockWalletState>): void {\n const state = this.getState(walletAddress);\n if (updates.ethBalance !== undefined) state.ethBalance = updates.ethBalance;\n if (updates.paused !== undefined) state.paused = updates.paused;\n if (updates.tokenBalances !== undefined) state.tokenBalances = updates.tokenBalances;\n if (updates.spendingUsed !== undefined) state.spendingUsed = updates.spendingUsed;\n if (updates.allowlistMode !== undefined) state.allowlistMode = updates.allowlistMode;\n if (updates.allowlistTargets !== undefined) state.allowlistTargets = updates.allowlistTargets;\n if (updates.spendingLimits !== undefined) state.spendingLimits = updates.spendingLimits;\n if (updates.guardian !== undefined) state.guardian = updates.guardian;\n }\n\n /** Get current wallet state (read-only copy) */\n getWalletState(walletAddress: Address): MockWalletState {\n return { ...this.getState(walletAddress) };\n }\n\n // ─── Private Helpers ──────────────────────────────────────────\n\n private getState(walletAddress: Address): MockWalletState {\n const state = this.wallets.get(walletAddress.toLowerCase());\n if (!state) {\n throw new ExecutionError(\n `No wallet found at ${walletAddress}. Call createWallet() or connectWallet() first.`,\n );\n }\n return state;\n }\n\n private enforceNotPaused(state: MockWalletState): void {\n if (state.paused) {\n throw new WalletPausedError(state.address);\n }\n }\n\n private enforceAllowlist(state: MockWalletState, target: Address): void {\n if (state.allowlistMode === \"allow\") {\n if (!state.allowlistTargets.has(target.toLowerCase())) {\n throw new ExecutionError(\n `Target ${target} is not on the allowlist`,\n );\n }\n } else if (state.allowlistMode === \"block\") {\n if (state.allowlistTargets.has(target.toLowerCase())) {\n throw new ExecutionError(\n `Target ${target} is on the blocklist`,\n );\n }\n }\n }\n\n private enforceAndDeductSpending(\n state: MockWalletState,\n token: Address,\n amount: bigint,\n ): void {\n const tokenKey = token.toLowerCase();\n const limitEntry = state.spendingLimits.get(tokenKey);\n if (!limitEntry) return; // No limit configured\n\n const used = state.spendingUsed.get(tokenKey) ?? 0n;\n const remaining = limitEntry.limit - used;\n\n if (amount > remaining) {\n throw new SpendingLimitExceededError(token, amount, remaining);\n }\n\n state.spendingUsed.set(tokenKey, used + amount);\n }\n\n private deductTokenTransfer(\n state: MockWalletState,\n tokenAddress: Address,\n data: Hex,\n ): void {\n // Extract amount from transfer(address,uint256) calldata\n // Selector (4 bytes) + address (32 bytes) + uint256 (32 bytes) = 68 bytes\n if (data.length < 138) return; // \"0x\" + 4 + 32 + 32 hex chars = 2 + 136\n const amountHex = \"0x\" + data.slice(74, 138);\n const amount = BigInt(amountHex);\n const tokenKey = tokenAddress.toLowerCase();\n\n // Deduct from token balance\n const balance = state.tokenBalances.get(tokenKey) ?? 0n;\n state.tokenBalances.set(tokenKey, balance - amount);\n\n // Enforce spending limit for token\n this.enforceAndDeductSpending(state, tokenAddress as Address, amount);\n }\n\n private resolvePolicies(params: CreateWalletParams): PolicyConfig[] {\n if (params.preset) {\n // Import and resolve presets from SDK\n return this.resolvePreset(params.preset, params.owner, params.presetParams);\n }\n return params.policies ?? [];\n }\n\n private resolvePreset(\n preset: string,\n owner: Address,\n params: Record<string, unknown> = {},\n ): PolicyConfig[] {\n // Simplified preset resolution matching SDK presets\n switch (preset) {\n case \"defi-trader\":\n return [\n {\n type: \"spending-limit\",\n limits: [\n {\n token: NATIVE_TOKEN,\n limit: (params.dailyEthLimit as bigint) ?? parseEther(\"1\"),\n window: 86400,\n },\n ],\n },\n {\n type: \"emergency-pause\",\n guardian: (params.guardian as Address) ?? owner,\n autoUnpauseAfter: 86400,\n },\n ];\n case \"treasury-agent\":\n return [\n {\n type: \"spending-limit\",\n limits: [\n {\n token: NATIVE_TOKEN,\n limit: (params.weeklyEthLimit as bigint) ?? parseEther(\"5\"),\n window: 604800,\n },\n ],\n },\n {\n type: \"emergency-pause\",\n guardian: (params.guardian as Address) ?? owner,\n autoUnpauseAfter: 0,\n },\n ];\n case \"payment-agent\": {\n const policies: PolicyConfig[] = [\n {\n type: \"spending-limit\",\n limits: [\n {\n token: NATIVE_TOKEN,\n limit: (params.dailyLimit as bigint) ?? parseEther(\"0.1\"),\n window: 86400,\n },\n ],\n },\n ];\n const recipients = params.approvedRecipients as Address[] | undefined;\n if (recipients?.length) {\n policies.push({\n type: \"allowlist\",\n mode: \"allow\",\n targets: recipients.map((addr) => ({ address: addr })),\n });\n }\n policies.push({\n type: \"emergency-pause\",\n guardian: (params.guardian as Address) ?? owner,\n autoUnpauseAfter: 3600,\n });\n return policies;\n }\n case \"minimal\":\n return [\n {\n type: \"emergency-pause\",\n guardian: (params.guardian as Address) ?? owner,\n autoUnpauseAfter: 0,\n },\n ];\n default:\n return [];\n }\n }\n\n private applyPolicy(state: MockWalletState, policy: PolicyConfig): void {\n switch (policy.type) {\n case \"spending-limit\":\n for (const limit of policy.limits) {\n state.spendingLimits.set(limit.token.toLowerCase(), {\n limit: limit.limit,\n window: limit.window,\n });\n }\n break;\n case \"allowlist\":\n state.allowlistMode = policy.mode;\n for (const target of policy.targets) {\n state.allowlistTargets.add(target.address.toLowerCase());\n }\n break;\n case \"emergency-pause\":\n state.guardian = policy.guardian;\n break;\n case \"automation\":\n // Not relevant for mock\n break;\n }\n }\n\n private stateToWallet(state: MockWalletState): AgentWallet {\n return {\n address: state.address,\n owner: state.owner,\n chain: { id: 84532, name: \"Base Sepolia\" } as Chain,\n isDeployed: state.isDeployed,\n policies: state.policies.map((p) => ({\n moduleAddress: NATIVE_TOKEN,\n moduleType: 4,\n name: p.type,\n config: p,\n })),\n sessions: state.sessions,\n };\n }\n\n private tokenSymbol(address: string): string {\n const symbols: Record<string, string> = {\n \"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48\": \"USDC\",\n \"0xdac17f958d2ee523a2206206994597c13d831ec7\": \"USDT\",\n \"0x6b175474e89094c44da98b954eedeac495271d0f\": \"DAI\",\n };\n return symbols[address.toLowerCase()] ?? \"TOKEN\";\n }\n\n private fakeTxHash(): Hex {\n const rand = Math.random().toString(16).slice(2).padEnd(64, \"0\");\n return `0x${rand}` as Hex;\n }\n\n private addLog(operation: string, details: Record<string, unknown>): void {\n const entry: MockLogEntry = {\n timestamp: Date.now(),\n operation,\n details,\n };\n this.log.push(entry);\n if (this.verbose) {\n console.log(`[mock] ${operation}:`, JSON.stringify(details));\n }\n }\n}\n","import { parseEther, type Address } from \"viem\";\nimport type { MockWalletState } from \"./types.js\";\n\nconst ZERO_ADDRESS = \"0x0000000000000000000000000000000000000000\" as Address;\n\nexport function createDefaultState(\n address: Address,\n owner: Address,\n initialBalance: bigint = parseEther(\"10\"),\n): MockWalletState {\n return {\n address,\n owner,\n isDeployed: true,\n paused: false,\n ethBalance: initialBalance,\n tokenBalances: new Map(),\n spendingUsed: new Map(),\n spendingLimits: new Map(),\n allowlistMode: null,\n allowlistTargets: new Set(),\n policies: [],\n sessions: [],\n guardian: null,\n };\n}\n\n/** Generate a deterministic mock address from a seed */\nexport function deterministicAddress(seed: number): Address {\n const hex = seed.toString(16).padStart(40, \"0\");\n return `0x${hex}` as Address;\n}\n"],"mappings":"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","names":["parseEther","parseEther"]}
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@smartagentkit/testing",
3
+ "version": "0.1.0",
4
+ "description": "Mock client for SmartAgentKit — run examples without funded wallets or deployed contracts",
5
+ "license": "MIT",
6
+ "author": "SmartAgentKit Contributors",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/smartagentkit/smartagentkit.git",
10
+ "directory": "packages/testing"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/index.mjs",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.mjs",
19
+ "require": "./dist/index.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "dependencies": {
29
+ "viem": "^2.46.0",
30
+ "@smartagentkit/sdk": "0.1.0"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^22.0.0",
34
+ "tsup": "^8.4.0",
35
+ "vitest": "^3.0.0",
36
+ "typescript": "^5.7.0"
37
+ },
38
+ "scripts": {
39
+ "build": "tsup",
40
+ "test": "vitest run",
41
+ "test:watch": "vitest",
42
+ "lint": "tsc --noEmit",
43
+ "typecheck": "tsc --noEmit",
44
+ "clean": "rm -rf dist"
45
+ }
46
+ }