@walletmesh/aztec-rpc-wallet 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +201 -0
  3. package/README.md +260 -0
  4. package/dist/.tsbuildinfo +1 -0
  5. package/dist/aztecRemoteWallet.d.ts +73 -0
  6. package/dist/aztecRemoteWallet.d.ts.map +1 -0
  7. package/dist/aztecRemoteWallet.js +354 -0
  8. package/dist/chainProvider.d.ts +56 -0
  9. package/dist/chainProvider.d.ts.map +1 -0
  10. package/dist/chainProvider.js +98 -0
  11. package/dist/contractArtifactCache.d.ts +50 -0
  12. package/dist/contractArtifactCache.d.ts.map +1 -0
  13. package/dist/contractArtifactCache.js +66 -0
  14. package/dist/errors.d.ts +50 -0
  15. package/dist/errors.d.ts.map +1 -0
  16. package/dist/errors.js +62 -0
  17. package/dist/handlers/aztecAccountWallet.d.ts +4 -0
  18. package/dist/handlers/aztecAccountWallet.d.ts.map +1 -0
  19. package/dist/handlers/aztecAccountWallet.js +329 -0
  20. package/dist/handlers/transactions.d.ts +21 -0
  21. package/dist/handlers/transactions.d.ts.map +1 -0
  22. package/dist/handlers/transactions.js +90 -0
  23. package/dist/handlers.d.ts +27 -0
  24. package/dist/handlers.d.ts.map +1 -0
  25. package/dist/handlers.js +55 -0
  26. package/dist/index.d.ts +58 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +33 -0
  29. package/dist/provider.d.ts +105 -0
  30. package/dist/provider.d.ts.map +1 -0
  31. package/dist/provider.js +160 -0
  32. package/dist/serializers/account.d.ts +167 -0
  33. package/dist/serializers/account.d.ts.map +1 -0
  34. package/dist/serializers/account.js +245 -0
  35. package/dist/serializers/contract-utils.d.ts +40 -0
  36. package/dist/serializers/contract-utils.d.ts.map +1 -0
  37. package/dist/serializers/contract-utils.js +102 -0
  38. package/dist/serializers/contract.d.ts +168 -0
  39. package/dist/serializers/contract.d.ts.map +1 -0
  40. package/dist/serializers/contract.js +268 -0
  41. package/dist/serializers/core.d.ts +110 -0
  42. package/dist/serializers/core.d.ts.map +1 -0
  43. package/dist/serializers/core.js +130 -0
  44. package/dist/serializers/index.d.ts +28 -0
  45. package/dist/serializers/index.d.ts.map +1 -0
  46. package/dist/serializers/index.js +159 -0
  47. package/dist/serializers/log.d.ts +113 -0
  48. package/dist/serializers/log.d.ts.map +1 -0
  49. package/dist/serializers/log.js +231 -0
  50. package/dist/serializers/note.d.ts +127 -0
  51. package/dist/serializers/note.d.ts.map +1 -0
  52. package/dist/serializers/note.js +182 -0
  53. package/dist/serializers/transaction-utils.d.ts +107 -0
  54. package/dist/serializers/transaction-utils.d.ts.map +1 -0
  55. package/dist/serializers/transaction-utils.js +130 -0
  56. package/dist/serializers/transaction.d.ts +103 -0
  57. package/dist/serializers/transaction.d.ts.map +1 -0
  58. package/dist/serializers/transaction.js +238 -0
  59. package/dist/serializers/types.d.ts +49 -0
  60. package/dist/serializers/types.d.ts.map +1 -0
  61. package/dist/serializers/types.js +22 -0
  62. package/dist/types.d.ts +391 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +8 -0
  65. package/dist/wallet.d.ts +62 -0
  66. package/dist/wallet.d.ts.map +1 -0
  67. package/dist/wallet.js +77 -0
  68. package/package.json +44 -0
  69. package/src/aztecRemoteWallet.test.ts +542 -0
  70. package/src/aztecRemoteWallet.ts +484 -0
  71. package/src/chainProvider.test.ts +322 -0
  72. package/src/chainProvider.ts +122 -0
  73. package/src/contractArtifactCache.test.ts +126 -0
  74. package/src/contractArtifactCache.ts +75 -0
  75. package/src/errors.ts +71 -0
  76. package/src/handlers/aztecAccountWallet.test.ts +720 -0
  77. package/src/handlers/aztecAccountWallet.ts +593 -0
  78. package/src/handlers/transactions.ts +110 -0
  79. package/src/handlers.test.ts +270 -0
  80. package/src/handlers.ts +70 -0
  81. package/src/index.test.ts +23 -0
  82. package/src/index.ts +64 -0
  83. package/src/provider.test.ts +276 -0
  84. package/src/provider.ts +189 -0
  85. package/src/serializers/account.test.ts +125 -0
  86. package/src/serializers/account.ts +319 -0
  87. package/src/serializers/contract-utils.ts +104 -0
  88. package/src/serializers/contract.test.ts +162 -0
  89. package/src/serializers/contract.ts +350 -0
  90. package/src/serializers/core.test.ts +56 -0
  91. package/src/serializers/core.ts +141 -0
  92. package/src/serializers/index.test.ts +122 -0
  93. package/src/serializers/index.ts +213 -0
  94. package/src/serializers/log.test.ts +119 -0
  95. package/src/serializers/log.ts +283 -0
  96. package/src/serializers/note.test.ts +100 -0
  97. package/src/serializers/note.ts +227 -0
  98. package/src/serializers/transaction-utils.ts +237 -0
  99. package/src/serializers/transaction.test.ts +153 -0
  100. package/src/serializers/transaction.ts +342 -0
  101. package/src/serializers/types.ts +58 -0
  102. package/src/types.ts +295 -0
  103. package/src/wallet.test.ts +275 -0
  104. package/src/wallet.ts +94 -0
  105. package/tsconfig.build.json +6 -0
  106. package/tsconfig.json +11 -0
  107. package/typedoc.json +15 -0
  108. package/vitest.config.ts +10 -0
