@provablehq/aleo-wallet-adaptor-shield 0.3.0-alpha.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/dist/index.mjs ADDED
@@ -0,0 +1,386 @@
1
+ // src/ShieldWalletAdapter.ts
2
+ import {
3
+ Network
4
+ } from "@provablehq/aleo-types";
5
+ import {
6
+ WalletDecryptPermission,
7
+ WalletReadyState
8
+ } from "@provablehq/aleo-wallet-standard";
9
+ import {
10
+ BaseAleoWalletAdapter,
11
+ WalletConnectionError,
12
+ WalletDisconnectionError,
13
+ WalletError,
14
+ WalletNotConnectedError,
15
+ WalletSwitchNetworkError,
16
+ WalletSignMessageError,
17
+ WalletTransactionError,
18
+ WalletDecryptionError,
19
+ WalletDecryptionNotAllowedError,
20
+ scopePollingDetectionStrategy
21
+ } from "@provablehq/aleo-wallet-adaptor-core";
22
+ var ShieldWalletAdapter = class extends BaseAleoWalletAdapter {
23
+ /**
24
+ * Create a new Shield wallet adapter
25
+ * @param config Adapter configuration
26
+ */
27
+ constructor(config) {
28
+ super();
29
+ /**
30
+ * The wallet name
31
+ */
32
+ this.name = "Shield Wallet";
33
+ /**
34
+ * The wallet URL
35
+ */
36
+ this.url = "https://provable.com/";
37
+ /**
38
+ * The wallet icon (base64-encoded SVG)
39
+ */
40
+ this.icon = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAyNCIgaGVpZ2h0PSIxMDI0IiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cmVjdCB3aWR0aD0iMTAyNCIgaGVpZ2h0PSIxMDI0IiBmaWxsPSIjMDkwNzA3Ii8+CjxwYXRoIGQ9Ik01MTIgODcxQzcxMC4yNyA4NzEgODcxIDcxMC4yNyA4NzEgNTEyQzg3MSA1MDUuMTI0IDg3MC44MDcgNDk4LjI5MyA4NzAuNDI1IDQ5MS41MTJDNzQ2LjQzIDYyNy4wNTggNDYxLjk5NCA3NjIuNDcgMzE0LjM5OSA4MTAuNjY0TDMxMi42ODQgODEwLjYzM0MzNjkuNzA0IDg0OC43NjUgNDM4LjI1NSA4NzEgNTEyIDg3MVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0yNTAuNDA4IDc1Ny44NjhDMTkwLjAwNiA2OTMuNjI4IDE1MyA2MDcuMTM2IDE1MyA1MTJDMTUzIDMxMy43MyAzMTMuNzMgMTUzIDUxMiAxNTNDNjkyLjk5MyAxNTMgODQyLjcwMyAyODYuOTM4IDg2Ny40MiA0NjEuMTA1QzYxMS4yMTIgNjM4LjgyMyAzNzcuNjU5IDcxOC42OCAyNTEuMDQ2IDc1Ny44NjhIMjUwLjQwOFoiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPgo=";
41
+ /**
42
+ * The wallet's decrypt permission
43
+ */
44
+ this.decryptPermission = WalletDecryptPermission.NoDecrypt;
45
+ /**
46
+ * Public key
47
+ */
48
+ this._publicKey = "";
49
+ this._readyState = typeof window === "undefined" || typeof document === "undefined" ? WalletReadyState.UNSUPPORTED : WalletReadyState.NOT_DETECTED;
50
+ /**
51
+ * EVENTS HANDLING
52
+ */
53
+ // Network change listener
54
+ this._onNetworkChange = (network) => {
55
+ console.debug("Shield Wallet network changed to: ", network);
56
+ this.network = network;
57
+ this.emit("networkChange", network);
58
+ };
59
+ // Account change listener
60
+ this._onAccountChange = () => {
61
+ console.debug("Shield Wallet account change detected \u2013 reauthorization required");
62
+ this._publicKey = "";
63
+ this.account = void 0;
64
+ this.emit("accountChange");
65
+ };
66
+ // Disconnect listener
67
+ this._onDisconnect = () => {
68
+ console.debug("Shield Wallet disconnected");
69
+ this._cleanupListeners();
70
+ this._publicKey = "";
71
+ this.account = void 0;
72
+ this.emit("disconnect");
73
+ };
74
+ console.debug("ShieldWalletAdapter constructor", config);
75
+ this.network = Network.TESTNET3;
76
+ if (this._readyState !== WalletReadyState.UNSUPPORTED) {
77
+ scopePollingDetectionStrategy(() => this._checkAvailability());
78
+ }
79
+ }
80
+ /**
81
+ * Check if Shield wallet is available
82
+ */
83
+ _checkAvailability() {
84
+ this._window = window;
85
+ if (this._window.shield) {
86
+ this.readyState = WalletReadyState.INSTALLED;
87
+ this._shieldWallet = this._window?.shield;
88
+ return true;
89
+ } else {
90
+ const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
91
+ if (isMobile) {
92
+ this.readyState = WalletReadyState.LOADABLE;
93
+ return true;
94
+ }
95
+ return false;
96
+ }
97
+ }
98
+ /**
99
+ * Connect to Shield wallet
100
+ * @returns The connected account
101
+ */
102
+ async connect(network, decryptPermission, programs) {
103
+ try {
104
+ if (this.readyState !== WalletReadyState.INSTALLED) {
105
+ throw new WalletConnectionError("Shield Wallet is not available");
106
+ }
107
+ try {
108
+ const connectResult = await this._shieldWallet?.connect(
109
+ network,
110
+ decryptPermission,
111
+ programs
112
+ );
113
+ this._publicKey = connectResult?.address || "";
114
+ this._onNetworkChange(network);
115
+ } catch (error) {
116
+ throw new WalletConnectionError(
117
+ error instanceof Error ? error.message : "Connection failed"
118
+ );
119
+ }
120
+ if (!this._publicKey) {
121
+ throw new WalletConnectionError("No address returned from wallet");
122
+ }
123
+ this._setupListeners();
124
+ const account = {
125
+ address: this._publicKey
126
+ };
127
+ this.account = account;
128
+ this.decryptPermission = decryptPermission;
129
+ this.emit("connect", account);
130
+ return account;
131
+ } catch (err) {
132
+ this.emit("error", err instanceof Error ? err : new Error(String(err)));
133
+ throw new WalletConnectionError(err instanceof Error ? err.message : "Connection failed");
134
+ }
135
+ }
136
+ /**
137
+ * Disconnect from Shield wallet
138
+ */
139
+ async disconnect() {
140
+ try {
141
+ this._cleanupListeners();
142
+ await this._shieldWallet?.disconnect();
143
+ this._onDisconnect();
144
+ } catch (err) {
145
+ this.emit("error", err instanceof Error ? err : new Error(String(err)));
146
+ throw new WalletDisconnectionError(
147
+ err instanceof Error ? err.message : "Disconnection failed"
148
+ );
149
+ }
150
+ }
151
+ /**
152
+ * Sign a transaction with Shield wallet
153
+ * @param message The message to sign
154
+ * @returns The signed message
155
+ */
156
+ async signMessage(message) {
157
+ if (!this._publicKey || !this.account) {
158
+ throw new WalletNotConnectedError();
159
+ }
160
+ try {
161
+ const signature = await this._shieldWallet?.signMessage(message);
162
+ if (!signature) {
163
+ throw new WalletSignMessageError("Failed to sign message");
164
+ }
165
+ return signature;
166
+ } catch (error) {
167
+ throw new WalletSignMessageError(
168
+ error instanceof Error ? error.message : "Failed to sign message"
169
+ );
170
+ }
171
+ }
172
+ async decrypt(cipherText) {
173
+ if (!this._shieldWallet || !this._publicKey) {
174
+ throw new WalletNotConnectedError();
175
+ }
176
+ switch (this.decryptPermission) {
177
+ case WalletDecryptPermission.NoDecrypt:
178
+ throw new WalletDecryptionNotAllowedError();
179
+ case WalletDecryptPermission.UponRequest:
180
+ case WalletDecryptPermission.AutoDecrypt:
181
+ case WalletDecryptPermission.OnChainHistory: {
182
+ try {
183
+ return await this._shieldWallet.decrypt(cipherText);
184
+ } catch (error) {
185
+ throw new WalletDecryptionError(
186
+ error instanceof Error ? error.message : "Failed to decrypt"
187
+ );
188
+ }
189
+ }
190
+ default:
191
+ throw new WalletDecryptionError();
192
+ }
193
+ }
194
+ /**
195
+ * Execute a transaction with Shield wallet
196
+ * @param options Transaction options
197
+ * @returns The executed temporary transaction ID
198
+ */
199
+ async executeTransaction(options) {
200
+ if (!this._publicKey || !this.account) {
201
+ throw new WalletNotConnectedError();
202
+ }
203
+ try {
204
+ const result = await this._shieldWallet?.executeTransaction({
205
+ ...options,
206
+ network: this.network
207
+ });
208
+ if (!result?.transactionId) {
209
+ throw new WalletTransactionError("Could not create transaction");
210
+ }
211
+ return {
212
+ transactionId: result.transactionId
213
+ };
214
+ } catch (error) {
215
+ console.error("ShieldWalletAdapter executeTransaction error", error);
216
+ if (error instanceof WalletError) {
217
+ throw error;
218
+ }
219
+ throw new WalletTransactionError(
220
+ error instanceof Error ? error.message : "Failed to execute transaction"
221
+ );
222
+ }
223
+ }
224
+ /**
225
+ * Get transaction status
226
+ * @param transactionId The transaction ID
227
+ * @returns The transaction status
228
+ */
229
+ async transactionStatus(transactionId) {
230
+ if (!this._publicKey || !this.account) {
231
+ throw new WalletNotConnectedError();
232
+ }
233
+ try {
234
+ const result = await this._shieldWallet?.transactionStatus(transactionId);
235
+ if (!result?.status) {
236
+ throw new WalletTransactionError("Could not get transaction status");
237
+ }
238
+ return result;
239
+ } catch (error) {
240
+ throw new WalletTransactionError(
241
+ error instanceof Error ? error.message : "Failed to get transaction status"
242
+ );
243
+ }
244
+ }
245
+ /**
246
+ * Switch the network
247
+ * @param network The network to switch to
248
+ */
249
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
250
+ async switchNetwork(_network) {
251
+ if (!this._publicKey || !this.account) {
252
+ throw new WalletNotConnectedError();
253
+ }
254
+ try {
255
+ await this._shieldWallet?.switchNetwork(_network);
256
+ this._onNetworkChange(_network);
257
+ } catch (error) {
258
+ throw new WalletSwitchNetworkError(
259
+ error instanceof Error ? error.message : "Failed to switch network"
260
+ );
261
+ }
262
+ }
263
+ /**
264
+ * Request records from Shield wallet
265
+ * @param program The program to request records from
266
+ * @param includePlaintext Whether to include plaintext on each record
267
+ * @returns The records
268
+ */
269
+ async requestRecords(program, includePlaintext) {
270
+ if (!this._publicKey || !this.account) {
271
+ throw new WalletNotConnectedError();
272
+ }
273
+ try {
274
+ const result = await this._shieldWallet?.requestRecords(program, includePlaintext);
275
+ return result || [];
276
+ } catch (error) {
277
+ throw new WalletError(error instanceof Error ? error.message : "Failed to request records");
278
+ }
279
+ }
280
+ /**
281
+ * Execute a deployment
282
+ * @param deployment The deployment to execute
283
+ * @returns The executed transaction ID
284
+ */
285
+ async executeDeployment(deployment) {
286
+ try {
287
+ if (!this._publicKey || !this.account) {
288
+ throw new WalletNotConnectedError();
289
+ }
290
+ try {
291
+ const result = await this._shieldWallet?.executeDeployment({
292
+ ...deployment,
293
+ network: this.network
294
+ });
295
+ if (!result?.transactionId) {
296
+ throw new WalletTransactionError("Could not create deployment");
297
+ }
298
+ return {
299
+ transactionId: result.transactionId
300
+ };
301
+ } catch (error) {
302
+ throw new WalletTransactionError(
303
+ error instanceof Error ? error.message : "Failed to execute deployment"
304
+ );
305
+ }
306
+ } catch (error) {
307
+ this.emit("error", error instanceof Error ? error : new Error(String(error)));
308
+ throw error;
309
+ }
310
+ }
311
+ /**
312
+ * get transition view keys(tvk) for a transaction
313
+ * @param transactionId The transaction ID
314
+ * @returns The tvk array
315
+ */
316
+ async transitionViewKeys(transactionId) {
317
+ try {
318
+ if (!this._publicKey || !this.account) {
319
+ throw new WalletNotConnectedError();
320
+ }
321
+ try {
322
+ const result = await this._shieldWallet?.transitionViewKeys(transactionId);
323
+ if (!Array.isArray(result)) {
324
+ throw new WalletTransactionError("Could not get transitionViewKeys");
325
+ }
326
+ return result;
327
+ } catch (error) {
328
+ throw new WalletTransactionError(
329
+ error instanceof Error ? error.message : "Failed to get transitionViewKeys"
330
+ );
331
+ }
332
+ } catch (error) {
333
+ this.emit("error", error instanceof Error ? error : new Error(String(error)));
334
+ throw error;
335
+ }
336
+ }
337
+ /**
338
+ * get transaction of specific program
339
+ * @param program The program ID
340
+ * @returns array of transactionId
341
+ */
342
+ async requestTransactionHistory(program) {
343
+ try {
344
+ if (!this._publicKey || !this.account) {
345
+ throw new WalletNotConnectedError();
346
+ }
347
+ try {
348
+ const result = await this._shieldWallet?.requestTransactionHistory(program);
349
+ if (!result?.transactions || !Array.isArray(result.transactions)) {
350
+ throw new WalletTransactionError("Could not get TransactionHistory");
351
+ }
352
+ return result;
353
+ } catch (error) {
354
+ throw new WalletTransactionError(
355
+ error instanceof Error ? error.message : "Failed to get transitionViewKeys"
356
+ );
357
+ }
358
+ } catch (error) {
359
+ this.emit("error", error instanceof Error ? error : new Error(String(error)));
360
+ throw error;
361
+ }
362
+ }
363
+ /**
364
+ * Set up event listeners with structured approach
365
+ */
366
+ _setupListeners() {
367
+ if (!this._shieldWallet)
368
+ return;
369
+ this._shieldWallet.on("networkChanged", this._onNetworkChange);
370
+ this._shieldWallet.on("disconnect", this._onDisconnect);
371
+ this._shieldWallet.on("accountChanged", this._onAccountChange);
372
+ }
373
+ /**
374
+ * Clean up all event listeners
375
+ */
376
+ _cleanupListeners() {
377
+ if (!this._shieldWallet)
378
+ return;
379
+ this._shieldWallet.off("networkChanged", this._onNetworkChange);
380
+ this._shieldWallet.off("disconnect", this._onDisconnect);
381
+ this._shieldWallet.off("accountChanged", this._onAccountChange);
382
+ }
383
+ };
384
+ export {
385
+ ShieldWalletAdapter
386
+ };
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@provablehq/aleo-wallet-adaptor-shield",
3
+ "version": "0.3.0-alpha.0",
4
+ "description": "Shield wallet adapter for Aleo",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "license": "GPL-3.0-or-later",
9
+ "files": [
10
+ "dist",
11
+ "src"
12
+ ],
13
+ "dependencies": {
14
+ "@provablehq/aleo-types": "0.3.0-alpha.0",
15
+ "@provablehq/aleo-wallet-standard": "0.3.0-alpha.0",
16
+ "@provablehq/aleo-wallet-adaptor-core": "0.3.0-alpha.0"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/ProvableHQ/aleo-dev-toolkit.git",
21
+ "directory": "packages/aleo-wallet-adaptor/wallets/shield"
22
+ },
23
+ "homepage": "https://provable.com/",
24
+ "keywords": [
25
+ "aleo",
26
+ "wallet",
27
+ "adapter",
28
+ "prove",
29
+ "alpha"
30
+ ],
31
+ "author": "Provable Labs",
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "devDependencies": {
36
+ "rimraf": "^5.0.5",
37
+ "tsup": "^7.0.0",
38
+ "typescript": "^5.0.0"
39
+ },
40
+ "scripts": {
41
+ "build": "tsup",
42
+ "clean": "rimraf dist",
43
+ "dev": "tsup --watch"
44
+ }
45
+ }