@walletmesh/aztec-rpc-wallet 0.3.0 → 0.4.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.
Files changed (185) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +290 -228
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/client/aztec-dapp-wallet.d.ts +401 -0
  5. package/dist/client/aztec-dapp-wallet.d.ts.map +1 -0
  6. package/dist/client/aztec-dapp-wallet.js +705 -0
  7. package/dist/client/aztec-router-provider.d.ts +58 -0
  8. package/dist/client/aztec-router-provider.d.ts.map +1 -0
  9. package/dist/client/aztec-router-provider.js +62 -0
  10. package/dist/client/helpers.d.ts +44 -0
  11. package/dist/client/helpers.d.ts.map +1 -0
  12. package/dist/client/helpers.js +79 -0
  13. package/dist/client/register-serializers.d.ts +41 -0
  14. package/dist/client/register-serializers.d.ts.map +1 -0
  15. package/dist/client/register-serializers.js +97 -0
  16. package/dist/contractArtifactCache.d.ts +49 -32
  17. package/dist/contractArtifactCache.d.ts.map +1 -1
  18. package/dist/contractArtifactCache.js +47 -34
  19. package/dist/errors.d.ts +50 -8
  20. package/dist/errors.d.ts.map +1 -1
  21. package/dist/errors.js +50 -10
  22. package/dist/index.d.ts +53 -40
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +52 -17
  25. package/dist/types.d.ts +345 -268
  26. package/dist/types.d.ts.map +1 -1
  27. package/dist/types.js +10 -8
  28. package/dist/wallet/create-node.d.ts +73 -0
  29. package/dist/wallet/create-node.d.ts.map +1 -0
  30. package/dist/wallet/create-node.js +99 -0
  31. package/dist/wallet/handlers/account.d.ts +67 -0
  32. package/dist/wallet/handlers/account.d.ts.map +1 -0
  33. package/dist/wallet/handlers/account.js +85 -0
  34. package/dist/wallet/handlers/contract-interaction.d.ts +77 -0
  35. package/dist/wallet/handlers/contract-interaction.d.ts.map +1 -0
  36. package/dist/wallet/handlers/contract-interaction.js +219 -0
  37. package/dist/wallet/handlers/contract.d.ts +96 -0
  38. package/dist/wallet/handlers/contract.d.ts.map +1 -0
  39. package/dist/wallet/handlers/contract.js +146 -0
  40. package/dist/wallet/handlers/event.d.ts +62 -0
  41. package/dist/wallet/handlers/event.d.ts.map +1 -0
  42. package/dist/wallet/handlers/event.js +85 -0
  43. package/dist/wallet/handlers/index.d.ts +88 -0
  44. package/dist/wallet/handlers/index.d.ts.map +1 -0
  45. package/dist/wallet/handlers/index.js +47 -0
  46. package/dist/wallet/handlers/node.d.ts +117 -0
  47. package/dist/wallet/handlers/node.d.ts.map +1 -0
  48. package/dist/wallet/handlers/node.js +196 -0
  49. package/dist/wallet/handlers/senders.d.ts +70 -0
  50. package/dist/wallet/handlers/senders.d.ts.map +1 -0
  51. package/dist/wallet/handlers/senders.js +92 -0
  52. package/dist/wallet/handlers/transaction.d.ts +123 -0
  53. package/dist/wallet/handlers/transaction.d.ts.map +1 -0
  54. package/dist/wallet/handlers/transaction.js +191 -0
  55. package/dist/wallet/serializers.d.ts +75 -0
  56. package/dist/wallet/serializers.d.ts.map +1 -0
  57. package/dist/wallet/serializers.js +501 -0
  58. package/docs/README.md +290 -229
  59. package/docs/classes/AztecDappWallet.md +1304 -0
  60. package/docs/classes/AztecRouterProvider.md +1058 -0
  61. package/docs/classes/AztecWalletError.md +124 -47
  62. package/docs/classes/ContractArtifactCache.md +48 -31
  63. package/docs/functions/connectAztec.md +62 -0
  64. package/docs/functions/createAztecWallet.md +46 -0
  65. package/docs/functions/createAztecWalletNode.md +96 -0
  66. package/docs/functions/registerAztecSerializers.md +61 -0
  67. package/docs/functions/registerWalletAztecSerializers.md +39 -0
  68. package/docs/globals.md +16 -14
  69. package/docs/interfaces/AztecHandlerContext.md +54 -0
  70. package/docs/interfaces/AztecWalletContext.md +50 -0
  71. package/docs/interfaces/AztecWalletMethodMap.md +471 -470
  72. package/docs/type-aliases/AztecChainId.md +16 -3
  73. package/docs/variables/ALL_AZTEC_METHODS.md +20 -0
  74. package/docs/variables/AztecWalletErrorMap.md +9 -4
  75. package/docs/variables/AztecWalletSerializer.md +45 -0
  76. package/package.json +9 -9
  77. package/src/client/aztec-dapp-wallet.test.ts +628 -0
  78. package/src/client/aztec-dapp-wallet.ts +879 -0
  79. package/src/client/aztec-router-provider.test.ts +235 -0
  80. package/src/client/aztec-router-provider.ts +64 -0
  81. package/src/client/helpers.test.ts +187 -0
  82. package/src/client/helpers.ts +91 -0
  83. package/src/client/register-serializers.ts +108 -0
  84. package/src/contractArtifactCache.test.ts +21 -10
  85. package/src/contractArtifactCache.ts +54 -35
  86. package/src/errors.ts +58 -10
  87. package/src/index.test.ts +2 -6
  88. package/src/index.ts +73 -37
  89. package/src/types.ts +379 -217
  90. package/src/wallet/create-node.test.ts +332 -0
  91. package/src/wallet/create-node.ts +120 -0
  92. package/src/wallet/handlers/account.test.ts +172 -0
  93. package/src/wallet/handlers/account.ts +99 -0
  94. package/src/wallet/handlers/contract-interaction.test.ts +248 -0
  95. package/src/wallet/handlers/contract-interaction.ts +269 -0
  96. package/src/wallet/handlers/contract.test.ts +245 -0
  97. package/src/wallet/handlers/contract.ts +174 -0
  98. package/src/wallet/handlers/event.test.ts +216 -0
  99. package/src/wallet/handlers/event.ts +99 -0
  100. package/src/wallet/handlers/index.ts +84 -0
  101. package/src/wallet/handlers/node.test.ts +304 -0
  102. package/src/wallet/handlers/node.ts +230 -0
  103. package/src/wallet/handlers/senders.test.ts +172 -0
  104. package/src/wallet/handlers/senders.ts +106 -0
  105. package/src/wallet/handlers/transaction.test.ts +371 -0
  106. package/src/wallet/handlers/transaction.ts +239 -0
  107. package/src/wallet/serializers.test.ts +253 -0
  108. package/src/wallet/serializers.ts +586 -0
  109. package/typedoc.json +23 -1
  110. package/dist/aztecRemoteWallet.d.ts +0 -70
  111. package/dist/aztecRemoteWallet.d.ts.map +0 -1
  112. package/dist/aztecRemoteWallet.js +0 -335
  113. package/dist/chainProvider.d.ts +0 -56
  114. package/dist/chainProvider.d.ts.map +0 -1
  115. package/dist/chainProvider.js +0 -98
  116. package/dist/handlers/aztecAccountWallet.d.ts +0 -4
  117. package/dist/handlers/aztecAccountWallet.d.ts.map +0 -1
  118. package/dist/handlers/aztecAccountWallet.js +0 -296
  119. package/dist/handlers/transactions.d.ts +0 -21
  120. package/dist/handlers/transactions.d.ts.map +0 -1
  121. package/dist/handlers/transactions.js +0 -98
  122. package/dist/handlers.d.ts +0 -27
  123. package/dist/handlers.d.ts.map +0 -1
  124. package/dist/handlers.js +0 -55
  125. package/dist/provider.d.ts +0 -105
  126. package/dist/provider.d.ts.map +0 -1
  127. package/dist/provider.js +0 -160
  128. package/dist/serializers/account.d.ts +0 -164
  129. package/dist/serializers/account.d.ts.map +0 -1
  130. package/dist/serializers/account.js +0 -244
  131. package/dist/serializers/contract.d.ts +0 -62
  132. package/dist/serializers/contract.d.ts.map +0 -1
  133. package/dist/serializers/contract.js +0 -130
  134. package/dist/serializers/index.d.ts +0 -21
  135. package/dist/serializers/index.d.ts.map +0 -1
  136. package/dist/serializers/index.js +0 -154
  137. package/dist/serializers/log.d.ts +0 -66
  138. package/dist/serializers/log.d.ts.map +0 -1
  139. package/dist/serializers/log.js +0 -222
  140. package/dist/serializers/note.d.ts +0 -124
  141. package/dist/serializers/note.d.ts.map +0 -1
  142. package/dist/serializers/note.js +0 -208
  143. package/dist/serializers/transaction.d.ts +0 -99
  144. package/dist/serializers/transaction.d.ts.map +0 -1
  145. package/dist/serializers/transaction.js +0 -275
  146. package/dist/wallet.d.ts +0 -62
  147. package/dist/wallet.d.ts.map +0 -1
  148. package/dist/wallet.js +0 -77
  149. package/docs/classes/AztecChainProvider.md +0 -553
  150. package/docs/classes/AztecChainWallet.md +0 -409
  151. package/docs/classes/AztecProvider.md +0 -1112
  152. package/docs/interfaces/AztecWalletBaseMethodMap.md +0 -135
  153. package/docs/interfaces/AztecWalletEventMap.md +0 -17
  154. package/docs/type-aliases/AztecChainWalletMiddleware.md +0 -13
  155. package/docs/type-aliases/AztecWalletContext.md +0 -29
  156. package/docs/type-aliases/AztecWalletMethodHandler.md +0 -37
  157. package/docs/type-aliases/AztecWalletMiddleware.md +0 -13
  158. package/docs/type-aliases/AztecWalletRouterClient.md +0 -13
  159. package/docs/type-aliases/TransactionFunctionCall.md +0 -33
  160. package/docs/type-aliases/TransactionParams.md +0 -27
  161. package/src/aztecRemoteWallet.test.ts +0 -504
  162. package/src/aztecRemoteWallet.ts +0 -467
  163. package/src/chainProvider.test.ts +0 -401
  164. package/src/chainProvider.ts +0 -116
  165. package/src/handlers/aztecAccountWallet.test.ts +0 -649
  166. package/src/handlers/aztecAccountWallet.ts +0 -532
  167. package/src/handlers/transactions.ts +0 -124
  168. package/src/handlers.test.ts +0 -270
  169. package/src/handlers.ts +0 -70
  170. package/src/provider.test.ts +0 -274
  171. package/src/provider.ts +0 -189
  172. package/src/serializers/account.test.ts +0 -125
  173. package/src/serializers/account.ts +0 -301
  174. package/src/serializers/contract.test.ts +0 -24
  175. package/src/serializers/contract.ts +0 -183
  176. package/src/serializers/index.test.ts +0 -136
  177. package/src/serializers/index.ts +0 -191
  178. package/src/serializers/log.test.ts +0 -286
  179. package/src/serializers/log.ts +0 -292
  180. package/src/serializers/note.test.ts +0 -125
  181. package/src/serializers/note.ts +0 -250
  182. package/src/serializers/transaction.test.ts +0 -320
  183. package/src/serializers/transaction.ts +0 -409
  184. package/src/wallet.test.ts +0 -275
  185. package/src/wallet.ts +0 -94
