@walletmesh/aztec-rpc-wallet 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/CHANGELOG.md +7 -0
- package/LICENSE +201 -0
- package/README.md +260 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/aztecRemoteWallet.d.ts +73 -0
- package/dist/aztecRemoteWallet.d.ts.map +1 -0
- package/dist/aztecRemoteWallet.js +354 -0
- package/dist/chainProvider.d.ts +56 -0
- package/dist/chainProvider.d.ts.map +1 -0
- package/dist/chainProvider.js +98 -0
- package/dist/contractArtifactCache.d.ts +50 -0
- package/dist/contractArtifactCache.d.ts.map +1 -0
- package/dist/contractArtifactCache.js +66 -0
- package/dist/errors.d.ts +50 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +62 -0
- package/dist/handlers/aztecAccountWallet.d.ts +4 -0
- package/dist/handlers/aztecAccountWallet.d.ts.map +1 -0
- package/dist/handlers/aztecAccountWallet.js +329 -0
- package/dist/handlers/transactions.d.ts +21 -0
- package/dist/handlers/transactions.d.ts.map +1 -0
- package/dist/handlers/transactions.js +90 -0
- package/dist/handlers.d.ts +27 -0
- package/dist/handlers.d.ts.map +1 -0
- package/dist/handlers.js +55 -0
- package/dist/index.d.ts +58 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/provider.d.ts +105 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +160 -0
- package/dist/serializers/account.d.ts +167 -0
- package/dist/serializers/account.d.ts.map +1 -0
- package/dist/serializers/account.js +245 -0
- package/dist/serializers/contract-utils.d.ts +40 -0
- package/dist/serializers/contract-utils.d.ts.map +1 -0
- package/dist/serializers/contract-utils.js +102 -0
- package/dist/serializers/contract.d.ts +168 -0
- package/dist/serializers/contract.d.ts.map +1 -0
- package/dist/serializers/contract.js +268 -0
- package/dist/serializers/core.d.ts +110 -0
- package/dist/serializers/core.d.ts.map +1 -0
- package/dist/serializers/core.js +130 -0
- package/dist/serializers/index.d.ts +28 -0
- package/dist/serializers/index.d.ts.map +1 -0
- package/dist/serializers/index.js +159 -0
- package/dist/serializers/log.d.ts +113 -0
- package/dist/serializers/log.d.ts.map +1 -0
- package/dist/serializers/log.js +231 -0
- package/dist/serializers/note.d.ts +127 -0
- package/dist/serializers/note.d.ts.map +1 -0
- package/dist/serializers/note.js +182 -0
- package/dist/serializers/transaction-utils.d.ts +107 -0
- package/dist/serializers/transaction-utils.d.ts.map +1 -0
- package/dist/serializers/transaction-utils.js +130 -0
- package/dist/serializers/transaction.d.ts +103 -0
- package/dist/serializers/transaction.d.ts.map +1 -0
- package/dist/serializers/transaction.js +238 -0
- package/dist/serializers/types.d.ts +49 -0
- package/dist/serializers/types.d.ts.map +1 -0
- package/dist/serializers/types.js +22 -0
- package/dist/types.d.ts +391 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/wallet.d.ts +62 -0
- package/dist/wallet.d.ts.map +1 -0
- package/dist/wallet.js +77 -0
- package/package.json +44 -0
- package/src/aztecRemoteWallet.test.ts +542 -0
- package/src/aztecRemoteWallet.ts +484 -0
- package/src/chainProvider.test.ts +322 -0
- package/src/chainProvider.ts +122 -0
- package/src/contractArtifactCache.test.ts +126 -0
- package/src/contractArtifactCache.ts +75 -0
- package/src/errors.ts +71 -0
- package/src/handlers/aztecAccountWallet.test.ts +720 -0
- package/src/handlers/aztecAccountWallet.ts +593 -0
- package/src/handlers/transactions.ts +110 -0
- package/src/handlers.test.ts +270 -0
- package/src/handlers.ts +70 -0
- package/src/index.test.ts +23 -0
- package/src/index.ts +64 -0
- package/src/provider.test.ts +276 -0
- package/src/provider.ts +189 -0
- package/src/serializers/account.test.ts +125 -0
- package/src/serializers/account.ts +319 -0
- package/src/serializers/contract-utils.ts +104 -0
- package/src/serializers/contract.test.ts +162 -0
- package/src/serializers/contract.ts +350 -0
- package/src/serializers/core.test.ts +56 -0
- package/src/serializers/core.ts +141 -0
- package/src/serializers/index.test.ts +122 -0
- package/src/serializers/index.ts +213 -0
- package/src/serializers/log.test.ts +119 -0
- package/src/serializers/log.ts +283 -0
- package/src/serializers/note.test.ts +100 -0
- package/src/serializers/note.ts +227 -0
- package/src/serializers/transaction-utils.ts +237 -0
- package/src/serializers/transaction.test.ts +153 -0
- package/src/serializers/transaction.ts +342 -0
- package/src/serializers/types.ts +58 -0
- package/src/types.ts +295 -0
- package/src/wallet.test.ts +275 -0
- package/src/wallet.ts +94 -0
- package/tsconfig.build.json +6 -0
- package/tsconfig.json +11 -0
- package/typedoc.json +15 -0
- package/vitest.config.ts +10 -0
@@ -0,0 +1,270 @@
|
|
1
|
+
import { describe, expect, it, vi, beforeEach } from 'vitest';
|
2
|
+
import type { AccountWallet, PXE, TxHash, AztecAddress } from '@aztec/aztec.js';
|
3
|
+
import { Fr } from '@aztec/aztec.js';
|
4
|
+
import { handler } from './handlers.js';
|
5
|
+
import { AztecWalletError } from './errors.js';
|
6
|
+
import { ContractArtifactCache } from './contractArtifactCache.js';
|
7
|
+
import type {
|
8
|
+
AztecWalletContext,
|
9
|
+
AztecWalletMethodMap,
|
10
|
+
TransactionParams,
|
11
|
+
TransactionFunctionCall,
|
12
|
+
} from './types.js';
|
13
|
+
|
14
|
+
// Mock Contract.at and NoFeePaymentMethod at the top level
|
15
|
+
// Mock Aztec.js dependencies
|
16
|
+
vi.mock('@aztec/aztec.js', async () => {
|
17
|
+
const actual = await vi.importActual('@aztec/aztec.js');
|
18
|
+
return {
|
19
|
+
...actual,
|
20
|
+
Contract: {
|
21
|
+
at: vi.fn(),
|
22
|
+
},
|
23
|
+
NoFeePaymentMethod: class {},
|
24
|
+
AztecAddress: {
|
25
|
+
fromString: vi.fn().mockImplementation((str) => ({
|
26
|
+
toString: () => str,
|
27
|
+
toField: () => new Fr(1),
|
28
|
+
equals: () => false,
|
29
|
+
isZero: () => false,
|
30
|
+
})),
|
31
|
+
},
|
32
|
+
AuthWitness: {
|
33
|
+
fromString: vi.fn().mockImplementation((str) => ({
|
34
|
+
toString: () => str,
|
35
|
+
})),
|
36
|
+
},
|
37
|
+
GasSettings: {
|
38
|
+
default: vi.fn().mockReturnValue({
|
39
|
+
maxFeePerGas: BigInt(1000),
|
40
|
+
maxPriorityFeePerGas: BigInt(100),
|
41
|
+
}),
|
42
|
+
},
|
43
|
+
};
|
44
|
+
});
|
45
|
+
|
46
|
+
// Mock circuits.js dependencies
|
47
|
+
vi.mock('@aztec/circuits.js', () => ({
|
48
|
+
GasSettings: {
|
49
|
+
default: vi.fn().mockReturnValue({
|
50
|
+
maxFeePerGas: BigInt(1000),
|
51
|
+
maxPriorityFeePerGas: BigInt(100),
|
52
|
+
}),
|
53
|
+
},
|
54
|
+
}));
|
55
|
+
|
56
|
+
describe('RPC Handlers', () => {
|
57
|
+
let context: AztecWalletContext;
|
58
|
+
let pxe: PXE;
|
59
|
+
// Define a type for our mocked wallet that includes the methods we need
|
60
|
+
type MockedWallet = AccountWallet & {
|
61
|
+
sendTransaction: ReturnType<typeof vi.fn>;
|
62
|
+
simulateTransaction: ReturnType<typeof vi.fn>;
|
63
|
+
getContractInstance: ReturnType<typeof vi.fn>;
|
64
|
+
getContractArtifact: ReturnType<typeof vi.fn>;
|
65
|
+
getCurrentBaseFees: ReturnType<typeof vi.fn>;
|
66
|
+
createTxExecutionRequest: ReturnType<typeof vi.fn>;
|
67
|
+
simulateTx: ReturnType<typeof vi.fn>;
|
68
|
+
proveTx: ReturnType<typeof vi.fn>;
|
69
|
+
sendTx: ReturnType<typeof vi.fn>;
|
70
|
+
};
|
71
|
+
let wallet: MockedWallet;
|
72
|
+
let contractArtifactCache: ContractArtifactCache;
|
73
|
+
|
74
|
+
beforeEach(() => {
|
75
|
+
// Mock wallet with common methods
|
76
|
+
wallet = {
|
77
|
+
getAddress: vi.fn().mockResolvedValue('mockAddress'),
|
78
|
+
getContractInstance: vi.fn().mockResolvedValue(undefined),
|
79
|
+
getContractArtifact: vi.fn().mockResolvedValue(undefined),
|
80
|
+
sendTransaction: vi.fn(),
|
81
|
+
simulateTransaction: vi.fn(),
|
82
|
+
getCurrentBaseFees: vi.fn().mockResolvedValue(BigInt(1000)),
|
83
|
+
createTxExecutionRequest: vi.fn().mockResolvedValue({
|
84
|
+
id: 'mockTxId',
|
85
|
+
data: new Uint8Array(),
|
86
|
+
}),
|
87
|
+
simulateTx: vi.fn().mockResolvedValue({
|
88
|
+
privateExecutionResult: {
|
89
|
+
success: true,
|
90
|
+
data: new Uint8Array(),
|
91
|
+
},
|
92
|
+
}),
|
93
|
+
proveTx: vi.fn().mockResolvedValue({
|
94
|
+
toTx: () => ({ id: 'mockTxId' }),
|
95
|
+
}),
|
96
|
+
sendTx: vi.fn().mockResolvedValue({
|
97
|
+
toString: () => 'txHash',
|
98
|
+
} as unknown as TxHash),
|
99
|
+
} as unknown as MockedWallet;
|
100
|
+
|
101
|
+
// Mock PXE
|
102
|
+
pxe = {
|
103
|
+
// Add PXE methods as needed
|
104
|
+
} as unknown as PXE;
|
105
|
+
|
106
|
+
// Create contract artifact cache
|
107
|
+
contractArtifactCache = new ContractArtifactCache(wallet);
|
108
|
+
|
109
|
+
// Setup context
|
110
|
+
context = {
|
111
|
+
pxe,
|
112
|
+
wallet,
|
113
|
+
contractArtifactCache,
|
114
|
+
};
|
115
|
+
});
|
116
|
+
|
117
|
+
describe('Base wallet methods', () => {
|
118
|
+
it('handles wm_getSupportedMethods', async () => {
|
119
|
+
const result = await handler(context, 'wm_getSupportedMethods', []);
|
120
|
+
expect(Array.isArray(result)).toBe(true);
|
121
|
+
expect(result.length).toBeGreaterThan(0);
|
122
|
+
expect(result).toContain('aztec_connect');
|
123
|
+
expect(result).toContain('aztec_getAccount');
|
124
|
+
});
|
125
|
+
|
126
|
+
it('handles aztec_connect', async () => {
|
127
|
+
const result = await handler(context, 'aztec_connect', []);
|
128
|
+
expect(result).toBe(true);
|
129
|
+
});
|
130
|
+
|
131
|
+
it('handles aztec_getAccount', async () => {
|
132
|
+
const result = await handler(context, 'aztec_getAccount', []);
|
133
|
+
expect(result).toBe('mockAddress');
|
134
|
+
expect(wallet.getAddress).toHaveBeenCalled();
|
135
|
+
});
|
136
|
+
});
|
137
|
+
|
138
|
+
describe('Transaction methods', () => {
|
139
|
+
// Create a valid AztecAddress for testing
|
140
|
+
// Create a valid hex string for AztecAddress (32 bytes = 64 hex chars)
|
141
|
+
const mockAddressHex = `0x${'1'.repeat(64)}`;
|
142
|
+
const mockAddress = {
|
143
|
+
toString: () => mockAddressHex,
|
144
|
+
toField: () => new Fr(1),
|
145
|
+
equals: () => false,
|
146
|
+
isZero: () => false,
|
147
|
+
_hex: mockAddressHex,
|
148
|
+
} as unknown as AztecAddress;
|
149
|
+
|
150
|
+
const mockFunctionCall: TransactionFunctionCall = {
|
151
|
+
contractAddress: mockAddress.toString(),
|
152
|
+
functionName: 'test',
|
153
|
+
args: ['arg1', 'arg2'],
|
154
|
+
};
|
155
|
+
|
156
|
+
const mockTxParams: TransactionParams = {
|
157
|
+
functionCalls: [mockFunctionCall],
|
158
|
+
authwits: [],
|
159
|
+
};
|
160
|
+
|
161
|
+
beforeEach(async () => {
|
162
|
+
// Mock contract instance with proper request data
|
163
|
+
const mockContract = {
|
164
|
+
methods: {
|
165
|
+
test: vi.fn().mockReturnValue({
|
166
|
+
simulate: vi.fn().mockResolvedValue({
|
167
|
+
success: true,
|
168
|
+
returnValue: '0x123',
|
169
|
+
}),
|
170
|
+
request: vi.fn().mockResolvedValue({
|
171
|
+
contractAddress: mockAddress,
|
172
|
+
functionData: new Uint8Array([1, 2, 3]), // Non-empty function data
|
173
|
+
functionSignature: 'test(uint256,uint256)',
|
174
|
+
args: ['arg1', 'arg2'],
|
175
|
+
}),
|
176
|
+
}),
|
177
|
+
},
|
178
|
+
address: mockAddress,
|
179
|
+
};
|
180
|
+
|
181
|
+
// Configure Contract.at mock
|
182
|
+
const { Contract } = await import('@aztec/aztec.js');
|
183
|
+
(Contract.at as ReturnType<typeof vi.fn>).mockResolvedValue(mockContract);
|
184
|
+
|
185
|
+
// Configure mock return values for contract artifact cache
|
186
|
+
const mockArtifact = {
|
187
|
+
functions: {
|
188
|
+
test: {
|
189
|
+
name: 'test',
|
190
|
+
parameters: [
|
191
|
+
{ name: 'arg1', type: 'uint256' },
|
192
|
+
{ name: 'arg2', type: 'uint256' },
|
193
|
+
],
|
194
|
+
},
|
195
|
+
},
|
196
|
+
};
|
197
|
+
|
198
|
+
// Mock contract artifact cache methods
|
199
|
+
contractArtifactCache.getContractArtifact = vi.fn().mockResolvedValue(mockArtifact);
|
200
|
+
});
|
201
|
+
|
202
|
+
it('handles aztec_sendTransaction', async () => {
|
203
|
+
const result = await handler(context, 'aztec_sendTransaction', mockTxParams);
|
204
|
+
expect(result).toBe('txHash');
|
205
|
+
expect(contractArtifactCache.getContractArtifact).toHaveBeenCalled();
|
206
|
+
expect(wallet.createTxExecutionRequest).toHaveBeenCalled();
|
207
|
+
expect(wallet.simulateTx).toHaveBeenCalled();
|
208
|
+
expect(wallet.proveTx).toHaveBeenCalled();
|
209
|
+
expect(wallet.sendTx).toHaveBeenCalled();
|
210
|
+
});
|
211
|
+
|
212
|
+
it('handles aztec_simulateTransaction', async () => {
|
213
|
+
const result = await handler(context, 'aztec_simulateTransaction', mockFunctionCall);
|
214
|
+
expect(result).toEqual({
|
215
|
+
success: true,
|
216
|
+
returnValue: '0x123',
|
217
|
+
});
|
218
|
+
expect(contractArtifactCache.getContractArtifact).toHaveBeenCalled();
|
219
|
+
});
|
220
|
+
|
221
|
+
it('handles transaction errors', async () => {
|
222
|
+
wallet.createTxExecutionRequest.mockRejectedValue(new Error('Transaction failed'));
|
223
|
+
await expect(handler(context, 'aztec_sendTransaction', mockTxParams)).rejects.toThrow(AztecWalletError);
|
224
|
+
});
|
225
|
+
});
|
226
|
+
|
227
|
+
describe('Error handling', () => {
|
228
|
+
it('throws error for unsupported method', async () => {
|
229
|
+
await expect(handler(context, 'unsupported_method' as keyof AztecWalletMethodMap, [])).rejects.toThrow(
|
230
|
+
AztecWalletError,
|
231
|
+
);
|
232
|
+
});
|
233
|
+
|
234
|
+
it('throws error for invalid parameters', async () => {
|
235
|
+
await expect(
|
236
|
+
handler(context, 'aztec_sendTransaction', [] as unknown as TransactionParams),
|
237
|
+
).rejects.toThrow(AztecWalletError);
|
238
|
+
});
|
239
|
+
|
240
|
+
it('handles null context values', async () => {
|
241
|
+
// Mock the handler to wrap errors
|
242
|
+
const mockHandler = async () => {
|
243
|
+
try {
|
244
|
+
await handler(
|
245
|
+
{ pxe, wallet: null, contractArtifactCache } as unknown as AztecWalletContext,
|
246
|
+
'aztec_getAccount',
|
247
|
+
[],
|
248
|
+
);
|
249
|
+
} catch (error) {
|
250
|
+
if (error instanceof Error) {
|
251
|
+
throw new AztecWalletError('unknownInternalError', error.message);
|
252
|
+
}
|
253
|
+
throw error;
|
254
|
+
}
|
255
|
+
};
|
256
|
+
|
257
|
+
await expect(mockHandler()).rejects.toThrow(AztecWalletError);
|
258
|
+
});
|
259
|
+
});
|
260
|
+
|
261
|
+
describe('Account wallet methods', () => {
|
262
|
+
// Add tests for account wallet specific methods
|
263
|
+
// These would test the routing to accountWalletHandler
|
264
|
+
it('routes account wallet methods correctly', async () => {
|
265
|
+
// Mock an account wallet method
|
266
|
+
const accountMethod = 'aztec_getBlock';
|
267
|
+
await expect(handler(context, accountMethod, { number: 1 })).rejects.toThrow(); // Should attempt to route to accountWalletHandler
|
268
|
+
});
|
269
|
+
});
|
270
|
+
});
|
package/src/handlers.ts
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
/**
|
2
|
+
* @module handlers
|
3
|
+
*
|
4
|
+
* This module provides the core RPC method handling logic for the Aztec wallet.
|
5
|
+
* It routes incoming RPC requests to appropriate specialized handlers based on the method type.
|
6
|
+
*
|
7
|
+
* The handlers are organized into categories:
|
8
|
+
* - Base wallet methods (connect, getAccount, etc.)
|
9
|
+
* - Account wallet methods (chain operations, contract management, etc.)
|
10
|
+
* - Transaction methods (send, simulate)
|
11
|
+
*
|
12
|
+
* Each method handler validates inputs, performs the requested operation through the wallet,
|
13
|
+
* and returns properly formatted responses.
|
14
|
+
*/
|
15
|
+
|
16
|
+
import type { AztecWalletMethodMap } from './types.js';
|
17
|
+
import { type AztecWalletContext, BASE_WALLET_METHODS } from './types.js';
|
18
|
+
import { AztecWalletError } from './errors.js';
|
19
|
+
import { sendTransaction, simulateTransaction } from './handlers/transactions.js';
|
20
|
+
import { aztecWalletHandler, AZTEC_WALLET_METHODS } from './handlers/aztecAccountWallet.js';
|
21
|
+
|
22
|
+
/**
|
23
|
+
* Main handler function that routes RPC method calls to appropriate specialized handlers.
|
24
|
+
*
|
25
|
+
* @param context - The wallet context containing PXE and wallet instances
|
26
|
+
* @param method - The RPC method being called
|
27
|
+
* @param params - Parameters passed to the method
|
28
|
+
* @returns Result from the method handler
|
29
|
+
* @throws {AztecWalletError} If method not supported or handler fails
|
30
|
+
*/
|
31
|
+
|
32
|
+
export async function handler<M extends keyof AztecWalletMethodMap>(
|
33
|
+
context: AztecWalletContext,
|
34
|
+
method: M,
|
35
|
+
params: AztecWalletMethodMap[M]['params'],
|
36
|
+
): Promise<AztecWalletMethodMap[M]['result']> {
|
37
|
+
if (AZTEC_WALLET_METHODS.includes(method)) {
|
38
|
+
return aztecWalletHandler(context, method, params);
|
39
|
+
}
|
40
|
+
switch (method) {
|
41
|
+
// Base wallet methods
|
42
|
+
case 'wm_getSupportedMethods': {
|
43
|
+
// Return combined list of supported methods from all handlers
|
44
|
+
return [...BASE_WALLET_METHODS, ...AZTEC_WALLET_METHODS] as string[];
|
45
|
+
}
|
46
|
+
case 'aztec_connect': {
|
47
|
+
// Basic connection validation
|
48
|
+
// Note: Main connection logic handled by provider
|
49
|
+
return true;
|
50
|
+
}
|
51
|
+
// Core wallet methods
|
52
|
+
case 'aztec_getAccount':
|
53
|
+
return (await context.wallet.getAddress()).toString();
|
54
|
+
|
55
|
+
// Transaction methods
|
56
|
+
case 'aztec_sendTransaction':
|
57
|
+
return await sendTransaction(
|
58
|
+
context,
|
59
|
+
params as AztecWalletMethodMap['aztec_sendTransaction']['params'],
|
60
|
+
);
|
61
|
+
case 'aztec_simulateTransaction':
|
62
|
+
return await simulateTransaction(
|
63
|
+
context,
|
64
|
+
params as AztecWalletMethodMap['aztec_simulateTransaction']['params'],
|
65
|
+
);
|
66
|
+
|
67
|
+
default:
|
68
|
+
throw new AztecWalletError('invalidRequest', `Method not supported: ${String(method)}`);
|
69
|
+
}
|
70
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
2
|
+
import * as exports from './index.js';
|
3
|
+
|
4
|
+
describe('index exports', () => {
|
5
|
+
it('should export AztecProvider', () => {
|
6
|
+
expect(exports.AztecProvider).toBeDefined();
|
7
|
+
});
|
8
|
+
|
9
|
+
it('should export AztecChainWallet', () => {
|
10
|
+
expect(exports.AztecChainWallet).toBeDefined();
|
11
|
+
});
|
12
|
+
|
13
|
+
it('should export error utilities', () => {
|
14
|
+
expect(exports.AztecWalletError).toBeDefined();
|
15
|
+
expect(exports.AztecWalletErrorMap).toBeDefined();
|
16
|
+
});
|
17
|
+
|
18
|
+
// Type exports can't be tested at runtime, but we can verify the file compiles
|
19
|
+
it('should compile with type exports', () => {
|
20
|
+
// This test passes by virtue of the file compiling
|
21
|
+
expect(true).toBe(true);
|
22
|
+
});
|
23
|
+
});
|
package/src/index.ts
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
/**
|
2
|
+
* @module @walletmesh/aztec-rpc-wallet
|
3
|
+
*
|
4
|
+
* This module provides a JSON-RPC implementation for interacting with Aztec Network.
|
5
|
+
* It enables communication between dApps and wallets through a standardized interface.
|
6
|
+
*/
|
7
|
+
|
8
|
+
/**
|
9
|
+
* Provider class for dApps to interact with Aztec wallets
|
10
|
+
* @see AztecProvider
|
11
|
+
*/
|
12
|
+
export { AztecProvider } from './provider.js';
|
13
|
+
|
14
|
+
/**
|
15
|
+
* Minimal provider for direct interaction with an Aztec chain wallet
|
16
|
+
* @see AztecChainProvider
|
17
|
+
*/
|
18
|
+
export { AztecChainProvider } from './chainProvider.js';
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Wallet implementation that handles RPC requests from dApps
|
22
|
+
* @see AztecChainWallet
|
23
|
+
*/
|
24
|
+
export { AztecChainWallet } from './wallet.js';
|
25
|
+
export { AztecChainWalletMiddleware } from './types.js';
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Cache for contract artifacts
|
29
|
+
* @see ContractArtifactCache
|
30
|
+
*/
|
31
|
+
export { ContractArtifactCache } from './contractArtifactCache.js';
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Error handling utilities for RPC communication
|
35
|
+
* @see AztecWalletError
|
36
|
+
* @see AztecWalletErrorMap
|
37
|
+
*/
|
38
|
+
export { AztecWalletError, AztecWalletErrorMap } from './errors.js';
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Type definitions for RPC interfaces
|
42
|
+
*/
|
43
|
+
export type {
|
44
|
+
/** Chain identifier type */
|
45
|
+
AztecChainId,
|
46
|
+
/** Context passed through RPC middleware */
|
47
|
+
AztecWalletContext,
|
48
|
+
/** Event map for wallet events */
|
49
|
+
AztecWalletEventMap,
|
50
|
+
/** Base method map for core wallet functionality */
|
51
|
+
AztecWalletBaseMethodMap,
|
52
|
+
/** Complete method map including all Aztec methods */
|
53
|
+
AztecWalletMethodMap,
|
54
|
+
/** Middleware type for processing RPC requests */
|
55
|
+
AztecWalletMiddleware,
|
56
|
+
/** Router client type for wallet mesh integration */
|
57
|
+
AztecWalletRouterClient,
|
58
|
+
/** Handler type for wallet methods */
|
59
|
+
AztecWalletMethodHandler,
|
60
|
+
/** Type for contract function calls */
|
61
|
+
TransactionFunctionCall,
|
62
|
+
/** Parameters for transaction requests */
|
63
|
+
TransactionParams,
|
64
|
+
} from './types.js';
|
@@ -0,0 +1,276 @@
|
|
1
|
+
import { describe, test, expect, vi, beforeEach } from 'vitest';
|
2
|
+
import { AztecProvider } from './provider.js';
|
3
|
+
import { AztecWalletError, AztecWalletErrorType } from './errors.js';
|
4
|
+
import type { JSONRPCTransport } from '@walletmesh/jsonrpc';
|
5
|
+
import type { ContractInstanceWithAddress, AztecAddress, ContractArtifact } from '@aztec/aztec.js';
|
6
|
+
import { WalletRouterProvider } from '@walletmesh/router';
|
7
|
+
import type { OperationBuilder } from '@walletmesh/router';
|
8
|
+
import type { Mock } from 'vitest';
|
9
|
+
|
10
|
+
const createMockTransport = () => ({
|
11
|
+
send: vi.fn(),
|
12
|
+
on: vi.fn(),
|
13
|
+
off: vi.fn(),
|
14
|
+
close: vi.fn(),
|
15
|
+
});
|
16
|
+
|
17
|
+
describe('AztecProvider', () => {
|
18
|
+
let provider: AztecProvider;
|
19
|
+
let mockTransport: ReturnType<typeof createMockTransport>;
|
20
|
+
let mockChainBuilder: {
|
21
|
+
chainId: string;
|
22
|
+
provider: WalletRouterProvider;
|
23
|
+
calls: unknown[];
|
24
|
+
call: Mock;
|
25
|
+
execute: Mock;
|
26
|
+
};
|
27
|
+
|
28
|
+
beforeEach(() => {
|
29
|
+
mockTransport = createMockTransport();
|
30
|
+
provider = new AztecProvider(mockTransport);
|
31
|
+
|
32
|
+
// Setup chain builder mock after provider creation
|
33
|
+
mockChainBuilder = {
|
34
|
+
chainId: 'aztec:testnet',
|
35
|
+
provider: provider,
|
36
|
+
calls: [],
|
37
|
+
call: vi.fn(),
|
38
|
+
execute: vi.fn(),
|
39
|
+
};
|
40
|
+
|
41
|
+
// Setup mock chain builder
|
42
|
+
mockChainBuilder.call.mockImplementation(() => mockChainBuilder);
|
43
|
+
mockChainBuilder.execute.mockImplementation(() => Promise.resolve());
|
44
|
+
|
45
|
+
// Setup additional mocks
|
46
|
+
vi.spyOn(provider as WalletRouterProvider, 'sessionId', 'get').mockReturnValue('test-session-id');
|
47
|
+
vi.spyOn(provider, 'chain').mockImplementation((chainId) => {
|
48
|
+
mockChainBuilder.chainId = chainId;
|
49
|
+
mockChainBuilder.call.mockImplementation((method, params) => {
|
50
|
+
mockChainBuilder.calls.push({ method, params });
|
51
|
+
return mockChainBuilder;
|
52
|
+
});
|
53
|
+
mockChainBuilder.execute.mockImplementation(async () => {
|
54
|
+
const result = await Promise.resolve(null);
|
55
|
+
if (result === null) {
|
56
|
+
throw new AztecWalletError(AztecWalletErrorType.invalidResponse, 'Invalid response');
|
57
|
+
}
|
58
|
+
return result;
|
59
|
+
});
|
60
|
+
return mockChainBuilder as unknown as OperationBuilder;
|
61
|
+
});
|
62
|
+
});
|
63
|
+
|
64
|
+
describe('constructor', () => {
|
65
|
+
test('registers event handlers', () => {
|
66
|
+
// Create a spy on the on method before creating provider
|
67
|
+
const onSpy = vi.spyOn(WalletRouterProvider.prototype, 'on');
|
68
|
+
const provider = new AztecProvider(mockTransport);
|
69
|
+
|
70
|
+
expect(onSpy).toHaveBeenCalledWith('wm_walletStateChanged', expect.any(Function));
|
71
|
+
expect(onSpy).toHaveBeenCalledWith('wm_sessionTerminated', expect.any(Function));
|
72
|
+
|
73
|
+
onSpy.mockRestore();
|
74
|
+
});
|
75
|
+
|
76
|
+
test('initializes with empty chain sets', () => {
|
77
|
+
expect(provider.getSupportedChains()).toEqual([]);
|
78
|
+
});
|
79
|
+
});
|
80
|
+
|
81
|
+
describe('handleWalletStateChanged', () => {
|
82
|
+
test('adds chain when accounts become available', () => {
|
83
|
+
const chainId = 'aztec:testnet';
|
84
|
+
provider['requestedChains'].add(chainId);
|
85
|
+
|
86
|
+
provider['handleWalletStateChanged']({
|
87
|
+
chainId,
|
88
|
+
changes: { accounts: ['0x123'] },
|
89
|
+
});
|
90
|
+
|
91
|
+
expect(provider.getSupportedChains()).toContain(chainId);
|
92
|
+
});
|
93
|
+
|
94
|
+
test('removes chain when accounts become unavailable', () => {
|
95
|
+
const chainId = 'aztec:testnet';
|
96
|
+
provider['requestedChains'].add(chainId);
|
97
|
+
provider['connectedChains'].add(chainId);
|
98
|
+
|
99
|
+
provider['handleWalletStateChanged']({
|
100
|
+
chainId,
|
101
|
+
changes: { accounts: [] },
|
102
|
+
});
|
103
|
+
|
104
|
+
expect(provider.getSupportedChains()).not.toContain(chainId);
|
105
|
+
});
|
106
|
+
|
107
|
+
test('ignores events for non-requested chains', () => {
|
108
|
+
const chainId = 'aztec:testnet';
|
109
|
+
// Chain not added to requestedChains
|
110
|
+
|
111
|
+
provider['handleWalletStateChanged']({
|
112
|
+
chainId,
|
113
|
+
changes: { accounts: ['0x123'] },
|
114
|
+
});
|
115
|
+
|
116
|
+
expect(provider.getSupportedChains()).not.toContain(chainId);
|
117
|
+
});
|
118
|
+
});
|
119
|
+
|
120
|
+
describe('handleSessionTerminated', () => {
|
121
|
+
test('clears chains when session matches', () => {
|
122
|
+
const chainId = 'aztec:testnet';
|
123
|
+
provider['requestedChains'].add(chainId);
|
124
|
+
provider['connectedChains'].add(chainId);
|
125
|
+
|
126
|
+
provider['handleSessionTerminated']({
|
127
|
+
sessionId: 'test-session-id',
|
128
|
+
reason: 'test termination',
|
129
|
+
});
|
130
|
+
|
131
|
+
expect(provider.getSupportedChains()).toEqual([]);
|
132
|
+
expect(provider['requestedChains'].size).toBe(0);
|
133
|
+
});
|
134
|
+
|
135
|
+
test('ignores termination for different sessions', () => {
|
136
|
+
const chainId = 'aztec:testnet';
|
137
|
+
provider['requestedChains'].add(chainId);
|
138
|
+
provider['connectedChains'].add(chainId);
|
139
|
+
|
140
|
+
provider['handleSessionTerminated']({
|
141
|
+
sessionId: 'different-session',
|
142
|
+
reason: 'test termination',
|
143
|
+
});
|
144
|
+
|
145
|
+
expect(provider.getSupportedChains()).toContain(chainId);
|
146
|
+
expect(provider['requestedChains'].has(chainId)).toBe(true);
|
147
|
+
});
|
148
|
+
});
|
149
|
+
|
150
|
+
describe('getAccount', () => {
|
151
|
+
test('returns account address on success', async () => {
|
152
|
+
const expectedAddress = '0x123';
|
153
|
+
mockChainBuilder.execute.mockResolvedValueOnce(expectedAddress);
|
154
|
+
|
155
|
+
const result = await provider.getAccount('aztec:testnet');
|
156
|
+
expect(result).toBe(expectedAddress);
|
157
|
+
});
|
158
|
+
|
159
|
+
test('throws on invalid response', async () => {
|
160
|
+
mockChainBuilder.execute.mockResolvedValueOnce(null);
|
161
|
+
|
162
|
+
await expect(provider.getAccount('aztec:testnet')).rejects.toThrowError(
|
163
|
+
new AztecWalletError(AztecWalletErrorType.invalidResponse, 'Invalid account address returned'),
|
164
|
+
);
|
165
|
+
});
|
166
|
+
});
|
167
|
+
|
168
|
+
describe('sendTransaction', () => {
|
169
|
+
const mockTxParams = {
|
170
|
+
functionCalls: [
|
171
|
+
{
|
172
|
+
contractAddress: '0x456',
|
173
|
+
functionName: 'transfer',
|
174
|
+
args: ['0x789', 100],
|
175
|
+
},
|
176
|
+
],
|
177
|
+
};
|
178
|
+
|
179
|
+
test('returns transaction hash on success', async () => {
|
180
|
+
const expectedHash = '0xabc';
|
181
|
+
mockChainBuilder.execute.mockResolvedValueOnce(expectedHash);
|
182
|
+
|
183
|
+
const result = await provider.sendTransaction('aztec:testnet', mockTxParams);
|
184
|
+
expect(result).toBe(expectedHash);
|
185
|
+
});
|
186
|
+
|
187
|
+
test('throws on invalid response', async () => {
|
188
|
+
mockChainBuilder.execute.mockResolvedValueOnce(null);
|
189
|
+
|
190
|
+
await expect(provider.sendTransaction('aztec:testnet', mockTxParams)).rejects.toThrowError(
|
191
|
+
new AztecWalletError(AztecWalletErrorType.invalidResponse, 'Invalid transaction hash returned'),
|
192
|
+
);
|
193
|
+
});
|
194
|
+
});
|
195
|
+
|
196
|
+
describe('simulateTransaction', () => {
|
197
|
+
const mockSimParams = {
|
198
|
+
contractAddress: '0x456',
|
199
|
+
functionName: 'transfer',
|
200
|
+
args: ['0x789', 100],
|
201
|
+
};
|
202
|
+
|
203
|
+
test('returns simulation result on success', async () => {
|
204
|
+
const expectedResult = { success: true, gas: 1000 };
|
205
|
+
mockChainBuilder.execute.mockResolvedValueOnce(expectedResult);
|
206
|
+
|
207
|
+
const result = await provider.simulateTransaction('aztec:testnet', mockSimParams);
|
208
|
+
expect(result).toEqual(expectedResult);
|
209
|
+
});
|
210
|
+
|
211
|
+
test('throws on invalid response', async () => {
|
212
|
+
mockChainBuilder.execute.mockResolvedValueOnce(null);
|
213
|
+
|
214
|
+
await expect(provider.simulateTransaction('aztec:testnet', mockSimParams)).rejects.toThrowError(
|
215
|
+
new AztecWalletError(AztecWalletErrorType.invalidResponse, 'Invalid simulation result returned'),
|
216
|
+
);
|
217
|
+
});
|
218
|
+
});
|
219
|
+
|
220
|
+
describe('registration methods', () => {
|
221
|
+
test('registerContract executes without error', async () => {
|
222
|
+
mockChainBuilder.execute.mockResolvedValueOnce(undefined);
|
223
|
+
|
224
|
+
await expect(
|
225
|
+
provider.registerContract('aztec:testnet', {
|
226
|
+
instance: {
|
227
|
+
address: '0x123' as unknown as AztecAddress,
|
228
|
+
version: 1,
|
229
|
+
salt: '0x0' as unknown as AztecAddress,
|
230
|
+
deployer: '0x0' as unknown as AztecAddress,
|
231
|
+
contractClassId: '0x0' as unknown as AztecAddress,
|
232
|
+
contractClassVersion: 1,
|
233
|
+
publicKey: '0x0' as unknown as AztecAddress,
|
234
|
+
} as unknown as ContractInstanceWithAddress,
|
235
|
+
artifact: {
|
236
|
+
name: 'TestContract',
|
237
|
+
bytecode: '0x',
|
238
|
+
functionSelectors: {},
|
239
|
+
functions: {},
|
240
|
+
outputs: {},
|
241
|
+
storageLayout: {},
|
242
|
+
events: {},
|
243
|
+
} as unknown as ContractArtifact,
|
244
|
+
}),
|
245
|
+
).resolves.not.toThrow();
|
246
|
+
});
|
247
|
+
|
248
|
+
test('registerContractClass executes without error', async () => {
|
249
|
+
mockChainBuilder.execute.mockResolvedValueOnce(undefined);
|
250
|
+
|
251
|
+
await expect(
|
252
|
+
provider.registerContractClass('aztec:testnet', {
|
253
|
+
artifact: {
|
254
|
+
name: 'TestContract',
|
255
|
+
bytecode: '0x',
|
256
|
+
functionSelectors: {},
|
257
|
+
functions: {},
|
258
|
+
outputs: {},
|
259
|
+
storageLayout: {},
|
260
|
+
events: {},
|
261
|
+
} as unknown as ContractArtifact,
|
262
|
+
}),
|
263
|
+
).resolves.not.toThrow();
|
264
|
+
});
|
265
|
+
|
266
|
+
test('registerSender executes without error', async () => {
|
267
|
+
mockChainBuilder.execute.mockResolvedValueOnce(undefined);
|
268
|
+
|
269
|
+
await expect(
|
270
|
+
provider.registerSender('aztec:testnet', {
|
271
|
+
sender: '0x123' as unknown as AztecAddress,
|
272
|
+
}),
|
273
|
+
).resolves.not.toThrow();
|
274
|
+
});
|
275
|
+
});
|
276
|
+
});
|