@@ -0,0 +1,275 @@
1
+ import { describe, expect, it, vi, beforeEach } from 'vitest';
2
+ import type { AccountWallet, PXE, TxHash } from '@aztec/aztec.js';
3
+ import { JSONRPCWalletClient } from '@walletmesh/router';
4
+ import { AztecChainWallet } from './wallet.js';
5
+ import { ContractArtifactCache } from './contractArtifactCache.js';
6
+ import { AztecWalletError } from './errors.js';
7
+ import type { JSONRPCTransport } from '@walletmesh/jsonrpc';
8
+ import type { AztecWalletContext } from './types.js';
9
+
10
+ describe('AztecChainWallet', () => {
11
+ let pxe: PXE;
12
+ let wallet: AccountWallet;
13
+ let transport: JSONRPCTransport;
14
+ let aztecWallet: AztecChainWallet;
15
+
16
+ beforeEach(() => {
17
+ // Mock PXE
18
+ pxe = {
19
+ // Add required PXE methods as needed
20
+ } as unknown as PXE;
21
+
22
+ // Mock AccountWallet
23
+ wallet = {
24
+ getAddress: vi.fn().mockResolvedValue('mockAddress'),
25
+ } as unknown as AccountWallet;
26
+
27
+ // Mock Transport
28
+ transport = {
29
+ send: vi.fn().mockResolvedValue(undefined),
30
+ on: vi.fn(),
31
+ off: vi.fn(),
32
+ emit: vi.fn(),
33
+ } as unknown as JSONRPCTransport;
34
+
35
+ // Create wallet instance
36
+ aztecWallet = new AztecChainWallet(pxe, wallet, transport);
37
+
38
+ // Setup fallback handler and serializer
39
+ const mockHandler = vi.fn().mockImplementation(async (context, method, params) => {
40
+ if (!isAztecWalletContext(context)) {
41
+ throw new AztecWalletError('unknownInternalError', 'Invalid context');
42
+ }
43
+ if (method === 'aztec_getAccount') {
44
+ return await context.wallet.getAddress();
45
+ }
46
+ throw new AztecWalletError('invalidRequest', `Method not supported: ${method}`);
47
+ });
48
+
49
+ const mockSerializer = {
50
+ serialize: vi.fn().mockImplementation((value) => value),
51
+ deserialize: vi.fn().mockImplementation((value) => value),
52
+ };
53
+
54
+ Object.defineProperties(aztecWallet, {
55
+ fallbackHandler: {
56
+ value: mockHandler,
57
+ writable: true,
58
+ configurable: true,
59
+ },
60
+ fallbackSerializer: {
61
+ value: mockSerializer,
62
+ writable: true,
63
+ configurable: true,
64
+ },
65
+ });
66
+ });
67
+
68
+ describe('constructor', () => {
69
+ it('initializes with valid context', () => {
70
+ expect(aztecWallet).toBeInstanceOf(AztecChainWallet);
71
+ const context = (aztecWallet as unknown as { context: AztecWalletContext }).context;
72
+ expect(context.pxe).toBe(pxe);
73
+ expect(context.wallet).toBe(wallet);
74
+ expect(context.contractArtifactCache).toBeInstanceOf(ContractArtifactCache);
75
+ });
76
+
77
+ it('sets up fallback handler and serializer', () => {
78
+ const instance = aztecWallet as unknown as {
79
+ fallbackHandler: unknown;
80
+ fallbackSerializer: unknown;
81
+ };
82
+ expect(instance.fallbackHandler).toBeDefined();
83
+ expect(instance.fallbackSerializer).toBeDefined();
84
+ });
85
+
86
+ it('throws error when handler receives invalid context', async () => {
87
+ // Create a mock transport that simulates an error response
88
+ const mockSend = vi
89
+ .fn()
90
+ .mockRejectedValue(new AztecWalletError('unknownInternalError', 'Invalid context'));
91
+
92
+ const invalidTransport = {
93
+ send: mockSend,
94
+ on: vi.fn(),
95
+ off: vi.fn(),
96
+ emit: vi.fn(),
97
+ } as unknown as JSONRPCTransport;
98
+
99
+ // Create wallet with invalid context
100
+ new AztecChainWallet(null as unknown as PXE, null as unknown as AccountWallet, invalidTransport);
101
+
102
+ // Attempt to send a request
103
+ const request = {
104
+ jsonrpc: '2.0',
105
+ id: 1,
106
+ method: 'test_method',
107
+ params: [],
108
+ };
109
+
110
+ // Verify the error is thrown
111
+ await expect(mockSend(request)).rejects.toThrow(AztecWalletError);
112
+ expect(mockSend).toHaveBeenCalledWith(request);
113
+ });
114
+ });
115
+
116
+ describe('isAztecWalletContext', () => {
117
+ it('returns true for valid context', () => {
118
+ const validContext = {
119
+ pxe,
120
+ wallet,
121
+ contractArtifactCache: new ContractArtifactCache(wallet),
122
+ };
123
+ expect(isAztecWalletContext(validContext)).toBe(true);
124
+ });
125
+
126
+ it('returns false for null', () => {
127
+ expect(isAztecWalletContext(null)).toBe(false);
128
+ });
129
+
130
+ it('returns false for non-object values', () => {
131
+ expect(isAztecWalletContext(123)).toBe(false);
132
+ expect(isAztecWalletContext('string')).toBe(false);
133
+ expect(isAztecWalletContext(undefined)).toBe(false);
134
+ expect(isAztecWalletContext(true)).toBe(false);
135
+ expect(isAztecWalletContext([])).toBe(false);
136
+ expect(isAztecWalletContext(() => {})).toBe(false);
137
+ });
138
+
139
+ it('returns false for missing required properties', () => {
140
+ expect(isAztecWalletContext({})).toBe(false);
141
+ expect(isAztecWalletContext({ pxe })).toBe(false);
142
+ expect(isAztecWalletContext({ pxe, wallet })).toBe(false);
143
+ expect(isAztecWalletContext({ wallet, contractArtifactCache: new ContractArtifactCache(wallet) })).toBe(
144
+ false,
145
+ );
146
+ });
147
+
148
+ it('returns false for objects with null properties', () => {
149
+ expect(isAztecWalletContext({ pxe: null, wallet: null, contractArtifactCache: null })).toBe(false);
150
+ expect(
151
+ isAztecWalletContext({ pxe, wallet: null, contractArtifactCache: new ContractArtifactCache(wallet) }),
152
+ ).toBe(false);
153
+ expect(
154
+ isAztecWalletContext({ pxe: null, wallet, contractArtifactCache: new ContractArtifactCache(wallet) }),
155
+ ).toBe(false);
156
+ });
157
+ });
158
+
159
+ describe('asWalletRouterClient', () => {
160
+ it('returns a JSONRPCWalletClient instance', () => {
161
+ const client = aztecWallet.asWalletRouterClient();
162
+ expect(client).toBeInstanceOf(JSONRPCWalletClient);
163
+ });
164
+
165
+ it('returns a valid router client', () => {
166
+ const client = aztecWallet.asWalletRouterClient();
167
+ // Verify the client is properly instantiated
168
+ expect(client).toBeDefined();
169
+ expect(client).toBeInstanceOf(JSONRPCWalletClient);
170
+ });
171
+ });
172
+
173
+ describe('request handling', () => {
174
+ it('handles valid context in fallback handler', async () => {
175
+ const result = await (
176
+ aztecWallet as unknown as {
177
+ fallbackHandler: (
178
+ context: AztecWalletContext,
179
+ method: string,
180
+ params: unknown[],
181
+ ) => Promise<unknown>;
182
+ }
183
+ ).fallbackHandler(
184
+ {
185
+ pxe,
186
+ wallet,
187
+ contractArtifactCache: new ContractArtifactCache(wallet),
188
+ },
189
+ 'aztec_getAccount',
190
+ [],
191
+ );
192
+ expect(result).toBe('mockAddress');
193
+ });
194
+
195
+ it('throws error for invalid context in fallback handler', async () => {
196
+ await expect(
197
+ (
198
+ aztecWallet as unknown as {
199
+ fallbackHandler: (
200
+ context: AztecWalletContext,
201
+ method: string,
202
+ params: unknown[],
203
+ ) => Promise<unknown>;
204
+ }
205
+ ).fallbackHandler({ invalidContext: true } as unknown as AztecWalletContext, 'aztec_getAccount', []),
206
+ ).rejects.toThrow(AztecWalletError);
207
+ });
208
+ });
209
+
210
+ describe('message handling', () => {
211
+ it('processes incoming messages through transport', async () => {
212
+ const message = {
213
+ jsonrpc: '2.0',
214
+ id: 1,
215
+ method: 'aztec_getAccount',
216
+ params: [],
217
+ };
218
+
219
+ // Setup request handler to use fallback handler
220
+ const handleRequest = async (msg: unknown) => {
221
+ const typedMessage = msg as { method: string; params: unknown[] };
222
+ return (
223
+ aztecWallet as unknown as {
224
+ fallbackHandler: (
225
+ context: AztecWalletContext,
226
+ method: string,
227
+ params: unknown[],
228
+ ) => Promise<unknown>;
229
+ }
230
+ ).fallbackHandler(
231
+ { pxe, wallet, contractArtifactCache: new ContractArtifactCache(wallet) },
232
+ typedMessage.method,
233
+ typedMessage.params,
234
+ );
235
+ };
236
+
237
+ (aztecWallet as unknown as { handleRequest: typeof handleRequest }).handleRequest = handleRequest;
238
+
239
+ await handleRequest(message);
240
+ expect(wallet.getAddress).toHaveBeenCalled();
241
+ });
242
+
243
+ it('handles transport errors gracefully', async () => {
244
+ const message = {
245
+ jsonrpc: '2.0',
246
+ id: 1,
247
+ method: 'invalidMethod',
248
+ params: [],
249
+ };
250
+
251
+ // Setup request handler to throw error for invalid method
252
+ const handleRequest = async (msg: unknown) => {
253
+ throw new AztecWalletError('invalidRequest', 'Invalid method');
254
+ };
255
+
256
+ (aztecWallet as unknown as { handleRequest: typeof handleRequest }).handleRequest = handleRequest;
257
+
258
+ await expect(handleRequest(message)).rejects.toThrow(AztecWalletError);
259
+ });
260
+ });
261
+ });
262
+
263
+ // Helper function to check context type
264
+ function isAztecWalletContext(value: unknown): value is AztecWalletContext {
265
+ return (
266
+ typeof value === 'object' &&
267
+ value !== null &&
268
+ 'pxe' in value &&
269
+ 'wallet' in value &&
270
+ 'contractArtifactCache' in value &&
271
+ value.pxe !== null &&
272
+ value.wallet !== null &&
273
+ value.contractArtifactCache !== null
274
+ );
275
+ }
package/src/wallet.ts ADDED
@@ -0,0 +1,94 @@
1
+ import type { AccountWallet, PXE } from '@aztec/aztec.js';
2
+
3
+ import { JSONRPCNode, type JSONRPCTransport } from '@walletmesh/jsonrpc';
4
+ import { JSONRPCWalletClient } from '@walletmesh/router';
5
+
6
+ import type {
7
+ AztecWalletMethodMap,
8
+ AztecWalletContext,
9
+ AztecWalletEventMap,
10
+ AztecWalletRouterClient,
11
+ } from './types.js';
12
+ import { AztecWalletSerializer } from './serializers/index.js';
13
+
14
+ import { ContractArtifactCache } from './contractArtifactCache.js';
15
+ import { handler } from './handlers.js';
16
+
17
+ /**
18
+ * @module wallet
19
+ *
20
+ * This module provides the server-side implementation of the Aztec RPC interface.
21
+ * It handles incoming RPC requests from dApps and executes them using an Aztec wallet instance.
22
+ */
23
+
24
+ /**
25
+ * JSON-RPC interface implementation for an Aztec Wallet.
26
+ *
27
+ * This class provides the core wallet functionality exposed through JSON-RPC:
28
+ * - Handles incoming RPC requests from dApps
29
+ * - Manages wallet state and context
30
+ * - Executes operations through the underlying Aztec wallet
31
+ * - Serializes responses back to JSON-RPC format
32
+ *
33
+ * The wallet supports operations like:
34
+ * - Account management
35
+ * - Transaction execution
36
+ * - Contract interaction
37
+ * - Note management
38
+ * - Event logging
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * // Create wallet instance
43
+ * const wallet = new AztecChainWallet(aztecWallet, transport);
44
+ *
45
+ * // Handle incoming RPC requests
46
+ * transport.on('message', async (request) => {
47
+ * const response = await wallet.handleRequest(request);
48
+ * // Send response back to dApp
49
+ * });
50
+ * ```
51
+ *
52
+ * @public
53
+ */
54
+ export class AztecChainWallet extends JSONRPCNode<
55
+ AztecWalletMethodMap,
56
+ AztecWalletEventMap,
57
+ AztecWalletContext
58
+ > {
59
+ /**
60
+ * Creates a new AztecWallet instance.
61
+ *
62
+ * @param pxe - The PXE instance for the Aztec protocol
63
+ * @param wallet - The underlying Aztec wallet instance that executes operations
64
+ * @param transport - Transport layer for sending/receiving JSON-RPC messages
65
+ *
66
+ * The wallet instance sets up:
67
+ * - Contract artifact caching
68
+ * - Default request handlers
69
+ * - Custom serialization for Aztec types
70
+ */
71
+ constructor(pxe: PXE, wallet: AccountWallet, transport: JSONRPCTransport) {
72
+ const context: AztecWalletContext = {
73
+ pxe,
74
+ wallet,
75
+ contractArtifactCache: new ContractArtifactCache(wallet),
76
+ };
77
+ super(transport, context);
78
+
79
+ this.setFallbackHandler(async (handlerContext: AztecWalletContext, method, params) => {
80
+ return await handler(handlerContext, method, params);
81
+ });
82
+ this.setFallbackSerializer(AztecWalletSerializer);
83
+ }
84
+
85
+ /**
86
+ * Creates a client wrapper for use with WalletMesh router.
87
+ * This enables the wallet to be used as a client in a routing setup.
88
+ *
89
+ * @returns Client interface for the wallet
90
+ */
91
+ asWalletRouterClient(): AztecWalletRouterClient {
92
+ return new JSONRPCWalletClient(this);
93
+ }
94
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "./tsconfig.json",
3
+ "exclude": [
4
+ "src/**/*.test.ts",
5
+ ]
6
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "extends": "../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "rootDir": "src",
5
+ "outDir": "dist",
6
+ "tsBuildInfoFile": "dist/.tsbuildinfo",
7
+ },
8
+ "include": [
9
+ "src/**/*",
10
+ ]
11
+ }
package/typedoc.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://typedoc-plugin-markdown.org/schema.json",
3
+ "plugin": [
4
+ "typedoc-plugin-markdown"
5
+ ],
6
+ "entryPoints": [
7
+ "src/index.ts"
8
+ ],
9
+ "out": "docs",
10
+ "exclude": [
11
+ "**/*.test.ts"
12
+ ],
13
+ "includeVersion": true,
14
+ "excludePrivate": true
15
+ }
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ testTimeout: 200, // .2 second timeout
6
+ coverage: {
7
+ include: ['src/**/*.ts', '!src/**/types.ts', '!src/**/index.ts', '!src/**/*.test.ts'],
8
+ },
9
+ },
10
+ });