@@ -0,0 +1,245 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { createContractHandlers } from './contract.js';
3
+ import type { AccountWallet, PXE, AztecAddress } from '@aztec/aztec.js';
4
+ import type { ContractArtifact } from '@aztec/stdlib/abi';
5
+ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
6
+ import type { ContractClassMetadata, ContractMetadata } from '@aztec/stdlib/interfaces/client';
7
+ import type { AztecHandlerContext } from './index.js';
8
+ import type { ContractArtifactCache } from '../../contractArtifactCache.js';
9
+ import { Fr } from '@aztec/aztec.js';
10
+
11
+ // Mock dependencies
12
+ const createMockWallet = () =>
13
+ ({
14
+ registerContract: vi.fn(),
15
+ registerContractClass: vi.fn(),
16
+ getContractMetadata: vi.fn(),
17
+ getContractClassMetadata: vi.fn(),
18
+ }) as unknown as AccountWallet;
19
+
20
+ const createMockPXE = () =>
21
+ ({
22
+ getContracts: vi.fn(),
23
+ }) as unknown as PXE;
24
+
25
+ const createMockContext = (wallet: AccountWallet, pxe: PXE): AztecHandlerContext => ({
26
+ wallet,
27
+ pxe,
28
+ cache: {} as ContractArtifactCache,
29
+ });
30
+
31
+ describe('Contract Handlers', () => {
32
+ let mockWallet: AccountWallet;
33
+ let mockPXE: PXE;
34
+ let context: AztecHandlerContext;
35
+ let handlers: ReturnType<typeof createContractHandlers>;
36
+
37
+ beforeEach(() => {
38
+ mockWallet = createMockWallet();
39
+ mockPXE = createMockPXE();
40
+ context = createMockContext(mockWallet, mockPXE);
41
+ handlers = createContractHandlers();
42
+ });
43
+
44
+ describe('aztec_registerContract', () => {
45
+ it('should register contract with instance only', async () => {
46
+ const instance = {
47
+ address: '0x1234567890abcdef' as unknown as AztecAddress,
48
+ version: 1,
49
+ salt: new Fr(42n),
50
+ deployer: '0xabcdef1234567890' as unknown as AztecAddress,
51
+ contractClassId: new Fr(123n),
52
+ initializationHash: new Fr(456n),
53
+ publicKeysHash: new Fr(789n),
54
+ } as unknown as ContractInstanceWithAddress;
55
+
56
+ vi.mocked(mockWallet.registerContract).mockResolvedValue(undefined);
57
+
58
+ const result = await handlers.aztec_registerContract(context, [instance, undefined]);
59
+
60
+ expect(mockWallet.registerContract).toHaveBeenCalledWith({ instance });
61
+ expect(result).toBe(true);
62
+ });
63
+
64
+ it('should register contract with instance and artifact', async () => {
65
+ const instance = {
66
+ address: '0x1234567890abcdef' as unknown as AztecAddress,
67
+ version: 1,
68
+ salt: new Fr(42n),
69
+ deployer: '0xabcdef1234567890' as unknown as AztecAddress,
70
+ contractClassId: new Fr(123n),
71
+ initializationHash: new Fr(456n),
72
+ publicKeysHash: new Fr(789n),
73
+ } as unknown as ContractInstanceWithAddress;
74
+
75
+ const artifact = {
76
+ name: 'TestContract',
77
+ functions: [],
78
+ outputs: { structs: {}, globals: {} },
79
+ fileMap: {},
80
+ storageLayout: {},
81
+ notes: {},
82
+ } as unknown as ContractArtifact;
83
+
84
+ vi.mocked(mockWallet.registerContract).mockResolvedValue(undefined);
85
+
86
+ const result = await handlers.aztec_registerContract(context, [instance, artifact]);
87
+
88
+ expect(mockWallet.registerContract).toHaveBeenCalledWith({ instance, artifact });
89
+ expect(result).toBe(true);
90
+ });
91
+
92
+ it('should propagate errors from wallet.registerContract', async () => {
93
+ const instance = {
94
+ address: '0x1234567890abcdef' as unknown as AztecAddress,
95
+ } as unknown as ContractInstanceWithAddress;
96
+
97
+ const error = new Error('Failed to register contract');
98
+ vi.mocked(mockWallet.registerContract).mockRejectedValue(error);
99
+
100
+ await expect(handlers.aztec_registerContract(context, [instance, undefined])).rejects.toThrow(
101
+ 'Failed to register contract',
102
+ );
103
+ expect(mockWallet.registerContract).toHaveBeenCalledOnce();
104
+ });
105
+ });
106
+
107
+ describe('aztec_registerContractClass', () => {
108
+ it('should register contract class with artifact', async () => {
109
+ const artifact = {
110
+ name: 'TestContract',
111
+ functions: [],
112
+ outputs: { structs: {}, globals: {} },
113
+ fileMap: {},
114
+ storageLayout: {},
115
+ notes: {},
116
+ } as unknown as ContractArtifact;
117
+
118
+ vi.mocked(mockWallet.registerContractClass).mockResolvedValue(undefined);
119
+
120
+ const result = await handlers.aztec_registerContractClass(context, [artifact]);
121
+
122
+ expect(mockWallet.registerContractClass).toHaveBeenCalledWith(artifact);
123
+ expect(result).toBe(true);
124
+ });
125
+
126
+ it('should propagate errors from wallet.registerContractClass', async () => {
127
+ const artifact = {
128
+ name: 'TestContract',
129
+ } as unknown as ContractArtifact;
130
+
131
+ const error = new Error('Failed to register contract class');
132
+ vi.mocked(mockWallet.registerContractClass).mockRejectedValue(error);
133
+
134
+ await expect(handlers.aztec_registerContractClass(context, [artifact])).rejects.toThrow(
135
+ 'Failed to register contract class',
136
+ );
137
+ expect(mockWallet.registerContractClass).toHaveBeenCalledOnce();
138
+ });
139
+ });
140
+
141
+ describe('aztec_getContractMetadata', () => {
142
+ it('should get contract metadata for given address', async () => {
143
+ const address = '0x1234567890abcdef' as unknown as AztecAddress;
144
+ const expectedMetadata = {
145
+ name: 'TestContract',
146
+ portalContractAddress: '0xabc123' as unknown as AztecAddress,
147
+ blockNumber: 42,
148
+ } as unknown as ContractMetadata;
149
+
150
+ vi.mocked(mockWallet.getContractMetadata).mockResolvedValue(expectedMetadata);
151
+
152
+ const result = await handlers.aztec_getContractMetadata(context, [address]);
153
+
154
+ expect(mockWallet.getContractMetadata).toHaveBeenCalledWith(address);
155
+ expect(result).toBe(expectedMetadata);
156
+ });
157
+
158
+ it('should propagate errors from wallet.getContractMetadata', async () => {
159
+ const address = '0x1234567890abcdef' as unknown as AztecAddress;
160
+ const error = new Error('Contract not found');
161
+ vi.mocked(mockWallet.getContractMetadata).mockRejectedValue(error);
162
+
163
+ await expect(handlers.aztec_getContractMetadata(context, [address])).rejects.toThrow(
164
+ 'Contract not found',
165
+ );
166
+ expect(mockWallet.getContractMetadata).toHaveBeenCalledWith(address);
167
+ });
168
+ });
169
+
170
+ describe('aztec_getContracts', () => {
171
+ it('should get all contracts from PXE', async () => {
172
+ const expectedContracts = [
173
+ '0x1234567890abcdef' as unknown as AztecAddress,
174
+ '0xabcdef1234567890' as unknown as AztecAddress,
175
+ ];
176
+
177
+ vi.mocked(mockPXE.getContracts).mockResolvedValue(expectedContracts);
178
+
179
+ const result = await handlers.aztec_getContracts(context, []);
180
+
181
+ expect(mockPXE.getContracts).toHaveBeenCalledOnce();
182
+ expect(result).toBe(expectedContracts);
183
+ });
184
+
185
+ it('should propagate errors from pxe.getContracts', async () => {
186
+ const error = new Error('Failed to get contracts');
187
+ vi.mocked(mockPXE.getContracts).mockRejectedValue(error);
188
+
189
+ await expect(handlers.aztec_getContracts(context, [])).rejects.toThrow('Failed to get contracts');
190
+ expect(mockPXE.getContracts).toHaveBeenCalledOnce();
191
+ });
192
+ });
193
+
194
+ describe('aztec_getContractClassMetadata', () => {
195
+ it('should get contract class metadata without artifact', async () => {
196
+ const id = new Fr(123n);
197
+ const expectedMetadata = {
198
+ id,
199
+ artifactHash: new Fr(456n),
200
+ privateFunctionsRoot: new Fr(789n),
201
+ packedBytecode: Buffer.from('bytecode'),
202
+ } as unknown as ContractClassMetadata;
203
+
204
+ vi.mocked(mockWallet.getContractClassMetadata).mockResolvedValue(expectedMetadata);
205
+
206
+ const result = await handlers.aztec_getContractClassMetadata(context, [id, undefined]);
207
+
208
+ expect(mockWallet.getContractClassMetadata).toHaveBeenCalledWith(id, false);
209
+ expect(result).toBe(expectedMetadata);
210
+ });
211
+
212
+ it('should get contract class metadata with artifact', async () => {
213
+ const id = new Fr(123n);
214
+ const includeArtifact = true;
215
+ const expectedMetadata = {
216
+ id,
217
+ artifactHash: new Fr(456n),
218
+ privateFunctionsRoot: new Fr(789n),
219
+ packedBytecode: Buffer.from('bytecode'),
220
+ artifact: {
221
+ name: 'TestContract',
222
+ functions: [],
223
+ },
224
+ } as unknown as ContractClassMetadata;
225
+
226
+ vi.mocked(mockWallet.getContractClassMetadata).mockResolvedValue(expectedMetadata);
227
+
228
+ const result = await handlers.aztec_getContractClassMetadata(context, [id, includeArtifact]);
229
+
230
+ expect(mockWallet.getContractClassMetadata).toHaveBeenCalledWith(id, includeArtifact);
231
+ expect(result).toBe(expectedMetadata);
232
+ });
233
+
234
+ it('should propagate errors from wallet.getContractClassMetadata', async () => {
235
+ const id = new Fr(123n);
236
+ const error = new Error('Contract class not found');
237
+ vi.mocked(mockWallet.getContractClassMetadata).mockRejectedValue(error);
238
+
239
+ await expect(handlers.aztec_getContractClassMetadata(context, [id, undefined])).rejects.toThrow(
240
+ 'Contract class not found',
241
+ );
242
+ expect(mockWallet.getContractClassMetadata).toHaveBeenCalledWith(id, false);
243
+ });
244
+ });
245
+ });
@@ -0,0 +1,174 @@
1
+ import type { ContractArtifact } from '@aztec/stdlib/abi';
2
+ import type { ContractInstanceWithAddress } from '@aztec/stdlib/contract';
3
+ import type { AztecWalletMethodMap } from '../../types.js';
4
+ import type { AztecHandlerContext } from './index.js';
5
+ import { createLogger } from '@aztec/foundation/log';
6
+
7
+ const logger = createLogger('aztec-rpc-wallet:contract');
8
+
9
+ /**
10
+ * Creates handlers for contract-related Aztec wallet JSON-RPC methods.
11
+ * These handlers are responsible for managing the registration of deployed contract
12
+ * instances and contract classes (artifacts), as well as retrieving contract metadata.
13
+ *
14
+ * Each handler function receives an {@link AztecHandlerContext} which provides access
15
+ * to the {@link AccountWallet}, {@link PXE} client, and {@link ContractArtifactCache}.
16
+ *
17
+ * @returns An object where keys are contract-related method names
18
+ * (e.g., "aztec_registerContract", "aztec_getContractMetadata") and values
19
+ * are their corresponding handler functions.
20
+ * @see {@link AztecWalletMethodMap} for method definitions.
21
+ */
22
+ export function createContractHandlers() {
23
+ return {
24
+ /**
25
+ * Handles the "aztec_registerContract" JSON-RPC method.
26
+ * Registers a deployed contract instance with the {@link AccountWallet} in the context.
27
+ * This allows the wallet to be aware of and interact with the specified contract.
28
+ * An optional {@link ContractArtifact} can be provided to include ABI information.
29
+ *
30
+ * @param ctx - The {@link AztecHandlerContext} containing the `wallet` instance.
31
+ * @param paramsTuple - A tuple containing the contract instance and optional artifact.
32
+ * Defined by {@link AztecWalletMethodMap.aztec_registerContract.params}.
33
+ * @param paramsTuple.0 - The {@link ContractInstanceWithAddress} to register.
34
+ * @param paramsTuple.1 - Optional: The {@link ContractArtifact} associated with the instance.
35
+ * @returns A promise that resolves to `true` if the registration was successful.
36
+ * @throws {Error} If critical parameters like `instance` are missing or invalid,
37
+ * though type checking and serializer validation should catch this earlier.
38
+ */
39
+ aztec_registerContract: async (
40
+ ctx: AztecHandlerContext,
41
+ paramsTuple: AztecWalletMethodMap['aztec_registerContract']['params'],
42
+ ): Promise<AztecWalletMethodMap['aztec_registerContract']['result']> => {
43
+ const [instance, artifact] = paramsTuple;
44
+ logger.debug(
45
+ `[HANDLER] aztec_registerContract: instance = ${instance?.address?.toString()}, artifact provided = ${!!artifact}`,
46
+ );
47
+ // Original logic used `instance === undefined` check, but instance is not optional in the tuple.
48
+ // The type system should ensure `instance` is provided.
49
+ // If `instance` itself could be undefined in the tuple, the tuple type would be `[ContractInstanceWithAddress | undefined, ...]`.
50
+ // Assuming `instance` is guaranteed by the tuple type.
51
+ const contractToRegister: { instance: ContractInstanceWithAddress; artifact?: ContractArtifact } = {
52
+ instance,
53
+ };
54
+ if (artifact) {
55
+ contractToRegister.artifact = artifact;
56
+ }
57
+ await ctx.wallet.registerContract(contractToRegister);
58
+ return true;
59
+ },
60
+
61
+ /**
62
+ * Handles the "aztec_registerContractClass" JSON-RPC method.
63
+ * Registers a contract class (defined by its {@link ContractArtifact}) with the
64
+ * {@link AccountWallet} in the context. This makes the contract's bytecode and ABI
65
+ * known to the wallet, typically for future deployments or interactions.
66
+ *
67
+ * @param ctx - The {@link AztecHandlerContext} containing the `wallet` instance.
68
+ * @param paramsTuple - A tuple containing the contract artifact.
69
+ * Defined by {@link AztecWalletMethodMap.aztec_registerContractClass.params}.
70
+ * @param paramsTuple.0 - The {@link ContractArtifact} to register.
71
+ * @returns A promise that resolves to `true` if the registration was successful.
72
+ * @throws {Error} If the `artifact` parameter is missing or invalid,
73
+ * though type checking and serializer validation should catch this earlier.
74
+ */
75
+ aztec_registerContractClass: async (
76
+ ctx: AztecHandlerContext,
77
+ paramsTuple: AztecWalletMethodMap['aztec_registerContractClass']['params'],
78
+ ): Promise<AztecWalletMethodMap['aztec_registerContractClass']['result']> => {
79
+ const [artifact] = paramsTuple;
80
+ logger.debug(`[HANDLER] aztec_registerContractClass: artifact name = ${artifact?.name}`);
81
+ // Artifact is not optional in the tuple type.
82
+ await ctx.wallet.registerContractClass(artifact);
83
+ return true;
84
+ },
85
+
86
+ /**
87
+ * Handles the "aztec_getContractMetadata" JSON-RPC method.
88
+ * Retrieves {@link ContractMetadata} for a deployed contract at a given {@link AztecAddress},
89
+ * using the {@link AccountWallet} in the context.
90
+ *
91
+ * Contract metadata typically includes information about the contract's instance,
92
+ * initialization status, and public deployment status.
93
+ *
94
+ * @param ctx - The {@link AztecHandlerContext} containing the `wallet` instance.
95
+ * @param paramsTuple - A tuple containing the contract address.
96
+ * Defined by {@link AztecWalletMethodMap.aztec_getContractMetadata.params}.
97
+ * @param paramsTuple.0 - The {@link AztecAddress} of the contract.
98
+ * @returns A promise that resolves to the {@link ContractMetadata}.
99
+ * @throws {Error} If the `address` parameter is missing or invalid, or if metadata is not found.
100
+ */
101
+ aztec_getContractMetadata: async (
102
+ ctx: AztecHandlerContext,
103
+ paramsTuple: AztecWalletMethodMap['aztec_getContractMetadata']['params'],
104
+ ): Promise<AztecWalletMethodMap['aztec_getContractMetadata']['result']> => {
105
+ const [address] = paramsTuple;
106
+ logger.debug(`[HANDLER] aztec_getContractMetadata: address = ${address?.toString()}`);
107
+ // Address is not optional in the tuple type.
108
+ // Add runtime check for robustness if needed, though TS should catch it.
109
+ if (!address || typeof address.toString !== 'function') {
110
+ // Basic check
111
+ throw new Error('Invalid address parameter received in tuple');
112
+ }
113
+ const metadata = await ctx.wallet.getContractMetadata(address);
114
+ if (!metadata) {
115
+ throw new Error(`Contract metadata not found for address: ${address.toString()}`);
116
+ }
117
+ return metadata;
118
+ },
119
+
120
+ /**
121
+ * Handles the "aztec_getContracts" JSON-RPC method.
122
+ * Retrieves a list of {@link AztecAddress}es for all contracts known to the {@link PXE}
123
+ * instance in the current context. This typically includes contracts that have been
124
+ * registered or deployed through this PXE.
125
+ *
126
+ * @param ctx - The {@link AztecHandlerContext} containing the `pxe` instance.
127
+ * @param _paramsTuple - Parameters for this method (expected to be an empty array).
128
+ * Defined by {@link AztecWalletMethodMap.aztec_getContracts.params}.
129
+ * @returns A promise that resolves to an array of {@link AztecAddress} objects.
130
+ * Type defined by {@link AztecWalletMethodMap.aztec_getContracts.result}.
131
+ */
132
+ aztec_getContracts: async (
133
+ ctx: AztecHandlerContext,
134
+ _paramsTuple: AztecWalletMethodMap['aztec_getContracts']['params'], // Will be `[]`
135
+ ): Promise<AztecWalletMethodMap['aztec_getContracts']['result']> => {
136
+ logger.debug('[HANDLER] aztec_getContracts');
137
+ return await ctx.pxe.getContracts();
138
+ },
139
+
140
+ /**
141
+ * Handles the "aztec_getContractClassMetadata" JSON-RPC method.
142
+ * Retrieves {@link ContractClassMetadata} for a contract class identified by its {@link Fr} ID,
143
+ * using the {@link AccountWallet} in the context.
144
+ *
145
+ * Contract class metadata provides information about a registered contract class,
146
+ * potentially including its artifact if requested.
147
+ *
148
+ * @param ctx - The {@link AztecHandlerContext} containing the `wallet` instance.
149
+ * @param paramsTuple - A tuple containing the class ID and an optional flag to include the artifact.
150
+ * Defined by {@link AztecWalletMethodMap.aztec_getContractClassMetadata.params}.
151
+ * @param paramsTuple.0 - The {@link Fr} ID of the contract class.
152
+ * @param paramsTuple.1 - Optional: A boolean indicating whether to include the full {@link ContractArtifact}
153
+ * in the returned metadata. Defaults to `false`.
154
+ * @returns A promise that resolves to the {@link ContractClassMetadata}.
155
+ * @throws {Error} If the `id` parameter is missing or invalid.
156
+ */
157
+ aztec_getContractClassMetadata: async (
158
+ ctx: AztecHandlerContext,
159
+ paramsTuple: AztecWalletMethodMap['aztec_getContractClassMetadata']['params'],
160
+ ): Promise<AztecWalletMethodMap['aztec_getContractClassMetadata']['result']> => {
161
+ const [id, includeArtifactInput] = paramsTuple;
162
+ const includeArtifact = includeArtifactInput === undefined ? false : includeArtifactInput; // Default for optional
163
+ logger.debug(
164
+ `[HANDLER] aztec_getContractClassMetadata: id = ${id?.toString()}, includeArtifact = ${includeArtifact}`,
165
+ );
166
+ // Id is not optional in the tuple type.
167
+ if (!id || typeof id.toString !== 'function') {
168
+ // Basic check for Fr-like object
169
+ throw new Error('Invalid id parameter received in tuple');
170
+ }
171
+ return await ctx.wallet.getContractClassMetadata(id, includeArtifact);
172
+ },
173
+ };
174
+ }
@@ -0,0 +1,216 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { createEventHandlers } from './event.js';
3
+ import type { AccountWallet, PXE, AztecAddress } from '@aztec/aztec.js';
4
+ import type { EventMetadataDefinition } from '@aztec/stdlib/interfaces/client';
5
+ import type { AztecHandlerContext } from './index.js';
6
+ import type { ContractArtifactCache } from '../../contractArtifactCache.js';
7
+
8
+ // Mock dependencies
9
+ const createMockWallet = () =>
10
+ ({
11
+ // No specific methods needed for event handlers
12
+ }) as unknown as AccountWallet;
13
+
14
+ const createMockPXE = () =>
15
+ ({
16
+ getPrivateEvents: vi.fn(),
17
+ getPublicEvents: vi.fn(),
18
+ }) as unknown as PXE;
19
+
20
+ const createMockContext = (wallet: AccountWallet, pxe: PXE): AztecHandlerContext => ({
21
+ wallet,
22
+ pxe,
23
+ cache: {} as ContractArtifactCache,
24
+ });
25
+
26
+ describe('Event Handlers', () => {
27
+ let mockWallet: AccountWallet;
28
+ let mockPXE: PXE;
29
+ let context: AztecHandlerContext;
30
+ let handlers: ReturnType<typeof createEventHandlers>;
31
+
32
+ beforeEach(() => {
33
+ mockWallet = createMockWallet();
34
+ mockPXE = createMockPXE();
35
+ context = createMockContext(mockWallet, mockPXE);
36
+ handlers = createEventHandlers();
37
+ });
38
+
39
+ describe('aztec_getPrivateEvents', () => {
40
+ it('should get private events with all parameters', async () => {
41
+ const contractAddress = '0x1234567890abcdef' as unknown as AztecAddress;
42
+ const eventMetadata = {
43
+ eventSelector: 'TestEvent',
44
+ fieldNames: ['field1', 'field2'],
45
+ } as unknown as EventMetadataDefinition;
46
+ const from = 100;
47
+ const numBlocks = 50;
48
+ const recipients = [
49
+ '0xabcdef1234567890' as unknown as AztecAddress,
50
+ '0x567890abcdef1234' as unknown as AztecAddress,
51
+ ];
52
+
53
+ const expectedEvents = [
54
+ { eventType: 'TestEvent', data: { field1: 'value1', field2: 'value2' } },
55
+ { eventType: 'TestEvent', data: { field1: 'value3', field2: 'value4' } },
56
+ ];
57
+
58
+ vi.mocked(mockPXE.getPrivateEvents).mockResolvedValue(expectedEvents);
59
+
60
+ const result = await handlers.aztec_getPrivateEvents(context, [
61
+ contractAddress,
62
+ eventMetadata,
63
+ from,
64
+ numBlocks,
65
+ recipients,
66
+ ]);
67
+
68
+ expect(mockPXE.getPrivateEvents).toHaveBeenCalledWith(
69
+ contractAddress,
70
+ eventMetadata,
71
+ from,
72
+ numBlocks,
73
+ recipients,
74
+ );
75
+ expect(result).toBe(expectedEvents);
76
+ });
77
+
78
+ it('should get private events with minimal parameters', async () => {
79
+ const contractAddress = '0x1234567890abcdef' as unknown as AztecAddress;
80
+ const eventMetadata = {
81
+ eventSelector: 'TestEvent',
82
+ fieldNames: ['field1'],
83
+ } as unknown as EventMetadataDefinition;
84
+ const from = 0;
85
+ const numBlocks = 10;
86
+ const recipients: AztecAddress[] = [];
87
+
88
+ const expectedEvents = [{ eventType: 'TestEvent', data: { field1: 'value1' } }];
89
+
90
+ vi.mocked(mockPXE.getPrivateEvents).mockResolvedValue(expectedEvents);
91
+
92
+ const result = await handlers.aztec_getPrivateEvents(context, [
93
+ contractAddress,
94
+ eventMetadata,
95
+ from,
96
+ numBlocks,
97
+ recipients,
98
+ ]);
99
+
100
+ expect(mockPXE.getPrivateEvents).toHaveBeenCalledWith(
101
+ contractAddress,
102
+ eventMetadata,
103
+ from,
104
+ numBlocks,
105
+ recipients,
106
+ );
107
+ expect(result).toBe(expectedEvents);
108
+ });
109
+
110
+ it('should propagate errors from pxe.getPrivateEvents', async () => {
111
+ const contractAddress = '0x1234567890abcdef' as unknown as AztecAddress;
112
+ const eventMetadata = {
113
+ eventSelector: 'TestEvent',
114
+ fieldNames: ['field1'],
115
+ } as unknown as EventMetadataDefinition;
116
+ const from = 100;
117
+ const numBlocks = 50;
118
+ const recipients: AztecAddress[] = [];
119
+
120
+ const error = new Error('Failed to get private events');
121
+ vi.mocked(mockPXE.getPrivateEvents).mockRejectedValue(error);
122
+
123
+ await expect(
124
+ handlers.aztec_getPrivateEvents(context, [
125
+ contractAddress,
126
+ eventMetadata,
127
+ from,
128
+ numBlocks,
129
+ recipients,
130
+ ]),
131
+ ).rejects.toThrow('Failed to get private events');
132
+ expect(mockPXE.getPrivateEvents).toHaveBeenCalledWith(
133
+ contractAddress,
134
+ eventMetadata,
135
+ from,
136
+ numBlocks,
137
+ recipients,
138
+ );
139
+ });
140
+
141
+ it('should handle missing required parameters', async () => {
142
+ await expect(
143
+ handlers.aztec_getPrivateEvents(context, ['0x1234567890abcdef' as unknown as AztecAddress] as never),
144
+ ).rejects.toThrow();
145
+ });
146
+ });
147
+
148
+ describe('aztec_getPublicEvents', () => {
149
+ it('should get public events with all parameters', async () => {
150
+ const eventMetadata = {
151
+ eventSelector: 'PublicTestEvent',
152
+ fieldNames: ['publicField1', 'publicField2'],
153
+ } as unknown as EventMetadataDefinition;
154
+ const from = 200;
155
+ const limit = 25;
156
+
157
+ const expectedEvents = [
158
+ { eventType: 'PublicTestEvent', data: { publicField1: 'pubValue1', publicField2: 'pubValue2' } },
159
+ { eventType: 'PublicTestEvent', data: { publicField1: 'pubValue3', publicField2: 'pubValue4' } },
160
+ ];
161
+
162
+ vi.mocked(mockPXE.getPublicEvents).mockResolvedValue(expectedEvents);
163
+
164
+ const result = await handlers.aztec_getPublicEvents(context, [eventMetadata, from, limit]);
165
+
166
+ expect(mockPXE.getPublicEvents).toHaveBeenCalledWith(eventMetadata, from, limit);
167
+ expect(result).toBe(expectedEvents);
168
+ });
169
+
170
+ it('should get public events with minimal parameters', async () => {
171
+ const eventMetadata = {
172
+ eventSelector: 'PublicTestEvent',
173
+ fieldNames: ['publicField1'],
174
+ } as unknown as EventMetadataDefinition;
175
+ const from = 0;
176
+ const limit = 100;
177
+
178
+ const expectedEvents = [{ eventType: 'PublicTestEvent', data: { publicField1: 'pubValue1' } }];
179
+
180
+ vi.mocked(mockPXE.getPublicEvents).mockResolvedValue(expectedEvents);
181
+
182
+ const result = await handlers.aztec_getPublicEvents(context, [eventMetadata, from, limit]);
183
+
184
+ expect(mockPXE.getPublicEvents).toHaveBeenCalledWith(eventMetadata, from, limit);
185
+ expect(result).toBe(expectedEvents);
186
+ });
187
+
188
+ it('should propagate errors from pxe.getPublicEvents', async () => {
189
+ const eventMetadata = {
190
+ eventSelector: 'PublicTestEvent',
191
+ fieldNames: ['publicField1'],
192
+ } as unknown as EventMetadataDefinition;
193
+ const from = 200;
194
+ const limit = 25;
195
+
196
+ const error = new Error('Failed to get public events');
197
+ vi.mocked(mockPXE.getPublicEvents).mockRejectedValue(error);
198
+
199
+ await expect(handlers.aztec_getPublicEvents(context, [eventMetadata, from, limit])).rejects.toThrow(
200
+ 'Failed to get public events',
201
+ );
202
+ expect(mockPXE.getPublicEvents).toHaveBeenCalledWith(eventMetadata, from, limit);
203
+ });
204
+
205
+ it('should handle missing required parameters', async () => {
206
+ await expect(
207
+ handlers.aztec_getPublicEvents(context, [
208
+ {
209
+ eventSelector: 'PublicTestEvent',
210
+ fieldNames: ['publicField1'],
211
+ } as unknown as EventMetadataDefinition,
212
+ ] as never),
213
+ ).rejects.toThrow();
214
+ });
215
+ });
216
+ });