Skip to content

Commit 5bd46e2

Browse files
committed
test: add tests for makeAccount
1 parent 5c86bdd commit 5bd46e2

File tree

2 files changed

+229
-2
lines changed

2 files changed

+229
-2
lines changed

services/ymax-planner/src/watchers/wallet-watcher.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export const watchSmartWalletTx = ({
6565
const TO_TOPIC = zeroPadValue(expectedAddr.toLowerCase(), 32);
6666
const filter = {
6767
address: factoryAddr,
68-
topics: [SMART_WALLET_CREATED_SIGNATURE, null, TO_TOPIC],
68+
topics: [SMART_WALLET_CREATED_SIGNATURE, TO_TOPIC],
6969
};
7070

7171
log(`Watching SmartWalletCreated events emitted by ${factoryAddr}`);
@@ -148,7 +148,7 @@ export const lookBackSmartWalletTx = async ({
148148
const toTopic = zeroPadValue(expectedAddr.toLowerCase(), 32);
149149
const baseFilter: Filter = {
150150
address: factoryAddr,
151-
topics: [SMART_WALLET_CREATED_SIGNATURE, null, toTopic],
151+
topics: [SMART_WALLET_CREATED_SIGNATURE, toTopic],
152152
};
153153

154154
const matchingEvent = await scanEvmLogsInChunks(
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
import test from 'ava';
2+
import { id, zeroPadValue, AbiCoder, getAddress } from 'ethers';
3+
import { createMockPendingTxOpts } from './mocks.ts';
4+
import { handlePendingTx } from '../src/pending-tx-manager.ts';
5+
import { TxType } from '@aglocal/portfolio-contract/src/resolver/constants.js';
6+
import type { PendingTx } from '@aglocal/portfolio-contract/src/resolver/types.ts';
7+
8+
const SMART_WALLET_CREATED_SIGNATURE = id(
9+
'SmartWalletCreated(address,string,string,string)',
10+
);
11+
const abiCoder = new AbiCoder();
12+
13+
const factoryAddress = '0x51e589D94b51d01B75442AE1504cD8c50d6127C9';
14+
const expectedWalletAddr = '0x8Cb4b25E77844fC0632aCa14f1f9B23bdd654EbF';
15+
16+
const createSmartWalletCreatedLog = (
17+
walletAddr: string,
18+
owner: string,
19+
sourceChain: string,
20+
sourceAddress: string,
21+
) => {
22+
const data = abiCoder.encode(
23+
['string', 'string', 'string'],
24+
[owner, sourceChain, sourceAddress],
25+
);
26+
27+
return {
28+
address: factoryAddress,
29+
topics: [
30+
SMART_WALLET_CREATED_SIGNATURE,
31+
zeroPadValue(walletAddr.toLowerCase(), 32),
32+
],
33+
data,
34+
transactionHash: '0x123abc',
35+
blockNumber: 18500000,
36+
};
37+
};
38+
39+
test('handlePendingTx processes MAKE_ACCOUNT transaction successfully', async t => {
40+
const opts = createMockPendingTxOpts();
41+
const txId = 'tx1';
42+
const chain = 'eip155:42161'; // Arbitrum
43+
const provider = opts.evmProviders[chain];
44+
const type = TxType.MAKE_ACCOUNT;
45+
46+
const logMessages: string[] = [];
47+
const logger = (...args: any[]) => logMessages.push(args.join(' '));
48+
49+
const makeAccountTx: PendingTx = {
50+
txId,
51+
type,
52+
status: 'pending',
53+
destinationAddress: `${chain}:${factoryAddress}`,
54+
expectedAddr: expectedWalletAddr,
55+
};
56+
57+
setTimeout(() => {
58+
const mockLog = createSmartWalletCreatedLog(
59+
expectedWalletAddr,
60+
'agoric1owner123',
61+
'agoric-3',
62+
'agoric1source456',
63+
);
64+
65+
const filter = {
66+
address: factoryAddress,
67+
topics: [
68+
SMART_WALLET_CREATED_SIGNATURE,
69+
zeroPadValue(expectedWalletAddr.toLowerCase(), 32),
70+
],
71+
};
72+
73+
(provider as any).emit(filter, mockLog);
74+
}, 50);
75+
76+
await t.notThrowsAsync(async () => {
77+
await handlePendingTx(makeAccountTx, {
78+
...opts,
79+
log: logger,
80+
timeoutMs: 3000,
81+
});
82+
});
83+
84+
t.deepEqual(logMessages, [
85+
`[${txId}] handling ${type} tx`,
86+
`[${txId}] Watching SmartWalletCreated events emitted by ${factoryAddress}`,
87+
`[${txId}] SmartWalletCreated event detected: wallet:${expectedWalletAddr}`,
88+
`[${txId}] ✓ Address matches! Expected: ${expectedWalletAddr}, Found: ${expectedWalletAddr}`,
89+
`[${txId}] MAKE_ACCOUNT tx resolved`,
90+
]);
91+
});
92+
93+
test('handlePendingTx logs timeout on MAKE_ACCOUNT transaction with no matching event', async t => {
94+
const opts = createMockPendingTxOpts();
95+
const txId = 'tx2';
96+
const chain = 'eip155:42161'; // Arbitrum
97+
const provider = opts.evmProviders[chain];
98+
const type = TxType.MAKE_ACCOUNT;
99+
100+
const logMessages: string[] = [];
101+
const logger = (...args: any[]) => logMessages.push(args.join(' '));
102+
103+
const makeAccountTx: PendingTx = {
104+
txId,
105+
type,
106+
status: 'pending',
107+
destinationAddress: `${chain}:${factoryAddress}`,
108+
expectedAddr: expectedWalletAddr,
109+
};
110+
111+
setTimeout(() => {
112+
const mockLog = createSmartWalletCreatedLog(
113+
expectedWalletAddr,
114+
'agoric1owner123',
115+
'agoric-3',
116+
'agoric1source456',
117+
);
118+
119+
const filter = {
120+
address: factoryAddress,
121+
topics: [
122+
SMART_WALLET_CREATED_SIGNATURE,
123+
zeroPadValue(expectedWalletAddr.toLowerCase(), 32),
124+
],
125+
};
126+
127+
(provider as any).emit(filter, mockLog);
128+
}, 3010);
129+
130+
await t.notThrowsAsync(async () => {
131+
await handlePendingTx(makeAccountTx, {
132+
...opts,
133+
log: logger,
134+
timeoutMs: 3000,
135+
});
136+
});
137+
138+
t.deepEqual(logMessages, [
139+
`[${txId}] handling ${type} tx`,
140+
`[${txId}] Watching SmartWalletCreated events emitted by ${factoryAddress}`,
141+
`[${txId}] ✗ No matching SmartWalletCreated event found within 0.05 minutes`,
142+
`[${txId}] SmartWalletCreated event detected: wallet:${expectedWalletAddr}`,
143+
`[${txId}] ✓ Address matches! Expected: ${expectedWalletAddr}, Found: ${expectedWalletAddr}`,
144+
`[${txId}] MAKE_ACCOUNT tx resolved`,
145+
]);
146+
});
147+
148+
test('handlePendingTx ignores non-matching wallet addresses', async t => {
149+
const opts = createMockPendingTxOpts();
150+
const txId = 'tx3';
151+
const chain = 'eip155:42161'; // Arbitrum
152+
const provider = opts.evmProviders[chain];
153+
const type = TxType.MAKE_ACCOUNT;
154+
155+
// Use a different address - getAddress normalizes it to checksummed format
156+
const wrongWalletAddrChecksummed = getAddress(
157+
'0x742d35cc6635c0532925a3b8d9deb1c9e5eb2b64',
158+
);
159+
160+
const logMessages: string[] = [];
161+
const logger = (...args: any[]) => logMessages.push(args.join(' '));
162+
163+
const makeAccountTx: PendingTx = {
164+
txId,
165+
type,
166+
status: 'pending',
167+
destinationAddress: `${chain}:${factoryAddress}`,
168+
expectedAddr: expectedWalletAddr,
169+
};
170+
171+
// Emit wrong address first
172+
setTimeout(() => {
173+
const mockLog = createSmartWalletCreatedLog(
174+
wrongWalletAddrChecksummed,
175+
'agoric1owner123',
176+
'agoric-3',
177+
'agoric1source456',
178+
);
179+
180+
const filter = {
181+
address: factoryAddress,
182+
topics: [
183+
SMART_WALLET_CREATED_SIGNATURE,
184+
zeroPadValue(expectedWalletAddr.toLowerCase(), 32),
185+
],
186+
};
187+
188+
(provider as any).emit(filter, mockLog);
189+
}, 30);
190+
191+
setTimeout(() => {
192+
const mockLog = createSmartWalletCreatedLog(
193+
expectedWalletAddr,
194+
'agoric1owner123',
195+
'agoric-3',
196+
'agoric1source456',
197+
);
198+
199+
const filter = {
200+
address: factoryAddress,
201+
topics: [
202+
SMART_WALLET_CREATED_SIGNATURE,
203+
zeroPadValue(expectedWalletAddr.toLowerCase(), 32),
204+
],
205+
};
206+
207+
(provider as any).emit(filter, mockLog);
208+
}, 60);
209+
210+
await t.notThrowsAsync(async () => {
211+
await handlePendingTx(makeAccountTx, {
212+
...opts,
213+
log: logger,
214+
timeoutMs: 3000,
215+
});
216+
});
217+
218+
t.deepEqual(logMessages, [
219+
`[${txId}] handling ${type} tx`,
220+
`[${txId}] Watching SmartWalletCreated events emitted by ${factoryAddress}`,
221+
`[${txId}] SmartWalletCreated event detected: wallet:${wrongWalletAddrChecksummed}`,
222+
`[${txId}] Address mismatch. Expected: ${expectedWalletAddr}, Found: ${wrongWalletAddrChecksummed}`,
223+
`[${txId}] SmartWalletCreated event detected: wallet:${expectedWalletAddr}`,
224+
`[${txId}] ✓ Address matches! Expected: ${expectedWalletAddr}, Found: ${expectedWalletAddr}`,
225+
`[${txId}] MAKE_ACCOUNT tx resolved`,
226+
]);
227+
});

0 commit comments

Comments
 (0)