@0xsequence/wallet-wdk 0.0.0-20250520201059

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 (173) hide show
  1. package/.env.test +3 -0
  2. package/.turbo/turbo-build.log +5 -0
  3. package/CHANGELOG.md +11 -0
  4. package/LICENSE +202 -0
  5. package/dist/dbs/auth-commitments.d.ts +17 -0
  6. package/dist/dbs/auth-commitments.d.ts.map +1 -0
  7. package/dist/dbs/auth-commitments.js +13 -0
  8. package/dist/dbs/auth-keys.d.ts +19 -0
  9. package/dist/dbs/auth-keys.d.ts.map +1 -0
  10. package/dist/dbs/auth-keys.js +67 -0
  11. package/dist/dbs/generic.d.ts +33 -0
  12. package/dist/dbs/generic.d.ts.map +1 -0
  13. package/dist/dbs/generic.js +170 -0
  14. package/dist/dbs/index.d.ts +12 -0
  15. package/dist/dbs/index.d.ts.map +1 -0
  16. package/dist/dbs/index.js +8 -0
  17. package/dist/dbs/messages.d.ts +6 -0
  18. package/dist/dbs/messages.d.ts.map +1 -0
  19. package/dist/dbs/messages.js +13 -0
  20. package/dist/dbs/recovery.d.ts +6 -0
  21. package/dist/dbs/recovery.d.ts.map +1 -0
  22. package/dist/dbs/recovery.js +13 -0
  23. package/dist/dbs/signatures.d.ts +6 -0
  24. package/dist/dbs/signatures.d.ts.map +1 -0
  25. package/dist/dbs/signatures.js +13 -0
  26. package/dist/dbs/transactions.d.ts +6 -0
  27. package/dist/dbs/transactions.d.ts.map +1 -0
  28. package/dist/dbs/transactions.js +13 -0
  29. package/dist/dbs/wallets.d.ts +6 -0
  30. package/dist/dbs/wallets.d.ts.map +1 -0
  31. package/dist/dbs/wallets.js +13 -0
  32. package/dist/identity/signer.d.ts +17 -0
  33. package/dist/identity/signer.d.ts.map +1 -0
  34. package/dist/identity/signer.js +58 -0
  35. package/dist/index.d.ts +3 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +2 -0
  38. package/dist/sequence/cron.d.ts +19 -0
  39. package/dist/sequence/cron.d.ts.map +1 -0
  40. package/dist/sequence/cron.js +118 -0
  41. package/dist/sequence/devices.d.ts +14 -0
  42. package/dist/sequence/devices.d.ts.map +1 -0
  43. package/dist/sequence/devices.js +43 -0
  44. package/dist/sequence/handlers/authcode-pkce.d.ts +14 -0
  45. package/dist/sequence/handlers/authcode-pkce.d.ts.map +1 -0
  46. package/dist/sequence/handlers/authcode-pkce.js +48 -0
  47. package/dist/sequence/handlers/authcode.d.ts +25 -0
  48. package/dist/sequence/handlers/authcode.d.ts.map +1 -0
  49. package/dist/sequence/handlers/authcode.js +91 -0
  50. package/dist/sequence/handlers/devices.d.ts +14 -0
  51. package/dist/sequence/handlers/devices.d.ts.map +1 -0
  52. package/dist/sequence/handlers/devices.js +39 -0
  53. package/dist/sequence/handlers/handler.d.ts +8 -0
  54. package/dist/sequence/handlers/handler.d.ts.map +1 -0
  55. package/dist/sequence/handlers/handler.js +1 -0
  56. package/dist/sequence/handlers/identity.d.ts +21 -0
  57. package/dist/sequence/handlers/identity.d.ts.map +1 -0
  58. package/dist/sequence/handlers/identity.js +86 -0
  59. package/dist/sequence/handlers/index.d.ts +7 -0
  60. package/dist/sequence/handlers/index.d.ts.map +1 -0
  61. package/dist/sequence/handlers/index.js +5 -0
  62. package/dist/sequence/handlers/mnemonic.d.ts +19 -0
  63. package/dist/sequence/handlers/mnemonic.d.ts.map +1 -0
  64. package/dist/sequence/handlers/mnemonic.js +67 -0
  65. package/dist/sequence/handlers/otp.d.ts +20 -0
  66. package/dist/sequence/handlers/otp.d.ts.map +1 -0
  67. package/dist/sequence/handlers/otp.js +83 -0
  68. package/dist/sequence/handlers/passkeys.d.ts +17 -0
  69. package/dist/sequence/handlers/passkeys.d.ts.map +1 -0
  70. package/dist/sequence/handlers/passkeys.js +63 -0
  71. package/dist/sequence/handlers/recovery.d.ts +15 -0
  72. package/dist/sequence/handlers/recovery.d.ts.map +1 -0
  73. package/dist/sequence/handlers/recovery.js +72 -0
  74. package/dist/sequence/index.d.ts +12 -0
  75. package/dist/sequence/index.d.ts.map +1 -0
  76. package/dist/sequence/index.js +9 -0
  77. package/dist/sequence/logger.d.ts +7 -0
  78. package/dist/sequence/logger.d.ts.map +1 -0
  79. package/dist/sequence/logger.js +11 -0
  80. package/dist/sequence/manager.d.ts +287 -0
  81. package/dist/sequence/manager.d.ts.map +1 -0
  82. package/dist/sequence/manager.js +356 -0
  83. package/dist/sequence/messages.d.ts +18 -0
  84. package/dist/sequence/messages.d.ts.map +1 -0
  85. package/dist/sequence/messages.js +115 -0
  86. package/dist/sequence/recovery.d.ts +30 -0
  87. package/dist/sequence/recovery.d.ts.map +1 -0
  88. package/dist/sequence/recovery.js +314 -0
  89. package/dist/sequence/sessions.d.ts +26 -0
  90. package/dist/sequence/sessions.d.ts.map +1 -0
  91. package/dist/sequence/sessions.js +169 -0
  92. package/dist/sequence/signatures.d.ts +21 -0
  93. package/dist/sequence/signatures.d.ts.map +1 -0
  94. package/dist/sequence/signatures.js +192 -0
  95. package/dist/sequence/signers.d.ts +14 -0
  96. package/dist/sequence/signers.d.ts.map +1 -0
  97. package/dist/sequence/signers.js +74 -0
  98. package/dist/sequence/transactions.d.ts +26 -0
  99. package/dist/sequence/transactions.d.ts.map +1 -0
  100. package/dist/sequence/transactions.js +201 -0
  101. package/dist/sequence/types/index.d.ts +9 -0
  102. package/dist/sequence/types/index.d.ts.map +1 -0
  103. package/dist/sequence/types/index.js +2 -0
  104. package/dist/sequence/types/message-request.d.ts +23 -0
  105. package/dist/sequence/types/message-request.d.ts.map +1 -0
  106. package/dist/sequence/types/message-request.js +1 -0
  107. package/dist/sequence/types/recovery.d.ts +15 -0
  108. package/dist/sequence/types/recovery.d.ts.map +1 -0
  109. package/dist/sequence/types/recovery.js +1 -0
  110. package/dist/sequence/types/signature-request.d.ts +76 -0
  111. package/dist/sequence/types/signature-request.d.ts.map +1 -0
  112. package/dist/sequence/types/signature-request.js +11 -0
  113. package/dist/sequence/types/signer.d.ts +28 -0
  114. package/dist/sequence/types/signer.d.ts.map +1 -0
  115. package/dist/sequence/types/signer.js +10 -0
  116. package/dist/sequence/types/transaction-request.d.ts +41 -0
  117. package/dist/sequence/types/transaction-request.d.ts.map +1 -0
  118. package/dist/sequence/types/transaction-request.js +1 -0
  119. package/dist/sequence/types/wallet.d.ts +21 -0
  120. package/dist/sequence/types/wallet.d.ts.map +1 -0
  121. package/dist/sequence/types/wallet.js +1 -0
  122. package/dist/sequence/wallets.d.ts +121 -0
  123. package/dist/sequence/wallets.d.ts.map +1 -0
  124. package/dist/sequence/wallets.js +632 -0
  125. package/package.json +40 -0
  126. package/src/dbs/auth-commitments.ts +26 -0
  127. package/src/dbs/auth-keys.ts +85 -0
  128. package/src/dbs/generic.ts +194 -0
  129. package/src/dbs/index.ts +13 -0
  130. package/src/dbs/messages.ts +16 -0
  131. package/src/dbs/recovery.ts +15 -0
  132. package/src/dbs/signatures.ts +15 -0
  133. package/src/dbs/transactions.ts +16 -0
  134. package/src/dbs/wallets.ts +16 -0
  135. package/src/identity/signer.ts +78 -0
  136. package/src/index.ts +2 -0
  137. package/src/sequence/cron.ts +134 -0
  138. package/src/sequence/devices.ts +53 -0
  139. package/src/sequence/handlers/authcode-pkce.ts +70 -0
  140. package/src/sequence/handlers/authcode.ts +116 -0
  141. package/src/sequence/handlers/devices.ts +53 -0
  142. package/src/sequence/handlers/handler.ts +14 -0
  143. package/src/sequence/handlers/identity.ts +101 -0
  144. package/src/sequence/handlers/index.ts +6 -0
  145. package/src/sequence/handlers/mnemonic.ts +88 -0
  146. package/src/sequence/handlers/otp.ts +107 -0
  147. package/src/sequence/handlers/passkeys.ts +84 -0
  148. package/src/sequence/handlers/recovery.ts +88 -0
  149. package/src/sequence/index.ts +25 -0
  150. package/src/sequence/logger.ts +11 -0
  151. package/src/sequence/manager.ts +634 -0
  152. package/src/sequence/messages.ts +146 -0
  153. package/src/sequence/recovery.ts +429 -0
  154. package/src/sequence/sessions.ts +238 -0
  155. package/src/sequence/signatures.ts +263 -0
  156. package/src/sequence/signers.ts +88 -0
  157. package/src/sequence/transactions.ts +281 -0
  158. package/src/sequence/types/index.ts +27 -0
  159. package/src/sequence/types/message-request.ts +26 -0
  160. package/src/sequence/types/recovery.ts +15 -0
  161. package/src/sequence/types/signature-request.ts +89 -0
  162. package/src/sequence/types/signer.ts +32 -0
  163. package/src/sequence/types/transaction-request.ts +47 -0
  164. package/src/sequence/types/wallet.ts +24 -0
  165. package/src/sequence/wallets.ts +853 -0
  166. package/test/constants.ts +62 -0
  167. package/test/recovery.test.ts +211 -0
  168. package/test/sessions.test.ts +324 -0
  169. package/test/setup.ts +63 -0
  170. package/test/transactions.test.ts +464 -0
  171. package/test/wallets.test.ts +381 -0
  172. package/tsconfig.json +10 -0
  173. package/vitest.config.ts +11 -0
