ecash-lib 0.1.0-rc2 → 0.1.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 (91) hide show
  1. package/README.md +73 -15
  2. package/dist/ecc.d.ts +6 -2
  3. package/dist/ecc.d.ts.map +1 -1
  4. package/dist/ecc.js +9 -6
  5. package/dist/ecc.js.map +1 -1
  6. package/dist/ffi/ecash_lib_wasm_bg.wasm +0 -0
  7. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm +0 -0
  8. package/dist/ffi/ecash_lib_wasm_bg_browser.wasm.d.ts +16 -0
  9. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm +0 -0
  10. package/dist/ffi/ecash_lib_wasm_bg_nodejs.wasm.d.ts +16 -0
  11. package/dist/ffi/ecash_lib_wasm_browser.d.ts +90 -0
  12. package/dist/ffi/ecash_lib_wasm_browser.js +340 -0
  13. package/dist/ffi/ecash_lib_wasm_nodejs.d.ts +50 -0
  14. package/dist/ffi/ecash_lib_wasm_nodejs.js +265 -0
  15. package/dist/hash.d.ts +10 -4
  16. package/dist/hash.d.ts.map +1 -1
  17. package/dist/hash.js +20 -4
  18. package/dist/hash.js.map +1 -1
  19. package/dist/index.d.ts +1 -1
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +37 -21
  22. package/dist/index.js.map +1 -1
  23. package/dist/indexBrowser.d.ts +3 -0
  24. package/dist/indexBrowser.d.ts.map +1 -0
  25. package/dist/indexBrowser.js +22 -0
  26. package/dist/indexBrowser.js.map +1 -0
  27. package/dist/indexNodeJs.d.ts +3 -0
  28. package/dist/indexNodeJs.d.ts.map +1 -0
  29. package/dist/indexNodeJs.js +22 -0
  30. package/dist/indexNodeJs.js.map +1 -0
  31. package/dist/initBrowser.d.ts +3 -0
  32. package/dist/initBrowser.d.ts.map +1 -0
  33. package/dist/initBrowser.js +44 -0
  34. package/dist/initBrowser.js.map +1 -0
  35. package/dist/initNodeJs.d.ts +3 -0
  36. package/dist/initNodeJs.d.ts.map +1 -0
  37. package/dist/initNodeJs.js +43 -0
  38. package/dist/initNodeJs.js.map +1 -0
  39. package/dist/io/bytes.js +5 -1
  40. package/dist/io/bytes.js.map +1 -1
  41. package/dist/io/hex.js +11 -4
  42. package/dist/io/hex.js.map +1 -1
  43. package/dist/io/int.js +2 -1
  44. package/dist/io/int.js.map +1 -1
  45. package/dist/io/str.d.ts +2 -0
  46. package/dist/io/str.d.ts.map +1 -1
  47. package/dist/io/str.js +11 -1
  48. package/dist/io/str.js.map +1 -1
  49. package/dist/io/varsize.js +7 -2
  50. package/dist/io/varsize.js.map +1 -1
  51. package/dist/io/writer.js +2 -1
  52. package/dist/io/writer.js.map +1 -1
  53. package/dist/io/writerbytes.js +5 -1
  54. package/dist/io/writerbytes.js.map +1 -1
  55. package/dist/io/writerlength.js +5 -1
  56. package/dist/io/writerlength.js.map +1 -1
  57. package/dist/op.js +23 -16
  58. package/dist/op.js.map +1 -1
  59. package/dist/opcode.js +126 -121
  60. package/dist/opcode.js.map +1 -1
  61. package/dist/script.d.ts +1 -0
  62. package/dist/script.d.ts.map +1 -1
  63. package/dist/script.js +34 -25
  64. package/dist/script.js.map +1 -1
  65. package/dist/sigHashType.js +23 -19
  66. package/dist/sigHashType.js.map +1 -1
  67. package/dist/test/testRunner.d.ts +1 -1
  68. package/dist/test/testRunner.d.ts.map +1 -1
  69. package/dist/test/testRunner.js +51 -26
  70. package/dist/test/testRunner.js.map +1 -1
  71. package/dist/token/alp.js +43 -36
  72. package/dist/token/alp.js.map +1 -1
  73. package/dist/token/common.js +8 -5
  74. package/dist/token/common.js.map +1 -1
  75. package/dist/token/empp.js +13 -9
  76. package/dist/token/empp.js.map +1 -1
  77. package/dist/token/slp.js +61 -53
  78. package/dist/token/slp.js.map +1 -1
  79. package/dist/tx.d.ts +2 -0
  80. package/dist/tx.d.ts.map +1 -1
  81. package/dist/tx.js +39 -21
  82. package/dist/tx.js.map +1 -1
  83. package/dist/txBuilder.js +33 -25
  84. package/dist/txBuilder.js.map +1 -1
  85. package/dist/unsignedTx.js +34 -29
  86. package/dist/unsignedTx.js.map +1 -1
  87. package/package.json +3 -3
  88. package/tsconfig.json +1 -2
  89. package/tests/alp.test.ts +0 -383
  90. package/tests/slp.test.ts +0 -1124
  91. package/tests/txBuilder.test.ts +0 -562
