@alephium/ledger-app 0.5.1 → 0.6.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/merkle-tree/proofs.json +1 -0
- package/dist/merkle-tree/token.json +1107 -0
- package/dist/src/ledger-app.d.ts +2 -3
- package/dist/src/ledger-app.js +35 -22
- package/dist/src/merkle.d.ts +9 -0
- package/dist/src/merkle.js +59 -0
- package/dist/src/serde.d.ts +3 -1
- package/dist/src/serde.js +19 -17
- package/dist/src/tx-encoder.d.ts +11 -0
- package/dist/src/tx-encoder.js +82 -0
- package/dist/src/types.d.ts +1 -0
- package/dist/src/types.js +3 -1
- package/dist/test/merkle.test.d.ts +1 -0
- package/dist/test/merkle.test.js +18 -0
- package/dist/test/tx-encoder.test.d.ts +1 -0
- package/dist/test/tx-encoder.test.js +73 -0
- package/dist/test/utils.d.ts +6 -3
- package/dist/test/utils.js +13 -4
- package/dist/test/wallet.test.js +113 -72
- package/merkle-tree/proofs.json +1 -0
- package/merkle-tree/token.json +1107 -0
- package/package.json +8 -6
- package/src/index.ts +1 -1
- package/src/ledger-app.ts +39 -31
- package/src/merkle.ts +63 -0
- package/src/serde.ts +19 -18
- package/src/tx-encoder.ts +90 -0
- package/src/types.ts +3 -1
- package/test/merkle.test.ts +20 -0
- package/test/tx-encoder.test.ts +80 -0
- package/test/utils.ts +9 -0
- package/test/wallet.test.ts +102 -39
package/test/wallet.test.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import AlephiumApp,
|
|
1
|
+
import { AlephiumApp, GROUP_NUM } from '../src/ledger-app'
|
|
2
2
|
import { ALPH_TOKEN_ID, Address, DUST_AMOUNT, NodeProvider, ONE_ALPH, binToHex, codec, groupOfAddress, node, sleep, transactionVerifySignature, waitForTxConfirmation, web3 } from '@alephium/web3'
|
|
3
3
|
import { getSigner, mintToken, transfer } from '@alephium/web3-test'
|
|
4
4
|
import { PrivateKeyWallet } from '@alephium/web3-wallet'
|
|
5
5
|
import blake from 'blakejs'
|
|
6
|
-
import { approveAddress, approveHash, approveTx, createTransport, enableBlindSigning, getRandomInt, needToAutoApprove, OutputType, skipBlindSigningWarning, staxFlexApproveOnce } from './utils'
|
|
6
|
+
import { approveAddress, approveHash, approveTx, createTransport, enableBlindSigning, getRandomInt, isNanos, needToAutoApprove, OutputType, skipBlindSigningWarning, staxFlexApproveOnce } from './utils'
|
|
7
7
|
import { TokenMetadata } from '../src/types'
|
|
8
|
-
import {
|
|
8
|
+
import { randomBytes } from 'crypto'
|
|
9
|
+
import { merkleTokens, tokenMerkleProofs } from '../src/merkle'
|
|
9
10
|
|
|
10
11
|
describe('ledger wallet', () => {
|
|
11
12
|
const nodeProvider = new NodeProvider("http://127.0.0.1:22973")
|
|
@@ -272,37 +273,87 @@ describe('ledger wallet', () => {
|
|
|
272
273
|
return { tokens, destinations }
|
|
273
274
|
}
|
|
274
275
|
|
|
275
|
-
it('should transfer
|
|
276
|
+
it('should transfer tokens with proof', async () => {
|
|
276
277
|
const transport = await createTransport()
|
|
277
278
|
const app = new AlephiumApp(transport)
|
|
278
279
|
const [testAccount] = await app.getAccount(path)
|
|
279
280
|
await transferToAddress(testAccount.address)
|
|
281
|
+
const newAccount = await getSigner()
|
|
282
|
+
|
|
283
|
+
const selectedTokens = [
|
|
284
|
+
merkleTokens[5], // decimals is 0
|
|
285
|
+
merkleTokens[6], // decimals is 18
|
|
286
|
+
merkleTokens[8], // decimals is 9
|
|
287
|
+
merkleTokens[11], // decimals is 8
|
|
288
|
+
merkleTokens[13], // decimals is 6
|
|
289
|
+
]
|
|
290
|
+
const outputs: node.FixedAssetOutput[] = selectedTokens.map((token, index) => {
|
|
291
|
+
return {
|
|
292
|
+
hint:0,
|
|
293
|
+
key: '',
|
|
294
|
+
attoAlphAmount: DUST_AMOUNT.toString(),
|
|
295
|
+
address: newAccount.address,
|
|
296
|
+
tokens: [{ id: token.tokenId, amount: (BigInt(index + 1) * ONE_ALPH).toString() }],
|
|
297
|
+
lockTime: 0,
|
|
298
|
+
message: ''
|
|
299
|
+
}
|
|
300
|
+
})
|
|
301
|
+
const unsignedTx: node.UnsignedTx = {
|
|
302
|
+
txId: '',
|
|
303
|
+
version: 0,
|
|
304
|
+
networkId: 4,
|
|
305
|
+
gasAmount: 100000,
|
|
306
|
+
gasPrice: (ONE_ALPH / 10000000n).toString(),
|
|
307
|
+
inputs: [{ outputRef: { hint: 0, key: binToHex(randomBytes(32)) }, unlockScript: '00' + testAccount.publicKey }],
|
|
308
|
+
fixedOutputs: outputs
|
|
309
|
+
}
|
|
310
|
+
const encodedUnsignedTx = codec.unsignedTxCodec.encodeApiUnsignedTx(unsignedTx)
|
|
280
311
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
312
|
+
if (isNanos()) {
|
|
313
|
+
approveTx([OutputType.Nanos11, OutputType.Nanos10, OutputType.Nanos10, OutputType.Nanos10, OutputType.Nanos11])
|
|
314
|
+
} else {
|
|
315
|
+
approveTx(Array(5).fill(OutputType.BaseAndToken))
|
|
316
|
+
}
|
|
317
|
+
const signature = await app.signUnsignedTx(path, Buffer.from(encodedUnsignedTx))
|
|
318
|
+
const txId = blake.blake2b(encodedUnsignedTx, undefined, 32)
|
|
319
|
+
expect(transactionVerifySignature(binToHex(txId), testAccount.publicKey, signature)).toBe(true)
|
|
285
320
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
fromPublicKey: testAccount.publicKey,
|
|
289
|
-
destinations: destinations
|
|
290
|
-
})
|
|
321
|
+
await app.close()
|
|
322
|
+
}, 120000)
|
|
291
323
|
|
|
292
|
-
|
|
293
|
-
const
|
|
294
|
-
|
|
324
|
+
it('should reject tx if the token proof is invalid', async () => {
|
|
325
|
+
const transport = await createTransport()
|
|
326
|
+
const app = new AlephiumApp(transport)
|
|
327
|
+
const [testAccount] = await app.getAccount(path)
|
|
328
|
+
await transferToAddress(testAccount.address)
|
|
295
329
|
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
330
|
+
const toAddress = '1BmVCLrjttchZMW7i6df7mTdCKzHpy38bgDbVL1GqV6P7'
|
|
331
|
+
const selectedToken = merkleTokens[6] // the decimals is 18
|
|
332
|
+
const output: node.FixedAssetOutput = {
|
|
333
|
+
hint: 0,
|
|
334
|
+
key: '',
|
|
335
|
+
attoAlphAmount: DUST_AMOUNT.toString(),
|
|
336
|
+
address: toAddress,
|
|
337
|
+
tokens: [{ id: selectedToken.tokenId, amount: ONE_ALPH.toString() }],
|
|
338
|
+
lockTime: 0,
|
|
339
|
+
message: ''
|
|
340
|
+
}
|
|
341
|
+
const unsignedTx: node.UnsignedTx = {
|
|
342
|
+
txId: '',
|
|
343
|
+
version: 0,
|
|
344
|
+
networkId: 4,
|
|
345
|
+
gasAmount: 100000,
|
|
346
|
+
gasPrice: (ONE_ALPH / 10000000n).toString(),
|
|
347
|
+
inputs: [{ outputRef: { hint: 0, key: binToHex(randomBytes(32)) }, unlockScript: '00' + testAccount.publicKey }],
|
|
348
|
+
fixedOutputs: [output]
|
|
349
|
+
}
|
|
350
|
+
const encodedUnsignedTx = codec.unsignedTxCodec.encodeApiUnsignedTx(unsignedTx)
|
|
351
|
+
|
|
352
|
+
const originalProof = tokenMerkleProofs[selectedToken.tokenId]
|
|
353
|
+
const invalidProof = originalProof.slice(0, originalProof.length - 64)
|
|
354
|
+
tokenMerkleProofs[selectedToken.tokenId] = invalidProof
|
|
355
|
+
await expect(app.signUnsignedTx(path, Buffer.from(encodedUnsignedTx))).rejects.toThrow()
|
|
356
|
+
tokenMerkleProofs[selectedToken.tokenId] = originalProof
|
|
306
357
|
|
|
307
358
|
await app.close()
|
|
308
359
|
}, 120000)
|
|
@@ -313,19 +364,31 @@ describe('ledger wallet', () => {
|
|
|
313
364
|
const [testAccount] = await app.getAccount(path)
|
|
314
365
|
await transferToAddress(testAccount.address)
|
|
315
366
|
|
|
316
|
-
const toAddress = '1BmVCLrjttchZMW7i6df7mTdCKzHpy38bgDbVL1GqV6P7'
|
|
317
|
-
const
|
|
318
|
-
const
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
367
|
+
const toAddress = '1BmVCLrjttchZMW7i6df7mTdCKzHpy38bgDbVL1GqV6P7'
|
|
368
|
+
const tokenIndex = 6
|
|
369
|
+
const selectedToken = merkleTokens[tokenIndex]
|
|
370
|
+
const output: node.FixedAssetOutput = {
|
|
371
|
+
hint: 0,
|
|
372
|
+
key: '',
|
|
373
|
+
attoAlphAmount: DUST_AMOUNT.toString(),
|
|
374
|
+
address: toAddress,
|
|
375
|
+
tokens: [{ id: selectedToken.tokenId, amount: ONE_ALPH.toString() }],
|
|
376
|
+
lockTime: 0,
|
|
377
|
+
message: ''
|
|
378
|
+
}
|
|
379
|
+
const unsignedTx: node.UnsignedTx = {
|
|
380
|
+
txId: '',
|
|
381
|
+
version: 0,
|
|
382
|
+
networkId: 4,
|
|
383
|
+
gasAmount: 100000,
|
|
384
|
+
gasPrice: (ONE_ALPH / 10000000n).toString(),
|
|
385
|
+
inputs: [{ outputRef: { hint: 0, key: binToHex(randomBytes(32)) }, unlockScript: '00' + testAccount.publicKey }],
|
|
386
|
+
fixedOutputs: [output]
|
|
387
|
+
}
|
|
388
|
+
const encodedUnsignedTx = codec.unsignedTxCodec.encodeApiUnsignedTx(unsignedTx)
|
|
389
|
+
merkleTokens[tokenIndex] = { ...selectedToken, version: 1 }
|
|
390
|
+
await expect(app.signUnsignedTx(path, Buffer.from(encodedUnsignedTx))).rejects.toThrow()
|
|
391
|
+
merkleTokens[tokenIndex] = selectedToken
|
|
329
392
|
|
|
330
393
|
await app.close()
|
|
331
394
|
}, 120000)
|