@@ -0,0 +1,464 @@
1
+ import { afterEach, describe, expect, it, vi } from 'vitest'
2
+ import { Manager, SignerActionable, Transaction, TransactionDefined, TransactionRelayed } from '../src/sequence'
3
+ import { Address, Hex, Mnemonic, Provider, RpcTransport } from 'ox'
4
+ import { LOCAL_RPC_URL, newManager } from './constants'
5
+ import { Payload } from '@0xsequence/wallet-primitives'
6
+
7
+ describe('Transactions', () => {
8
+ let manager: Manager | undefined
9
+
10
+ afterEach(async () => {
11
+ await manager?.stop()
12
+ })
13
+
14
+ it('Should send a transaction from a new wallet', async () => {
15
+ manager = newManager()
16
+ const wallet = await manager.signUp({
17
+ mnemonic: Mnemonic.random(Mnemonic.english),
18
+ kind: 'mnemonic',
19
+ noGuard: true,
20
+ })
21
+ expect(wallet).toBeDefined()
22
+ await expect(manager.hasWallet(wallet!)).resolves.toBeTruthy()
23
+
24
+ const provider = Provider.from(RpcTransport.fromHttp(LOCAL_RPC_URL))
25
+ await provider.request({
26
+ method: 'anvil_setBalance',
27
+ params: [wallet!, '0xa'],
28
+ })
29
+
30
+ const recipient = Address.from(Hex.random(20))
31
+ const txId = await manager.requestTransaction(wallet!, 42161n, [
32
+ {
33
+ to: recipient,
34
+ value: 9n,
35
+ },
36
+ ])
37
+
38
+ expect(txId).toBeDefined()
39
+ await manager.defineTransaction(txId!)
40
+
41
+ let tx = await manager.getTransaction(txId!)
42
+ expect(tx).toBeDefined()
43
+ expect(tx.status).toBe('defined')
44
+
45
+ if (tx.status !== 'defined') {
46
+ throw new Error('Transaction status is not defined')
47
+ }
48
+
49
+ expect(tx.relayerOptions.length).toBe(1)
50
+ expect(tx.relayerOptions[0].id).toBeDefined()
51
+
52
+ const sigId = await manager.selectTransactionRelayer(txId!, tx.relayerOptions[0].id)
53
+ expect(sigId).toBeDefined()
54
+
55
+ tx = await manager.getTransaction(txId!)
56
+ expect(tx).toBeDefined()
57
+ expect(tx.status).toBe('formed')
58
+
59
+ // Sign using the device signer
60
+ const sigRequest = await manager.getSignatureRequest(sigId!)
61
+ expect(sigRequest).toBeDefined()
62
+ expect(sigRequest.status).toBe('pending')
63
+ expect(sigRequest.signers.filter((s) => s.status === 'ready').length).toBe(1)
64
+
65
+ const deviceSigner = sigRequest.signers.find((s) => s.status === 'ready')!
66
+ expect(deviceSigner).toBeDefined()
67
+
68
+ await deviceSigner.handle()
69
+
70
+ await manager.relayTransaction(txId)
71
+
72
+ // Check the balance of the wallet
73
+ const balance = await provider.request({
74
+ method: 'eth_getBalance',
75
+ params: [wallet!, 'latest'],
76
+ })
77
+ expect(balance).toBeDefined()
78
+ expect(balance).toBe('0x1')
79
+
80
+ // Check the balance of the recipient
81
+ const recipientBalance = await provider.request({
82
+ method: 'eth_getBalance',
83
+ params: [recipient, 'latest'],
84
+ })
85
+ expect(recipientBalance).toBeDefined()
86
+ expect(recipientBalance).toBe('0x9')
87
+ })
88
+
89
+ it('Should send a transaction after logging in to a wallet', async () => {
90
+ manager = newManager()
91
+ const mnemonic = Mnemonic.random(Mnemonic.english)
92
+ const wallet = await manager.signUp({
93
+ mnemonic,
94
+ kind: 'mnemonic',
95
+ noGuard: true,
96
+ })
97
+ expect(wallet).toBeDefined()
98
+ await expect(manager.hasWallet(wallet!)).resolves.toBeTruthy()
99
+
100
+ // Logout without removing the device
101
+ await manager.logout(wallet!, { skipRemoveDevice: true })
102
+
103
+ // Login to the same wallet
104
+ const loginId = await manager.login({ wallet: wallet! })
105
+ expect(loginId).toBeDefined()
106
+
107
+ // Register the UI for the mnemonic signer
108
+ let signRequests = 0
109
+ let unregisteredUI = manager.registerMnemonicUI(async (respond) => {
110
+ signRequests++
111
+ await respond(mnemonic)
112
+ })
113
+
114
+ const loginRequest = await manager.getSignatureRequest(loginId!)
115
+ expect(loginRequest).toBeDefined()
116
+ expect(loginRequest.action).toBe('login')
117
+
118
+ const mnemonicSigner = loginRequest.signers.find((signer) => signer.handler?.kind === 'login-mnemonic')
119
+ expect(mnemonicSigner).toBeDefined()
120
+ expect(mnemonicSigner?.status).toBe('actionable')
121
+
122
+ signRequests = 0
123
+ unregisteredUI = manager.registerMnemonicUI(async (respond) => {
124
+ signRequests++
125
+ await respond(mnemonic)
126
+ })
127
+
128
+ await (mnemonicSigner as SignerActionable).handle()
129
+ expect(signRequests).toBe(1)
130
+ unregisteredUI()
131
+
132
+ await manager.completeLogin(loginId!)
133
+ expect((await manager.getSignatureRequest(loginId!))?.status).toBe('completed')
134
+
135
+ // Set balance for the wallet
136
+ const provider = Provider.from(RpcTransport.fromHttp(LOCAL_RPC_URL))
137
+ await provider.request({
138
+ method: 'anvil_setBalance',
139
+ params: [wallet!, '0xa'],
140
+ })
141
+
142
+ // Send a transaction
143
+ const recipient = Address.from(Hex.random(20))
144
+ const txId = await manager.requestTransaction(wallet!, 42161n, [
145
+ {
146
+ to: recipient,
147
+ value: 9n,
148
+ },
149
+ ])
150
+
151
+ expect(txId).toBeDefined()
152
+ await manager.defineTransaction(txId!)
153
+
154
+ let tx = await manager.getTransaction(txId!)
155
+ expect(tx).toBeDefined()
156
+ expect(tx.status).toBe('defined')
157
+
158
+ if (tx.status !== 'defined') {
159
+ throw new Error('Transaction status is not defined')
160
+ }
161
+
162
+ expect(tx.relayerOptions.length).toBe(1)
163
+ expect(tx.relayerOptions[0].id).toBeDefined()
164
+
165
+ const sigId = await manager.selectTransactionRelayer(txId!, tx.relayerOptions[0].id)
166
+ expect(sigId).toBeDefined()
167
+
168
+ tx = await manager.getTransaction(txId!)
169
+ expect(tx).toBeDefined()
170
+ expect(tx.status).toBe('formed')
171
+
172
+ // Sign using the device signer
173
+ const sigRequest = await manager.getSignatureRequest(sigId!)
174
+ expect(sigRequest).toBeDefined()
175
+ expect(sigRequest.status).toBe('pending')
176
+ expect(sigRequest.signers.filter((s) => s.status === 'ready').length).toBe(1)
177
+
178
+ const deviceSigner = sigRequest.signers.find((s) => s.status === 'ready')!
179
+ expect(deviceSigner).toBeDefined()
180
+
181
+ await deviceSigner.handle()
182
+
183
+ await manager.relayTransaction(txId)
184
+
185
+ // Check the balance of the wallet
186
+ const balance = await provider.request({
187
+ method: 'eth_getBalance',
188
+ params: [wallet!, 'latest'],
189
+ })
190
+ expect(balance).toBeDefined()
191
+ expect(balance).toBe('0x1')
192
+
193
+ // Check the balance of the recipient
194
+ const recipientBalance = await provider.request({
195
+ method: 'eth_getBalance',
196
+ params: [recipient, 'latest'],
197
+ })
198
+ expect(recipientBalance).toBeDefined()
199
+ expect(recipientBalance).toBe('0x9')
200
+ })
201
+
202
+ it('Should call onTransactionsUpdate when a new transaction is requested', async () => {
203
+ manager = newManager()
204
+ const wallet = await manager.signUp({
205
+ mnemonic: Mnemonic.random(Mnemonic.english),
206
+ kind: 'mnemonic',
207
+ noGuard: true,
208
+ })
209
+ expect(wallet).toBeDefined()
210
+ await expect(manager.hasWallet(wallet!)).resolves.toBeTruthy()
211
+
212
+ let transactions: Transaction[] = []
213
+ let calledTimes = 0
214
+ manager.onTransactionsUpdate((txs) => {
215
+ transactions = txs
216
+ calledTimes++
217
+ })
218
+
219
+ const to = Address.from(Hex.random(20))
220
+ const txId = await manager.requestTransaction(wallet!, 42161n, [
221
+ {
222
+ to,
223
+ value: 9n,
224
+ },
225
+ ])
226
+
227
+ expect(txId).toBeDefined()
228
+ await manager.defineTransaction(txId!)
229
+
230
+ expect(calledTimes).toBe(1)
231
+ expect(transactions.length).toBe(1)
232
+ expect(transactions[0].status).toBe('requested')
233
+ expect(transactions[0].wallet).toBe(wallet!)
234
+ expect(transactions[0].requests.length).toBe(1)
235
+ expect(transactions[0].requests[0].to).toEqual(to)
236
+ expect(transactions[0].requests[0].value).toEqual(9n)
237
+ })
238
+
239
+ it('Should call onTransactionUpdate when a transaction is defined, relayer selected and relayed', async () => {
240
+ manager = newManager()
241
+ const wallet = await manager.signUp({
242
+ mnemonic: Mnemonic.random(Mnemonic.english),
243
+ kind: 'mnemonic',
244
+ noGuard: true,
245
+ })
246
+ expect(wallet).toBeDefined()
247
+ await expect(manager.hasWallet(wallet!)).resolves.toBeTruthy()
248
+
249
+ const to = Address.from(Hex.random(20))
250
+ const txId = await manager.requestTransaction(wallet!, 42161n, [
251
+ {
252
+ to,
253
+ },
254
+ ])
255
+
256
+ let tx: Transaction | undefined
257
+ let calledTimes = 0
258
+ manager.onTransactionUpdate(txId!, (t) => {
259
+ tx = t
260
+ calledTimes++
261
+ })
262
+
263
+ expect(txId).toBeDefined()
264
+ await manager.defineTransaction(txId!)
265
+
266
+ while (calledTimes < 1) {
267
+ await new Promise((resolve) => setTimeout(resolve, 1))
268
+ }
269
+
270
+ expect(calledTimes).toBe(1)
271
+ expect(tx).toBeDefined()
272
+ expect(tx!.status).toBe('defined')
273
+ expect(tx!.wallet).toBe(wallet!)
274
+ expect(tx!.requests.length).toBe(1)
275
+ expect(tx!.requests[0].to).toEqual(to)
276
+ expect(tx!.requests[0].value).toBeUndefined()
277
+ expect(tx!.requests[0].gasLimit).toBeUndefined()
278
+ expect(tx!.requests[0].data).toBeUndefined()
279
+
280
+ const sigId = await manager.selectTransactionRelayer(txId!, (tx as TransactionDefined).relayerOptions[0].id)
281
+ expect(sigId).toBeDefined()
282
+
283
+ while (calledTimes < 2) {
284
+ await new Promise((resolve) => setTimeout(resolve, 1))
285
+ }
286
+
287
+ expect(calledTimes).toBe(2)
288
+ expect(tx!.status).toBe('formed')
289
+
290
+ // Sign the transaction
291
+ const sigRequest = await manager.getSignatureRequest(sigId!)
292
+ expect(sigRequest).toBeDefined()
293
+ expect(sigRequest.status).toBe('pending')
294
+ expect(sigRequest.signers.filter((s) => s.status === 'ready').length).toBe(1)
295
+
296
+ const deviceSigner = sigRequest.signers.find((s) => s.status === 'ready')!
297
+ await deviceSigner.handle()
298
+
299
+ await manager.relayTransaction(txId!)
300
+ while (calledTimes < 3) {
301
+ await new Promise((resolve) => setTimeout(resolve, 1))
302
+ }
303
+
304
+ expect(calledTimes).toBe(3)
305
+ expect(tx!.status).toBe('relayed')
306
+ expect((tx! as TransactionRelayed).opHash).toBeDefined()
307
+ })
308
+
309
+ it('Should delete an existing transaction before it is defined', async () => {
310
+ manager = newManager()
311
+ const wallet = await manager.signUp({
312
+ mnemonic: Mnemonic.random(Mnemonic.english),
313
+ kind: 'mnemonic',
314
+ noGuard: true,
315
+ })
316
+
317
+ const to = Address.from(Hex.random(20))
318
+ const txId = await manager.requestTransaction(wallet!, 42161n, [
319
+ {
320
+ to,
321
+ },
322
+ ])
323
+
324
+ expect(txId).toBeDefined()
325
+
326
+ await manager.deleteTransaction(txId!)
327
+ await expect(manager.getTransaction(txId!)).rejects.toThrow()
328
+ })
329
+
330
+ it('Should delete an existing transaction before the relayer is selected', async () => {
331
+ manager = newManager()
332
+ const wallet = await manager.signUp({
333
+ mnemonic: Mnemonic.random(Mnemonic.english),
334
+ kind: 'mnemonic',
335
+ noGuard: true,
336
+ })
337
+
338
+ const to = Address.from(Hex.random(20))
339
+ const txId = await manager.requestTransaction(wallet!, 42161n, [
340
+ {
341
+ to,
342
+ },
343
+ ])
344
+
345
+ expect(txId).toBeDefined()
346
+
347
+ await manager.defineTransaction(txId!)
348
+
349
+ await manager.deleteTransaction(txId!)
350
+ await expect(manager.getTransaction(txId!)).rejects.toThrow()
351
+ })
352
+
353
+ it('Should delete an existing transaction before it is relayed', async () => {
354
+ manager = newManager()
355
+ const wallet = await manager.signUp({
356
+ mnemonic: Mnemonic.random(Mnemonic.english),
357
+ kind: 'mnemonic',
358
+ noGuard: true,
359
+ })
360
+
361
+ const to = Address.from(Hex.random(20))
362
+ const txId = await manager.requestTransaction(wallet!, 42161n, [
363
+ {
364
+ to,
365
+ },
366
+ ])
367
+
368
+ expect(txId).toBeDefined()
369
+
370
+ await manager.defineTransaction(txId!)
371
+
372
+ const tx = await manager.getTransaction(txId!)
373
+ expect(tx).toBeDefined()
374
+ expect(tx!.status).toBe('defined')
375
+
376
+ const sigId = await manager.selectTransactionRelayer(txId!, (tx as TransactionDefined).relayerOptions[0].id)
377
+ expect(sigId).toBeDefined()
378
+
379
+ await manager.deleteTransaction(txId!)
380
+ await expect(manager.getTransaction(txId!)).rejects.toThrow()
381
+
382
+ // Signature request should be canceled
383
+ const sigRequest = await manager.getSignatureRequest(sigId!)
384
+ expect(sigRequest).toBeDefined()
385
+ expect(sigRequest.status).toBe('cancelled')
386
+ })
387
+
388
+ it('Should update the onchain configuration when a transaction is sent', async () => {
389
+ const manager = newManager()
390
+ const wallet = await manager.signUp({
391
+ mnemonic: Mnemonic.random(Mnemonic.english),
392
+ kind: 'mnemonic',
393
+ noGuard: true,
394
+ })
395
+
396
+ // Add a recovery signer, just to change the configuration
397
+ const rSigId = await manager.addRecoverySigner(wallet!, Address.from(Hex.random(20)))
398
+ expect(rSigId).toBeDefined()
399
+
400
+ // Sign using the device signer
401
+ const rSigRequest = await manager.getSignatureRequest(rSigId!)
402
+ expect(rSigRequest).toBeDefined()
403
+ expect(rSigRequest.status).toBe('pending')
404
+ expect(rSigRequest.signers.filter((s) => s.status === 'ready').length).toBe(1)
405
+
406
+ const rDeviceSigner = rSigRequest.signers.find((s) => s.status === 'ready')!
407
+ await rDeviceSigner.handle()
408
+
409
+ await expect(manager.isUpdatedOnchain(wallet!, 42161n)).resolves.toBeTruthy()
410
+
411
+ await manager.completeRecoveryUpdate(rSigId!)
412
+
413
+ // It should no longer be updated onchain
414
+ await expect(manager.isUpdatedOnchain(wallet!, 42161n)).resolves.toBeFalsy()
415
+
416
+ const randomAddress = Address.from(Hex.random(20))
417
+ const txId = await manager.requestTransaction(wallet!, 42161n, [
418
+ {
419
+ to: randomAddress,
420
+ },
421
+ ])
422
+
423
+ await manager.defineTransaction(txId!)
424
+
425
+ let tx = await manager.getTransaction(txId!)
426
+ expect(tx).toBeDefined()
427
+ expect(tx!.status).toBe('defined')
428
+
429
+ // The transaction should contain the one that we want to perform
430
+ // and a configuration update
431
+ expect((tx.envelope.payload as Payload.Calls).calls.length).toBe(2)
432
+
433
+ // The first call should be to the random address
434
+ // and the second one should be a call to self
435
+ const call1 = (tx.envelope.payload as Payload.Calls).calls[0]
436
+ const call2 = (tx.envelope.payload as Payload.Calls).calls[1]
437
+ expect(call1.to).toEqual(randomAddress)
438
+ expect(call2.to).toEqual(wallet)
439
+
440
+ const sigId = await manager.selectTransactionRelayer(txId!, (tx as TransactionDefined).relayerOptions[0].id)
441
+ expect(sigId).toBeDefined()
442
+
443
+ tx = await manager.getTransaction(txId!)
444
+ expect(tx).toBeDefined()
445
+ expect(tx!.status).toBe('formed')
446
+
447
+ // Sign using the device signer
448
+ const sigRequest = await manager.getSignatureRequest(sigId!)
449
+ expect(sigRequest).toBeDefined()
450
+ expect(sigRequest.status).toBe('pending')
451
+ expect(sigRequest.signers.filter((s) => s.status === 'ready').length).toBe(1)
452
+
453
+ const deviceSigner = sigRequest.signers.find((s) => s.status === 'ready')!
454
+ await deviceSigner.handle()
455
+
456
+ await manager.relayTransaction(txId!)
457
+
458
+ // wait 1 second
459
+ await new Promise((resolve) => setTimeout(resolve, 1000))
460
+
461
+ // The onchain configuration should be updated
462
+ await expect(manager.isUpdatedOnchain(wallet!, 42161n)).resolves.toBeTruthy()
463
+ })
464
+ })