package/tests/slp.test.ts DELETED
@@ -1,1124 +0,0 @@
1
- // Copyright (c) 2024 The Bitcoin developers
2
- // Distributed under the MIT software license, see the accompanying
3
- // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
-
5
- import { expect } from 'chai';
6
- import { ChronikClientNode } from 'chronik-client';
7
- import { EventEmitter, once } from 'node:events';
8
-
9
- import {
10
- ALL_BIP143,
11
- Ecc,
12
- OP_10,
13
- P2PKHSignatory,
14
- Script,
15
- TxBuilder,
16
- fromHex,
17
- initWasm,
18
- pushBytesOp,
19
- shaRmd160,
20
- toHex,
21
- } from '../src/index.js';
22
- import { TestRunner } from '../src/test/testRunner.js';
23
- import {
24
- SLP_FUNGIBLE,
25
- SLP_MINT_VAULT,
26
- SLP_NFT1_CHILD,
27
- SLP_NFT1_GROUP,
28
- slpBurn,
29
- slpGenesis,
30
- slpMint,
31
- slpMintVault,
32
- slpSend,
33
- } from '../src/token/slp.js';
34
-
35
- const NUM_COINS = 500;
36
- const COIN_VALUE = 100000;
37
-
38
- const SLP_TOKEN_TYPE_FUNGIBLE = {
39
- number: 1,
40
- protocol: 'SLP',
41
- type: 'SLP_TOKEN_TYPE_FUNGIBLE',
42
- };
43
-
44
- const SLP_TOKEN_TYPE_MINT_VAULT = {
45
- number: 2,
46
- protocol: 'SLP',
47
- type: 'SLP_TOKEN_TYPE_MINT_VAULT',
48
- };
49
-
50
- const SLP_TOKEN_TYPE_NFT1_GROUP = {
51
- number: 0x81,
52
- protocol: 'SLP',
53
- type: 'SLP_TOKEN_TYPE_NFT1_GROUP',
54
- };
55
-
56
- const SLP_TOKEN_TYPE_NFT1_CHILD = {
57
- number: 0x41,
58
- protocol: 'SLP',
59
- type: 'SLP_TOKEN_TYPE_NFT1_CHILD',
60
- };
61
-
62
- describe('SLP Integration Test', () => {
63
- let runner: TestRunner;
64
- let chronik: ChronikClientNode;
65
- let ecc: Ecc;
66
-
67
- before(async () => {
68
- runner = await TestRunner.setup();
69
- chronik = runner.chronik;
70
- ecc = runner.ecc;
71
- await initWasm();
72
- await runner.setupCoins(NUM_COINS, COIN_VALUE);
73
- });
74
-
75
- after(() => {
76
- runner.stop();
77
- });
78
-
79
- it('TxBuilder P2PKH SLP FUNGIBLE', async () => {
80
- const sk1 = fromHex('11'.repeat(32));
81
- const pk1 = ecc.derivePubkey(sk1);
82
- const pkh1 = shaRmd160(pk1);
83
- const p2pkh1 = Script.p2pkh(pkh1);
84
-
85
- const sk2 = fromHex('22'.repeat(32));
86
- const pk2 = ecc.derivePubkey(sk2);
87
- const pkh2 = shaRmd160(pk2);
88
- const p2pkh2 = Script.p2pkh(pkh2);
89
-
90
- const sk3 = fromHex('33'.repeat(32));
91
- const pk3 = ecc.derivePubkey(sk3);
92
- const pkh3 = shaRmd160(pk3);
93
- const p2pkh3 = Script.p2pkh(pkh3);
94
-
95
- const sk4 = fromHex('44'.repeat(32));
96
- const pk4 = ecc.derivePubkey(sk4);
97
- const pkh4 = shaRmd160(pk4);
98
- const p2pkh4 = Script.p2pkh(pkh4);
99
-
100
- await runner.sendToScript(50000, p2pkh1);
101
-
102
- const utxos = await chronik.script('p2pkh', toHex(pkh1)).utxos();
103
- expect(utxos.utxos.length).to.equal(1);
104
- const utxo = utxos.utxos[0];
105
-
106
- const txBuildGenesis = new TxBuilder({
107
- inputs: [
108
- {
109
- input: {
110
- prevOut: utxo.outpoint,
111
- signData: {
112
- value: utxo.value,
113
- outputScript: p2pkh1,
114
- },
115
- },
116
- signatory: P2PKHSignatory(sk1, pk1, ALL_BIP143),
117
- },
118
- ],
119
- outputs: [
120
- {
121
- value: 0,
122
- script: slpGenesis(
123
- SLP_FUNGIBLE,
124
- {
125
- tokenTicker: 'SLP FUNGIBLE TOKEN',
126
- tokenName: 'SLP Fungible Token Name',
127
- url: 'https://example.com/fungible',
128
- hash: '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
129
- decimals: 4,
130
- },
131
- 2000,
132
- 2,
133
- ),
134
- },
135
- { value: 10000, script: p2pkh2 },
136
- { value: 10000, script: p2pkh1 },
137
- ],
138
- });
139
- const genesisTx = txBuildGenesis.sign(ecc);
140
- const genesisTxid = (await chronik.broadcastTx(genesisTx.ser())).txid;
141
- const tokenId = genesisTxid;
142
-
143
- expect(await chronik.token(genesisTxid)).to.deep.equal({
144
- tokenId,
145
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
146
- genesisInfo: {
147
- tokenTicker: 'SLP FUNGIBLE TOKEN',
148
- tokenName: 'SLP Fungible Token Name',
149
- url: 'https://example.com/fungible',
150
- hash: '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
151
- decimals: 4,
152
- },
153
- timeFirstSeen: 1300000000,
154
- });
155
-
156
- const utxos2 = await chronik.script('p2pkh', toHex(pkh2)).utxos();
157
- expect(utxos2.utxos).to.deep.equal([
158
- {
159
- outpoint: {
160
- txid: genesisTxid,
161
- outIdx: 1,
162
- },
163
- blockHeight: -1,
164
- isCoinbase: false,
165
- value: 10000,
166
- isFinal: false,
167
- token: {
168
- amount: '2000',
169
- isMintBaton: false,
170
- tokenId: tokenId,
171
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
172
- },
173
- },
174
- ]);
175
-
176
- const txBuildMint = new TxBuilder({
177
- inputs: [
178
- {
179
- input: {
180
- prevOut: {
181
- txid: genesisTxid,
182
- outIdx: 2,
183
- },
184
- signData: {
185
- value: 10000,
186
- outputScript: p2pkh1,
187
- },
188
- },
189
- signatory: P2PKHSignatory(sk1, pk1, ALL_BIP143),
190
- },
191
- ],
192
- outputs: [
193
- {
194
- value: 0,
195
- script: slpMint(tokenId, SLP_FUNGIBLE, 500, 2),
196
- },
197
- { value: 546, script: p2pkh1 },
198
- { value: 546, script: p2pkh3 },
199
- ],
200
- });
201
- const mintTx = txBuildMint.sign(ecc);
202
- const mintTxid = (await chronik.broadcastTx(mintTx.ser())).txid;
203
-
204
- const utxos3 = await chronik.script('p2pkh', toHex(pkh3)).utxos();
205
- expect(utxos3.utxos).to.deep.equal([
206
- {
207
- outpoint: {
208
- txid: mintTxid,
209
- outIdx: 2,
210
- },
211
- blockHeight: -1,
212
- isCoinbase: false,
213
- value: 546,
214
- isFinal: false,
215
- token: {
216
- amount: '0',
217
- isMintBaton: true,
218
- tokenId: tokenId,
219
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
220
- },
221
- },
222
- ]);
223
-
224
- const txBuildSend = new TxBuilder({
225
- inputs: [
226
- {
227
- input: {
228
- prevOut: {
229
- txid: mintTxid,
230
- outIdx: 1,
231
- },
232
- signData: {
233
- value: 546,
234
- outputScript: p2pkh1,
235
- },
236
- },
237
- signatory: P2PKHSignatory(sk1, pk1, ALL_BIP143),
238
- },
239
- {
240
- input: {
241
- prevOut: {
242
- txid: genesisTxid,
243
- outIdx: 1,
244
- },
245
- signData: {
246
- value: 10000,
247
- outputScript: p2pkh2,
248
- },
249
- },
250
- signatory: P2PKHSignatory(sk2, pk2, ALL_BIP143),
251
- },
252
- ],
253
- outputs: [
254
- {
255
- value: 0,
256
- script: slpSend(tokenId, SLP_FUNGIBLE, [1000, 1500]),
257
- },
258
- { value: 546, script: p2pkh2 },
259
- { value: 546, script: p2pkh4 },
260
- ],
261
- });
262
- const sendTx = txBuildSend.sign(ecc);
263
- const sendTxid = (await chronik.broadcastTx(sendTx.ser())).txid;
264
-
265
- const sendProtoTx = await chronik.tx(sendTxid);
266
- expect(sendProtoTx).to.deep.equal({
267
- txid: sendTxid,
268
- version: 2,
269
- inputs: [
270
- {
271
- inputScript: toHex(sendTx.inputs[0].script!.bytecode),
272
- outputScript: toHex(p2pkh1.bytecode),
273
- prevOut: sendTx.inputs[0].prevOut,
274
- sequenceNo: 0xffffffff,
275
- token: {
276
- amount: '500',
277
- entryIdx: 0,
278
- isMintBaton: false,
279
- tokenId: tokenId,
280
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
281
- },
282
- value: 546,
283
- },
284
- {
285
- inputScript: toHex(sendTx.inputs[1].script!.bytecode),
286
- outputScript: toHex(p2pkh2.bytecode),
287
- prevOut: sendTx.inputs[1].prevOut,
288
- sequenceNo: 0xffffffff,
289
- token: {
290
- amount: '2000',
291
- entryIdx: 0,
292
- isMintBaton: false,
293
- tokenId: tokenId,
294
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
295
- },
296
- value: 10000,
297
- },
298
- ],
299
- outputs: [
300
- {
301
- value: 0,
302
- outputScript: toHex(sendTx.outputs[0].script.bytecode),
303
- },
304
- {
305
- outputScript: toHex(p2pkh2.bytecode),
306
- token: {
307
- amount: '1000',
308
- entryIdx: 0,
309
- isMintBaton: false,
310
- tokenId: tokenId,
311
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
312
- },
313
- value: 546,
314
- },
315
- {
316
- outputScript: toHex(p2pkh4.bytecode),
317
- token: {
318
- amount: '1500',
319
- entryIdx: 0,
320
- isMintBaton: false,
321
- tokenId: tokenId,
322
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
323
- },
324
- value: 546,
325
- },
326
- ],
327
- lockTime: 0,
328
- timeFirstSeen: 1300000000,
329
- size: sendTx.serSize(),
330
- isCoinbase: false,
331
- tokenEntries: [
332
- {
333
- actualBurnAmount: '0',
334
- burnSummary: '',
335
- burnsMintBatons: false,
336
- failedColorings: [],
337
- intentionalBurn: '0',
338
- isInvalid: false,
339
- tokenId: tokenId,
340
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
341
- txType: 'SEND',
342
- },
343
- ],
344
- tokenFailedParsings: [],
345
- tokenStatus: 'TOKEN_STATUS_NORMAL',
346
- });
347
-
348
- const txBuildBurn = new TxBuilder({
349
- inputs: [
350
- {
351
- input: {
352
- prevOut: {
353
- txid: sendTxid,
354
- outIdx: 1,
355
- },
356
- signData: {
357
- value: 546,
358
- outputScript: p2pkh2,
359
- },
360
- },
361
- signatory: P2PKHSignatory(sk2, pk2, ALL_BIP143),
362
- },
363
- ],
364
- outputs: [
365
- {
366
- value: 0,
367
- script: slpBurn(tokenId, SLP_FUNGIBLE, 1000),
368
- },
369
- ],
370
- });
371
- const burnTx = txBuildBurn.sign(ecc);
372
- const burnTxid = (await chronik.broadcastTx(burnTx.ser())).txid;
373
- const burnProtoTx = await chronik.tx(burnTxid);
374
- expect(burnProtoTx).to.deep.equal({
375
- txid: burnTxid,
376
- version: 2,
377
- inputs: [
378
- {
379
- inputScript: toHex(burnTx.inputs[0].script!.bytecode),
380
- outputScript: toHex(p2pkh2.bytecode),
381
- prevOut: burnTx.inputs[0].prevOut,
382
- sequenceNo: 0xffffffff,
383
- token: {
384
- amount: '1000',
385
- entryIdx: 0,
386
- isMintBaton: false,
387
- tokenId: tokenId,
388
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
389
- },
390
- value: 546,
391
- },
392
- ],
393
- outputs: [
394
- {
395
- value: 0,
396
- outputScript: toHex(burnTx.outputs[0].script.bytecode),
397
- },
398
- ],
399
- lockTime: 0,
400
- timeFirstSeen: 1300000000,
401
- size: burnTx.serSize(),
402
- isCoinbase: false,
403
- tokenEntries: [
404
- {
405
- actualBurnAmount: '1000',
406
- burnSummary: '',
407
- burnsMintBatons: false,
408
- failedColorings: [],
409
- intentionalBurn: '1000',
410
- isInvalid: false,
411
- tokenId: tokenId,
412
- tokenType: SLP_TOKEN_TYPE_FUNGIBLE,
413
- txType: 'BURN',
414
- },
415
- ],
416
- tokenFailedParsings: [],
417
- tokenStatus: 'TOKEN_STATUS_NORMAL',
418
- });
419
- });
420
-
421
- it('TxBuilder P2PKH SLP MINT VAULT', async () => {
422
- const sk1 = fromHex('55'.repeat(32));
423
- const pk1 = ecc.derivePubkey(sk1);
424
- const pkh1 = shaRmd160(pk1);
425
- const p2pkh1 = Script.p2pkh(pkh1);
426
-
427
- const sk2 = fromHex('66'.repeat(32));
428
- const pk2 = ecc.derivePubkey(sk2);
429
- const pkh2 = shaRmd160(pk2);
430
- const p2pkh2 = Script.p2pkh(pkh2);
431
-
432
- const sk3 = fromHex('77'.repeat(32));
433
- const pk3 = ecc.derivePubkey(sk3);
434
- const pkh3 = shaRmd160(pk3);
435
- const p2pkh3 = Script.p2pkh(pkh3);
436
-
437
- const sk4 = fromHex('88'.repeat(32));
438
- const pk4 = ecc.derivePubkey(sk4);
439
- const pkh4 = shaRmd160(pk4);
440
- const p2pkh4 = Script.p2pkh(pkh4);
441
-
442
- const mintVaultScript = Script.fromOps([OP_10]);
443
- const mintVaultScripthash = shaRmd160(mintVaultScript.bytecode);
444
- const mintVaultP2sh = Script.p2sh(mintVaultScripthash);
445
-
446
- const wsBlocks = new EventEmitter();
447
- const ws = chronik.ws({
448
- onMessage: msg => {
449
- if (msg.type == 'Block') {
450
- wsBlocks.emit(msg.msgType);
451
- }
452
- },
453
- });
454
- await ws.waitForOpen();
455
- ws.subscribeToBlocks();
456
-
457
- await runner.sendToScript(50000, p2pkh1);
458
-
459
- const utxos = await chronik.script('p2pkh', toHex(pkh1)).utxos();
460
- expect(utxos.utxos.length).to.equal(1);
461
- const utxo = utxos.utxos[0];
462
-
463
- const txBuildGenesis = new TxBuilder({
464
- inputs: [
465
- {
466
- input: {
467
- prevOut: utxo.outpoint,
468
- signData: {
469
- value: utxo.value,
470
- outputScript: p2pkh1,
471
- },
472
- },
473
- signatory: P2PKHSignatory(sk1, pk1, ALL_BIP143),
474
- },
475
- ],
476
- outputs: [
477
- {
478
- value: 0,
479
- script: slpGenesis(
480
- SLP_MINT_VAULT,
481
- {
482
- tokenTicker: 'SLP MINT VAULT TOKEN',
483
- tokenName: 'SLP MINT Vault Token Name',
484
- url: 'https://example.com/mintvault',
485
- hash: '00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff',
486
- mintVaultScripthash: toHex(mintVaultScripthash),
487
- decimals: 4,
488
- },
489
- 2000,
490
- ),
491
- },
492
- { value: 10000, script: p2pkh2 },
493
- ],
494
- });
495
- const genesisTx = txBuildGenesis.sign(ecc);
496
- const genesisTxid = (await chronik.broadcastTx(genesisTx.ser())).txid;
497
- const tokenId = genesisTxid;
498
-
499
- expect(await chronik.token(genesisTxid)).to.deep.equal({
500
- tokenId,
501
- tokenType: SLP_TOKEN_TYPE_MINT_VAULT,
502
- genesisInfo: {
503
- tokenTicker: 'SLP MINT VAULT TOKEN',
504
- tokenName: 'SLP MINT Vault Token Name',
505
- url: 'https://example.com/mintvault',
506
- hash: '00112233445566778899aabbccddeeff00112233445566778899aabbccddeeff',
507
- mintVaultScripthash: toHex(mintVaultScripthash),
508
- decimals: 4,
509
- },
510
- timeFirstSeen: 1300000000,
511
- });
512
-
513
- const utxos2 = await chronik.script('p2pkh', toHex(pkh2)).utxos();
514
- expect(utxos2.utxos).to.deep.equal([
515
- {
516
- outpoint: {
517
- txid: genesisTxid,
518
- outIdx: 1,
519
- },
520
- blockHeight: -1,
521
- isCoinbase: false,
522
- value: 10000,
523
- isFinal: false,
524
- token: {
525
- amount: '2000',
526
- isMintBaton: false,
527
- tokenId: tokenId,
528
- tokenType: SLP_TOKEN_TYPE_MINT_VAULT,
529
- },
530
- },
531
- ]);
532
-
533
- // MINT VAULT GENESIS has to be mined
534
- runner.generate();
535
- await once(wsBlocks, 'BLK_CONNECTED');
536
-
537
- const mintVaultTxid = await runner.sendToScript(50000, mintVaultP2sh);
538
-
539
- const txBuildMint = new TxBuilder({
540
- inputs: [
541
- {
542
- input: {
543
- prevOut: {
544
- txid: mintVaultTxid,
545
- outIdx: 0,
546
- },
547
- script: Script.fromOps([
548
- pushBytesOp(mintVaultScript.bytecode),
549
- ]),
550
- },
551
- },
552
- ],
553
- outputs: [
554
- {
555
- value: 0,
556
- script: slpMintVault(tokenId, [500, 600]),
557
- },
558
- { value: 546, script: p2pkh1 },
559
- { value: 546, script: p2pkh3 },
560
- ],
561
- });
562
- const mintTx = txBuildMint.sign(ecc);
563
- const mintTxid = (await chronik.broadcastTx(mintTx.ser())).txid;
564
-
565
- const utxos3 = await chronik.script('p2pkh', toHex(pkh3)).utxos();
566
- expect(utxos3.utxos).to.deep.equal([
567
- {
568
- outpoint: {
569
- txid: mintTxid,
570
- outIdx: 2,
571
- },
572
- blockHeight: -1,
573
- isCoinbase: false,
574
- value: 546,
575
- isFinal: false,
576
- token: {
577
- amount: '600',
578
- isMintBaton: false,
579
- tokenId: tokenId,
580
- tokenType: SLP_TOKEN_TYPE_MINT_VAULT,
581
- },
582
- },
583
- ]);
584
-
585
- const txBuildSend = new TxBuilder({
586
- inputs: [
587
- {
588
- input: {
589
- prevOut: {
590
- txid: mintTxid,
591
- outIdx: 1,
592
- },
593
- signData: {
594
- value: 546,
595
- outputScript: p2pkh1,
596
- },
597
- },
598
- signatory: P2PKHSignatory(sk1, pk1, ALL_BIP143),
599
- },
600
- {
601
- input: {
602
- prevOut: {
603
- txid: genesisTxid,
604
- outIdx: 1,
605
- },
606
- signData: {
607
- value: 10000,
608
- outputScript: p2pkh2,
609
- },
610
- },
611
- signatory: P2PKHSignatory(sk2, pk2, ALL_BIP143),
612
- },
613
- ],
614
- outputs: [
615
- {
616
- value: 0,
617
- script: slpSend(tokenId, SLP_MINT_VAULT, [1000, 1500]),
618
- },
619
- { value: 546, script: p2pkh2 },
620
- { value: 546, script: p2pkh4 },
621
- ],
622
- });
623
- const sendTx = txBuildSend.sign(ecc);
624
- const sendTxid = (await chronik.broadcastTx(sendTx.ser())).txid;
625
-
626
- const sendProtoTx = await chronik.tx(sendTxid);
627
- expect(sendProtoTx).to.deep.equal({
628
- txid: sendTxid,
629
- version: 2,
630
- inputs: [
631
- {
632
- inputScript: toHex(sendTx.inputs[0].script!.bytecode),
633
- outputScript: toHex(p2pkh1.bytecode),
634
- prevOut: sendTx.inputs[0].prevOut,
635
- sequenceNo: 0xffffffff,
636
- token: {
637
- amount: '500',
638
- entryIdx: 0,
639
- isMintBaton: false,
640
- tokenId: tokenId,
641
- tokenType: SLP_TOKEN_TYPE_MINT_VAULT,
642
- },
643
- value: 546,
644
- },
645
- {
646
- inputScript: toHex(sendTx.inputs[1].script!.bytecode),
647
- outputScript: toHex(p2pkh2.bytecode),
648
- prevOut: sendTx.inputs[1].prevOut,
649
- sequenceNo: 0xffffffff,
650
- token: {
651
- amount: '2000',
652
- entryIdx: 0,
653
- isMintBaton: false,
654
- tokenId: tokenId,
655
- tokenType: SLP_TOKEN_TYPE_MINT_VAULT,
656
- },
657
- value: 10000,
658
- },
659
- ],
660
- outputs: [
661
- {
662
- value: 0,
663
- outputScript: toHex(sendTx.outputs[0].script.bytecode),
664
- },
665
- {
666
- outputScript: toHex(p2pkh2.bytecode),
667
- token: {
668
- amount: '1000',
669
- entryIdx: 0,
670
- isMintBaton: false,
671
- tokenId: tokenId,
672
- tokenType: SLP_TOKEN_TYPE_MINT_VAULT,
673
- },
674
- value: 546,
675
- },
676
- {
677
- outputScript: toHex(p2pkh4.bytecode),
678
- token: {
679
- amount: '1500',
680
- entryIdx: 0,
681
- isMintBaton: false,
682
- tokenId: tokenId,
683
- tokenType: SLP_TOKEN_TYPE_MINT_VAULT,
684
- },
685
- value: 546,
686
- },
687
- ],
688
- lockTime: 0,
689
- timeFirstSeen: 1300000000,
690
- size: sendTx.serSize(),
691
- isCoinbase: false,
692
- tokenEntries: [
693
- {
694
- actualBurnAmount: '0',
695
- burnSummary: '',
696
- burnsMintBatons: false,
697
- failedColorings: [],
698
- intentionalBurn: '0',
699
- isInvalid: false,
700
- tokenId: tokenId,
701
- tokenType: SLP_TOKEN_TYPE_MINT_VAULT,
702
- txType: 'SEND',
703
- },
704
- ],
705
- tokenFailedParsings: [],
706
- tokenStatus: 'TOKEN_STATUS_NORMAL',
707
- });
708
- });
709
-
710
- it('TxBuilder P2PKH SLP NFT1', async () => {
711
- const sk1 = fromHex('99'.repeat(32));
712
- const pk1 = ecc.derivePubkey(sk1);
713
- const pkh1 = shaRmd160(pk1);
714
- const p2pkh1 = Script.p2pkh(pkh1);
715
-
716
- const sk2 = fromHex('aa'.repeat(32));
717
- const pk2 = ecc.derivePubkey(sk2);
718
- const pkh2 = shaRmd160(pk2);
719
- const p2pkh2 = Script.p2pkh(pkh2);
720
-
721
- const sk3 = fromHex('bb'.repeat(32));
722
- const pk3 = ecc.derivePubkey(sk3);
723
- const pkh3 = shaRmd160(pk3);
724
- const p2pkh3 = Script.p2pkh(pkh3);
725
-
726
- const sk4 = fromHex('cc'.repeat(32));
727
- const pk4 = ecc.derivePubkey(sk4);
728
- const pkh4 = shaRmd160(pk4);
729
- const p2pkh4 = Script.p2pkh(pkh4);
730
-
731
- await runner.sendToScript(50000, p2pkh1);
732
-
733
- const utxos = await chronik.script('p2pkh', toHex(pkh1)).utxos();
734
- expect(utxos.utxos.length).to.equal(1);
735
- const utxo = utxos.utxos[0];
736
-
737
- const txBuildGenesisGroup = new TxBuilder({
738
- inputs: [
739
- {
740
- input: {
741
- prevOut: utxo.outpoint,
742
- signData: {
743
- value: utxo.value,
744
- outputScript: p2pkh1,
745
- },
746
- },
747
- signatory: P2PKHSignatory(sk1, pk1, ALL_BIP143),
748
- },
749
- ],
750
- outputs: [
751
- {
752
- value: 0,
753
- script: slpGenesis(
754
- SLP_NFT1_GROUP,
755
- {
756
- tokenTicker: 'SLP NFT1 TOKEN',
757
- tokenName: 'SLP NFT1 Token Name',
758
- url: 'https://example.com/nft1',
759
- hash: '000111222333444555666777888999aaabbbcccdddeeefff0001112223334444',
760
- decimals: 4,
761
- },
762
- 2000,
763
- 2,
764
- ),
765
- },
766
- { value: 10000, script: p2pkh2 },
767
- { value: 10000, script: p2pkh1 },
768
- ],
769
- });
770
- const genesisTx = txBuildGenesisGroup.sign(ecc);
771
- const genesisTxid = (await chronik.broadcastTx(genesisTx.ser())).txid;
772
- const tokenId = genesisTxid;
773
-
774
- expect(await chronik.token(genesisTxid)).to.deep.equal({
775
- tokenId,
776
- tokenType: SLP_TOKEN_TYPE_NFT1_GROUP,
777
- genesisInfo: {
778
- tokenTicker: 'SLP NFT1 TOKEN',
779
- tokenName: 'SLP NFT1 Token Name',
780
- url: 'https://example.com/nft1',
781
- hash: '000111222333444555666777888999aaabbbcccdddeeefff0001112223334444',
782
- decimals: 4,
783
- },
784
- timeFirstSeen: 1300000000,
785
- });
786
-
787
- const utxos2 = await chronik.script('p2pkh', toHex(pkh2)).utxos();
788
- expect(utxos2.utxos).to.deep.equal([
789
- {
790
- outpoint: {
791
- txid: genesisTxid,
792
- outIdx: 1,
793
- },
794
- blockHeight: -1,
795
- isCoinbase: false,
796
- value: 10000,
797
- isFinal: false,
798
- token: {
799
- amount: '2000',
800
- isMintBaton: false,
801
- tokenId: tokenId,
802
- tokenType: SLP_TOKEN_TYPE_NFT1_GROUP,
803
- },
804
- },
805
- ]);
806
-
807
- const txBuildMint = new TxBuilder({
808
- inputs: [
809
- {
810
- input: {
811
- prevOut: {
812
- txid: genesisTxid,
813
- outIdx: 2,
814
- },
815
- signData: {
816
- value: 10000,
817
- outputScript: p2pkh1,
818
- },
819
- },
820
- signatory: P2PKHSignatory(sk1, pk1, ALL_BIP143),
821
- },
822
- ],
823
- outputs: [
824
- {
825
- value: 0,
826
- script: slpMint(tokenId, SLP_NFT1_GROUP, 500, 2),
827
- },
828
- { value: 546, script: p2pkh1 },
829
- { value: 546, script: p2pkh3 },
830
- ],
831
- });
832
- const mintTx = txBuildMint.sign(ecc);
833
- const mintTxid = (await chronik.broadcastTx(mintTx.ser())).txid;
834
-
835
- const utxos3 = await chronik.script('p2pkh', toHex(pkh3)).utxos();
836
- expect(utxos3.utxos).to.deep.equal([
837
- {
838
- outpoint: {
839
- txid: mintTxid,
840
- outIdx: 2,
841
- },
842
- blockHeight: -1,
843
- isCoinbase: false,
844
- value: 546,
845
- isFinal: false,
846
- token: {
847
- amount: '0',
848
- isMintBaton: true,
849
- tokenId: tokenId,
850
- tokenType: SLP_TOKEN_TYPE_NFT1_GROUP,
851
- },
852
- },
853
- ]);
854
-
855
- const txBuildSend = new TxBuilder({
856
- inputs: [
857
- {
858
- input: {
859
- prevOut: {
860
- txid: mintTxid,
861
- outIdx: 1,
862
- },
863
- signData: {
864
- value: 546,
865
- outputScript: p2pkh1,
866
- },
867
- },
868
- signatory: P2PKHSignatory(sk1, pk1, ALL_BIP143),
869
- },
870
- {
871
- input: {
872
- prevOut: {
873
- txid: genesisTxid,
874
- outIdx: 1,
875
- },
876
- signData: {
877
- value: 10000,
878
- outputScript: p2pkh2,
879
- },
880
- },
881
- signatory: P2PKHSignatory(sk2, pk2, ALL_BIP143),
882
- },
883
- ],
884
- outputs: [
885
- {
886
- value: 0,
887
- script: slpSend(tokenId, SLP_NFT1_GROUP, [1, 2499]),
888
- },
889
- { value: 8000, script: p2pkh2 },
890
- { value: 546, script: p2pkh4 },
891
- ],
892
- });
893
- const sendTx = txBuildSend.sign(ecc);
894
- const sendTxid = (await chronik.broadcastTx(sendTx.ser())).txid;
895
-
896
- const sendProtoTx = await chronik.tx(sendTxid);
897
- expect(sendProtoTx).to.deep.equal({
898
- txid: sendTxid,
899
- version: 2,
900
- inputs: [
901
- {
902
- inputScript: toHex(sendTx.inputs[0].script!.bytecode),
903
- outputScript: toHex(p2pkh1.bytecode),
904
- prevOut: sendTx.inputs[0].prevOut,
905
- sequenceNo: 0xffffffff,
906
- token: {
907
- amount: '500',
908
- entryIdx: 0,
909
- isMintBaton: false,
910
- tokenId: tokenId,
911
- tokenType: SLP_TOKEN_TYPE_NFT1_GROUP,
912
- },
913
- value: 546,
914
- },
915
- {
916
- inputScript: toHex(sendTx.inputs[1].script!.bytecode),
917
- outputScript: toHex(p2pkh2.bytecode),
918
- prevOut: sendTx.inputs[1].prevOut,
919
- sequenceNo: 0xffffffff,
920
- token: {
921
- amount: '2000',
922
- entryIdx: 0,
923
- isMintBaton: false,
924
- tokenId: tokenId,
925
- tokenType: SLP_TOKEN_TYPE_NFT1_GROUP,
926
- },
927
- value: 10000,
928
- },
929
- ],
930
- outputs: [
931
- {
932
- value: 0,
933
- outputScript: toHex(sendTx.outputs[0].script.bytecode),
934
- },
935
- {
936
- outputScript: toHex(p2pkh2.bytecode),
937
- token: {
938
- amount: '1',
939
- entryIdx: 0,
940
- isMintBaton: false,
941
- tokenId: tokenId,
942
- tokenType: SLP_TOKEN_TYPE_NFT1_GROUP,
943
- },
944
- value: 8000,
945
- },
946
- {
947
- outputScript: toHex(p2pkh4.bytecode),
948
- token: {
949
- amount: '2499',
950
- entryIdx: 0,
951
- isMintBaton: false,
952
- tokenId: tokenId,
953
- tokenType: SLP_TOKEN_TYPE_NFT1_GROUP,
954
- },
955
- value: 546,
956
- },
957
- ],
958
- lockTime: 0,
959
- timeFirstSeen: 1300000000,
960
- size: sendTx.serSize(),
961
- isCoinbase: false,
962
- tokenEntries: [
963
- {
964
- actualBurnAmount: '0',
965
- burnSummary: '',
966
- burnsMintBatons: false,
967
- failedColorings: [],
968
- intentionalBurn: '0',
969
- isInvalid: false,
970
- tokenId: tokenId,
971
- tokenType: SLP_TOKEN_TYPE_NFT1_GROUP,
972
- txType: 'SEND',
973
- },
974
- ],
975
- tokenFailedParsings: [],
976
- tokenStatus: 'TOKEN_STATUS_NORMAL',
977
- });
978
-
979
- const txBuildGenesisChild = new TxBuilder({
980
- inputs: [
981
- {
982
- input: {
983
- prevOut: {
984
- txid: sendTxid,
985
- outIdx: 1,
986
- },
987
- signData: {
988
- value: 8000,
989
- outputScript: p2pkh2,
990
- },
991
- },
992
- signatory: P2PKHSignatory(sk2, pk2, ALL_BIP143),
993
- },
994
- ],
995
- outputs: [
996
- {
997
- value: 0,
998
- script: slpGenesis(
999
- SLP_NFT1_CHILD,
1000
- {
1001
- tokenTicker: 'SLP NFT1 CHILD TOKEN',
1002
- tokenName: 'SLP NFT1 Child Token Name',
1003
- url: 'https://example.com/nft1child',
1004
- hash: '0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff',
1005
- decimals: 0,
1006
- },
1007
- 1,
1008
- ),
1009
- },
1010
- { value: 6000, script: p2pkh1 },
1011
- ],
1012
- });
1013
- const genesisChildTx = txBuildGenesisChild.sign(ecc);
1014
- const genesisChildTxid = (
1015
- await chronik.broadcastTx(genesisChildTx.ser())
1016
- ).txid;
1017
- const childTokenId = genesisChildTxid;
1018
-
1019
- expect(await chronik.token(childTokenId)).to.deep.equal({
1020
- tokenId: childTokenId,
1021
- tokenType: SLP_TOKEN_TYPE_NFT1_CHILD,
1022
- genesisInfo: {
1023
- tokenTicker: 'SLP NFT1 CHILD TOKEN',
1024
- tokenName: 'SLP NFT1 Child Token Name',
1025
- url: 'https://example.com/nft1child',
1026
- hash: '0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff',
1027
- decimals: 0,
1028
- },
1029
- timeFirstSeen: 1300000000,
1030
- });
1031
-
1032
- const txBuildChildSend = new TxBuilder({
1033
- inputs: [
1034
- {
1035
- input: {
1036
- prevOut: {
1037
- txid: genesisChildTxid,
1038
- outIdx: 1,
1039
- },
1040
- signData: {
1041
- value: 6000,
1042
- outputScript: p2pkh1,
1043
- },
1044
- },
1045
- signatory: P2PKHSignatory(sk1, pk1, ALL_BIP143),
1046
- },
1047
- ],
1048
- outputs: [
1049
- {
1050
- value: 0,
1051
- script: slpSend(childTokenId, SLP_NFT1_CHILD, [0, 1]),
1052
- },
1053
- { value: 546, script: p2pkh2 },
1054
- { value: 546, script: p2pkh4 },
1055
- ],
1056
- });
1057
- const childSendTx = txBuildChildSend.sign(ecc);
1058
- const childSendTxid = (await chronik.broadcastTx(childSendTx.ser()))
1059
- .txid;
1060
-
1061
- const childSendProtoTx = await chronik.tx(childSendTxid);
1062
- expect(childSendProtoTx).to.deep.equal({
1063
- txid: childSendTxid,
1064
- version: 2,
1065
- inputs: [
1066
- {
1067
- inputScript: toHex(childSendTx.inputs[0].script!.bytecode),
1068
- outputScript: toHex(p2pkh1.bytecode),
1069
- prevOut: childSendTx.inputs[0].prevOut,
1070
- sequenceNo: 0xffffffff,
1071
- token: {
1072
- amount: '1',
1073
- entryIdx: 0,
1074
- isMintBaton: false,
1075
- tokenId: childTokenId,
1076
- tokenType: SLP_TOKEN_TYPE_NFT1_CHILD,
1077
- },
1078
- value: 6000,
1079
- },
1080
- ],
1081
- outputs: [
1082
- {
1083
- value: 0,
1084
- outputScript: toHex(childSendTx.outputs[0].script.bytecode),
1085
- },
1086
- {
1087
- outputScript: toHex(p2pkh2.bytecode),
1088
- value: 546,
1089
- },
1090
- {
1091
- outputScript: toHex(p2pkh4.bytecode),
1092
- token: {
1093
- amount: '1',
1094
- entryIdx: 0,
1095
- isMintBaton: false,
1096
- tokenId: childTokenId,
1097
- tokenType: SLP_TOKEN_TYPE_NFT1_CHILD,
1098
- },
1099
- value: 546,
1100
- },
1101
- ],
1102
- lockTime: 0,
1103
- timeFirstSeen: 1300000000,
1104
- size: childSendTx.serSize(),
1105
- isCoinbase: false,
1106
- tokenEntries: [
1107
- {
1108
- actualBurnAmount: '0',
1109
- burnSummary: '',
1110
- burnsMintBatons: false,
1111
- failedColorings: [],
1112
- intentionalBurn: '0',
1113
- isInvalid: false,
1114
- tokenId: childTokenId,
1115
- tokenType: SLP_TOKEN_TYPE_NFT1_CHILD,
1116
- groupTokenId: tokenId,
1117
- txType: 'SEND',
1118
- },
1119
- ],
1120
- tokenFailedParsings: [],
1121
- tokenStatus: 'TOKEN_STATUS_NORMAL',
1122
- });
1123
- });
1124
- });