mainnet-js 1.0.7 → 1.0.8

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 (50) hide show
  1. package/dist/index.html +1 -1
  2. package/dist/{mainnet-1.0.7.js → mainnet-1.0.8.js} +17 -7
  3. package/dist/module/config.d.ts +4 -0
  4. package/dist/module/config.d.ts.map +1 -0
  5. package/dist/module/config.js +4 -0
  6. package/dist/module/config.js.map +1 -0
  7. package/dist/module/index.d.ts +1 -0
  8. package/dist/module/index.d.ts.map +1 -1
  9. package/dist/module/index.js +2 -0
  10. package/dist/module/index.js.map +1 -1
  11. package/dist/module/network/ElectrumNetworkProvider.d.ts +6 -2
  12. package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
  13. package/dist/module/network/ElectrumNetworkProvider.js +69 -45
  14. package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
  15. package/dist/module/network/interface.d.ts +11 -8
  16. package/dist/module/network/interface.d.ts.map +1 -1
  17. package/dist/module/transaction/Wif.d.ts +1 -1
  18. package/dist/module/transaction/Wif.d.ts.map +1 -1
  19. package/dist/module/transaction/Wif.js +15 -7
  20. package/dist/module/transaction/Wif.js.map +1 -1
  21. package/dist/module/util/deriveCashaddr.d.ts +1 -0
  22. package/dist/module/util/deriveCashaddr.d.ts.map +1 -1
  23. package/dist/module/util/deriveCashaddr.js +5 -0
  24. package/dist/module/util/deriveCashaddr.js.map +1 -1
  25. package/dist/module/wallet/Util.d.ts.map +1 -1
  26. package/dist/module/wallet/Util.js +1 -0
  27. package/dist/module/wallet/Util.js.map +1 -1
  28. package/dist/module/wallet/Wif.d.ts +3 -0
  29. package/dist/module/wallet/Wif.d.ts.map +1 -1
  30. package/dist/module/wallet/Wif.js +14 -20
  31. package/dist/module/wallet/Wif.js.map +1 -1
  32. package/dist/module/wallet/interface.d.ts +1 -0
  33. package/dist/module/wallet/interface.d.ts.map +1 -1
  34. package/dist/module/wallet/model.d.ts.map +1 -1
  35. package/dist/module/wallet/model.js +4 -3
  36. package/dist/module/wallet/model.js.map +1 -1
  37. package/dist/tsconfig.tsbuildinfo +1 -1
  38. package/package.json +1 -1
  39. package/src/config.ts +3 -0
  40. package/src/index.ts +3 -0
  41. package/src/network/ElectrumNetworkProvider.ts +99 -51
  42. package/src/network/interface.ts +12 -12
  43. package/src/transaction/Wif.ts +23 -8
  44. package/src/util/deriveCashaddr.ts +6 -0
  45. package/src/wallet/Cashtokens.test.ts +148 -6
  46. package/src/wallet/Util.ts +1 -0
  47. package/src/wallet/Wif.test.ts +5 -4
  48. package/src/wallet/Wif.ts +29 -21
  49. package/src/wallet/interface.ts +1 -0
  50. package/src/wallet/model.ts +5 -2
@@ -19,23 +19,21 @@ export interface ElectrumClusterParams {
19
19
  timeout: number;
20
20
  }
21
21
 
22
+ export interface ElectrumTokenData {
23
+ amount: string;
24
+ category: string;
25
+ nft?: {
26
+ capability?: NFTCapability;
27
+ commitment?: string;
28
+ };
29
+ }
30
+
22
31
  export interface ElectrumUtxo {
23
32
  tx_pos: number;
24
33
  value: number;
25
34
  tx_hash: string;
26
35
  height: number;
27
- token_data:
28
- | {
29
- amount: string;
30
- category: string;
31
- nft:
32
- | {
33
- capability: NFTCapability | undefined;
34
- commitment: string | undefined;
35
- }
36
- | undefined;
37
- }
38
- | undefined;
36
+ token_data?: ElectrumTokenData;
39
37
  }
40
38
 
41
39
  export interface ElectrumRawTransaction {
@@ -65,12 +63,14 @@ export interface ElectrumRawTransactionVin {
65
63
  vout: number;
66
64
  value?: number; // optional extention by mainnet.cash
67
65
  address?: string; // optional extension by mainnet.cash
66
+ tokenData?: ElectrumTokenData; // optional extension by mainnet.cash
68
67
  }
69
68
 
70
69
  export interface ElectrumRawTransactionVout {
71
70
  n: number;
72
71
  scriptPubKey: ElectrumRawTransactionVoutScriptPubKey;
73
72
  value: number;
73
+ tokenData?: ElectrumTokenData;
74
74
  }
75
75
 
76
76
  export interface ElectrumRawTransactionVoutScriptPubKey {
@@ -286,7 +286,8 @@ export async function getSuitableUtxos(
286
286
  amountRequired: BigInt | undefined,
287
287
  bestHeight: number,
288
288
  feePaidBy: FeePaidByEnum,
289
- requests: SendRequestType[]
289
+ requests: SendRequestType[],
290
+ ensureUtxos: UtxoI[] = []
290
291
  ): Promise<UtxoI[]> {
291
292
  let suitableUtxos: UtxoI[] = [];
292
293
  let amountAvailable = BigInt(0);
@@ -294,6 +295,16 @@ export async function getSuitableUtxos(
294
295
  const tokenRequests = requests.filter(
295
296
  (val) => val instanceof TokenSendRequest
296
297
  ) as TokenSendRequest[];
298
+
299
+ // if we do a new token genesis, we shall filter all token utxos out
300
+ const isTokenGenesis = tokenRequests.some(
301
+ (val) => !val.tokenId || (val as any)._isGenesis
302
+ );
303
+ const bchOnlyTransfer = tokenRequests.length === 0;
304
+ let filteredInputs =
305
+ isTokenGenesis || bchOnlyTransfer
306
+ ? inputs.slice(0).filter((val) => !val.token)
307
+ : inputs.slice();
297
308
  const tokenIds = tokenRequests
298
309
  .map((val) => val.tokenId)
299
310
  .filter((value, index, array) => array.indexOf(value) === index);
@@ -304,8 +315,6 @@ export async function getSuitableUtxos(
304
315
  tokenAmountsRequired.push({ tokenId, requiredAmount });
305
316
  }
306
317
 
307
- let filteredInputs = inputs.slice(0);
308
-
309
318
  // find suitable token inputs first
310
319
  for (const { tokenId, requiredAmount } of tokenAmountsRequired) {
311
320
  let tokenAmountAvailable = 0;
@@ -325,10 +334,10 @@ export async function getSuitableUtxos(
325
334
  }
326
335
  }
327
336
 
328
- // find plain outputs
337
+ // find plain bch outputs
329
338
  for (const u of filteredInputs) {
330
339
  if (u.token) {
331
- // continue;
340
+ continue;
332
341
  }
333
342
 
334
343
  if (u.coinbase && u.height && bestHeight) {
@@ -347,14 +356,20 @@ export async function getSuitableUtxos(
347
356
  }
348
357
  }
349
358
 
359
+ const addEnsured = (suitableUtxos) => {
360
+ return [...suitableUtxos, ...ensureUtxos].filter(
361
+ (val, index, array) => array.indexOf(val) === index
362
+ );
363
+ };
364
+
350
365
  // if the fee is split with a feePaidBy option, skip checking change.
351
366
  if (feePaidBy && feePaidBy != FeePaidByEnum.change) {
352
- return suitableUtxos;
367
+ return addEnsured(suitableUtxos);
353
368
  }
354
369
 
355
370
  // If the amount needed is met, or no amount is given, return
356
371
  if (typeof amountRequired === "undefined") {
357
- return suitableUtxos;
372
+ return addEnsured(suitableUtxos);
358
373
  } else if (amountAvailable < amountRequired) {
359
374
  let e = Error(
360
375
  `Amount required was not met, ${amountRequired} satoshis needed, ${amountAvailable} satoshis available`
@@ -365,7 +380,7 @@ export async function getSuitableUtxos(
365
380
  };
366
381
  throw e;
367
382
  } else {
368
- return suitableUtxos;
383
+ return addEnsured(suitableUtxos);
369
384
  }
370
385
  }
371
386
 
@@ -131,3 +131,9 @@ export function isTokenaddr(address: string): boolean {
131
131
  ].indexOf(result.version) !== -1
132
132
  );
133
133
  }
134
+
135
+ export function checkTokenaddr(cashaddr: string, enforce: boolean) {
136
+ if (enforce && !isTokenaddr(cashaddr)) {
137
+ throw new Error("Error trying to send to a non-tokenaware cash address");
138
+ }
139
+ }
@@ -1,9 +1,15 @@
1
1
  import { RegTestWallet, TestNetWallet, Wallet } from "./Wif";
2
2
  import { initProviders, disconnectProviders } from "../network/Connection";
3
- import { SendRequest, TokenMintRequest, TokenSendRequest } from "./model";
3
+ import {
4
+ SendRequest,
5
+ SendResponse,
6
+ TokenMintRequest,
7
+ TokenSendRequest,
8
+ } from "./model";
4
9
  import { Network, NFTCapability } from "../interface";
5
10
  import { binToHex, utf8ToBin } from "@bitauth/libauth";
6
11
  import { delay } from "../util";
12
+ import { Config } from "../config";
7
13
 
8
14
  beforeAll(async () => {
9
15
  await initProviders();
@@ -194,9 +200,11 @@ describe(`Test cashtokens`, () => {
194
200
  const response = await alice.tokenMint(tokenId, [
195
201
  new TokenMintRequest({
196
202
  cashaddr: alice.cashaddr!,
203
+ commitment: "test",
197
204
  }),
198
205
  new TokenMintRequest({
199
206
  cashaddr: alice.cashaddr!,
207
+ commitment: "test2",
200
208
  }),
201
209
  ]);
202
210
  expect(await alice.getTokenBalance(tokenId)).toBe(0);
@@ -313,7 +321,7 @@ describe(`Test cashtokens`, () => {
313
321
  expect(tokenId).toEqual(response.tokenIds![0]);
314
322
  });
315
323
 
316
- test("Test explicit burning of FT+NFT", async () => {
324
+ test("Test explicit burning of FT and NFT", async () => {
317
325
  const alice = await RegTestWallet.fromId(process.env.ALICE_ID!);
318
326
  const genesisResponse = await alice.tokenGenesis({
319
327
  cashaddr: alice.cashaddr!,
@@ -439,13 +447,15 @@ describe(`Test cashtokens`, () => {
439
447
  expect(bobUtxos[1].satoshis).toBe(3349);
440
448
  });
441
449
 
442
- test("Test cashtoken waiting and watching balance", async () => {
450
+ test("Test cashtoken waiting and watching", async () => {
443
451
  const alice = await RegTestWallet.fromId(process.env.ALICE_ID!);
444
452
  const bob = await RegTestWallet.newRandom();
445
453
 
446
454
  const genesisResponse = await alice.tokenGenesis({
447
455
  amount: 100,
448
456
  value: 5000,
457
+ capability: NFTCapability.minting,
458
+ commitment: "test",
449
459
  cashaddr: alice.cashaddr!,
450
460
  });
451
461
 
@@ -457,16 +467,17 @@ describe(`Test cashtokens`, () => {
457
467
  expect(tokenUtxos[0].satoshis).toBe(5000);
458
468
 
459
469
  let seenBalance = 0;
470
+ let sendResponse: SendResponse = {};
460
471
  setTimeout(
461
- () =>
462
- alice.send([
472
+ async () =>
473
+ (sendResponse = await alice.send([
463
474
  new TokenSendRequest({
464
475
  cashaddr: bob.cashaddr!,
465
476
  amount: 100,
466
477
  tokenId: tokenId,
467
478
  value: 1500,
468
479
  }),
469
- ]),
480
+ ])),
470
481
  0
471
482
  );
472
483
 
@@ -474,10 +485,141 @@ describe(`Test cashtokens`, () => {
474
485
  seenBalance = balance;
475
486
  });
476
487
 
488
+ let bobTxId = ".";
489
+ const txCancel = bob.watchAddressTokenTransactions((tx) => {
490
+ bobTxId = tx.txid;
491
+ });
492
+
477
493
  const balance = await bob.waitForTokenBalance(tokenId, 100);
494
+ await delay(500);
478
495
  expect(balance).toBe(100);
479
496
  expect(seenBalance).toBe(100);
497
+ expect(sendResponse.txId).toBe(bobTxId);
480
498
  await cancel();
499
+ await txCancel();
481
500
  await delay(500);
482
501
  });
502
+
503
+ test("Test double genesis should not burn tokens", async () => {
504
+ const alice = await RegTestWallet.fromId(process.env.ALICE_ID!);
505
+ const bob = await RegTestWallet.newRandom();
506
+
507
+ // prepare inputs for two token geneses
508
+ await alice.send({ cashaddr: bob.cashaddr!, value: 10000, unit: "sat" });
509
+ await alice.send({ cashaddr: bob.cashaddr!, value: 10000, unit: "sat" });
510
+
511
+ const genesisResponse = await bob.tokenGenesis({
512
+ amount: 100,
513
+ });
514
+
515
+ const tokenId = genesisResponse.tokenIds![0];
516
+ const tokenBalance = await bob.getTokenBalance(tokenId);
517
+
518
+ expect(tokenBalance).toBe(100);
519
+ const tokenUtxos = await bob.getTokenUtxos(tokenId);
520
+ expect(tokenUtxos.length).toBe(1);
521
+
522
+ const genesis2Response = await bob.tokenGenesis({
523
+ amount: 200,
524
+ });
525
+
526
+ const tokenId2 = genesis2Response.tokenIds![0];
527
+ const tokenBalance2 = await bob.getTokenBalance(tokenId2);
528
+ expect(tokenBalance2).toBe(200);
529
+ const tokenUtxos2 = await bob.getTokenUtxos(tokenId2);
530
+ expect(tokenUtxos2.length).toBe(1);
531
+
532
+ expect((await bob.getTokenUtxos()).length).toBe(2);
533
+ });
534
+
535
+ test("Test sending tokens should not burn tokens", async () => {
536
+ const alice = await RegTestWallet.fromId(process.env.ALICE_ID!);
537
+ const bob = await RegTestWallet.newRandom();
538
+
539
+ // prepare inputs for two token geneses
540
+ await alice.send({ cashaddr: bob.cashaddr!, value: 10000, unit: "sat" });
541
+ await alice.send({ cashaddr: bob.cashaddr!, value: 10000, unit: "sat" });
542
+
543
+ const genesisResponse = await bob.tokenGenesis({
544
+ amount: 100,
545
+ });
546
+
547
+ const tokenId = genesisResponse.tokenIds![0];
548
+ const tokenBalance = await bob.getTokenBalance(tokenId);
549
+
550
+ expect(tokenBalance).toBe(100);
551
+ const tokenUtxos = await bob.getTokenUtxos(tokenId);
552
+ expect(tokenUtxos.length).toBe(1);
553
+
554
+ const genesis2Response = await bob.tokenGenesis({
555
+ amount: 200,
556
+ });
557
+
558
+ const tokenId2 = genesis2Response.tokenIds![0];
559
+ const tokenBalance2 = await bob.getTokenBalance(tokenId2);
560
+ expect(tokenBalance2).toBe(200);
561
+ const tokenUtxos2 = await bob.getTokenUtxos(tokenId2);
562
+ expect(tokenUtxos2.length).toBe(1);
563
+
564
+ expect((await bob.getTokenUtxos()).length).toBe(2);
565
+
566
+ const charlie = await RegTestWallet.newRandom();
567
+ await bob.send({
568
+ cashaddr: charlie.cashaddr!,
569
+ tokenId: tokenId,
570
+ amount: 50,
571
+ });
572
+ expect((await bob.getTokenUtxos()).length).toBe(2);
573
+ expect((await charlie.getTokenUtxos()).length).toBe(1);
574
+ expect(await bob.getTokenBalance(tokenId)).toBe(50);
575
+ expect(await charlie.getTokenBalance(tokenId)).toBe(50);
576
+ });
577
+
578
+ test("Test sending bch should not burn tokens", async () => {
579
+ const alice = await RegTestWallet.fromId(process.env.ALICE_ID!);
580
+ const bob = await RegTestWallet.newRandom();
581
+
582
+ // prepare inputs for two token geneses
583
+ await alice.send({ cashaddr: bob.cashaddr!, value: 10000, unit: "sat" });
584
+
585
+ const genesisResponse = await bob.tokenGenesis({
586
+ amount: 100,
587
+ });
588
+
589
+ const tokenId = genesisResponse.tokenIds![0];
590
+ const tokenBalance = await bob.getTokenBalance(tokenId);
591
+
592
+ expect(tokenBalance).toBe(100);
593
+ const tokenUtxos = await bob.getTokenUtxos(tokenId);
594
+ expect(tokenUtxos.length).toBe(1);
595
+
596
+ await bob.send({ cashaddr: alice.cashaddr!, value: 1000, unit: "sat" });
597
+
598
+ const tokenBalance2 = await bob.getTokenBalance(tokenId);
599
+ expect(tokenBalance2).toBe(100);
600
+ const tokenUtxos2 = await bob.getTokenUtxos(tokenId);
601
+ expect(tokenUtxos2.length).toBe(1);
602
+ });
603
+
604
+ test("Test enforcing tokenaddresses", async () => {
605
+ const bob = await RegTestWallet.newRandom();
606
+
607
+ const previousValue = Config.ValidateTokenAddresses;
608
+
609
+ const wrap = (addr) => {
610
+ return new Promise(() => {
611
+ return new TokenSendRequest({ cashaddr: addr, tokenId: "" });
612
+ });
613
+ };
614
+
615
+ Config.ValidateTokenAddresses = false;
616
+ expect(wrap(bob.cashaddr)).resolves.not.toThrow();
617
+ expect(wrap(bob.tokenaddr)).resolves.not.toThrow();
618
+
619
+ Config.ValidateTokenAddresses = true;
620
+ expect(wrap(bob.cashaddr)).rejects.toThrow();
621
+ expect(wrap(bob.tokenaddr)).resolves.not.toThrow();
622
+
623
+ Config.ValidateTokenAddresses = previousValue;
624
+ });
483
625
  });
@@ -100,6 +100,7 @@ export class Util {
100
100
  .vout.find((val) => val.n === input.vout)!;
101
101
  input.address = output.scriptPubKey.addresses[0];
102
102
  input.value = output.value;
103
+ input.tokenData = output.tokenData;
103
104
  });
104
105
  }
105
106
 
@@ -806,11 +806,11 @@ describe(`Wallet subscriptions`, () => {
806
806
  });
807
807
 
808
808
  let bobWatchResult = false;
809
- const bobWatchCancel = (
810
- bob.provider! as ElectrumNetworkProvider
811
- ).watchAddressStatus(bob.getDepositAddress(), (_status) => {
809
+ let bobTransactionId = "";
810
+ const bobWatchCancel = bob.watchAddress((txHash) => {
812
811
  bobWatchCancel();
813
812
  bobWatchResult = true;
813
+ bobTransactionId = txHash;
814
814
  });
815
815
 
816
816
  let bobBalanceWatchResult = false;
@@ -847,7 +847,7 @@ describe(`Wallet subscriptions`, () => {
847
847
  blockNumberWaitResult = true;
848
848
  }, 0);
849
849
 
850
- await alice.send({
850
+ const sendResponse = await alice.send({
851
851
  cashaddr: bob.getDepositAddress(),
852
852
  value: 0.001,
853
853
  unit: "bch",
@@ -862,6 +862,7 @@ describe(`Wallet subscriptions`, () => {
862
862
  expect(waitBalanceResult).toBe(true);
863
863
  expect(aliceWatchResult).toBe(true);
864
864
  expect(bobWatchResult).toBe(true);
865
+ expect(bobTransactionId).toBe(sendResponse.txId);
865
866
  expect(bobBalanceWatchResult).toBe(true);
866
867
  expect(blockWatchResult).toBe(true);
867
868
  expect(blockWaitResult).toBe(true);
package/src/wallet/Wif.ts CHANGED
@@ -711,25 +711,32 @@ export class Wallet extends BaseWallet {
711
711
  return this.getBalanceFromUtxos();
712
712
  }
713
713
 
714
- // // waiting for any transaction hash of this wallet
715
- // // commented out until fulcrum supports new method https://github.com/cculianu/Fulcrum/pull/89
716
- // public watchAddress(callback: (txHash: string) => void): CancelWatchFn {
717
- // return (this.provider! as ElectrumNetworkProvider).watchAddress(
718
- // this.getDepositAddress(),
719
- // callback
720
- // );
721
- // }
722
-
723
- // // waiting for any transaction of this wallet
724
- // // commented out until fulcrum supports new method https://github.com/cculianu/Fulcrum/pull/89
725
- // public watchAddressTransactions(
726
- // callback: (tx: ElectrumRawTransaction) => void
727
- // ): CancelWatchFn {
728
- // return (this.provider! as ElectrumNetworkProvider).watchAddressTransactions(
729
- // this.getDepositAddress(),
730
- // callback
731
- // );
732
- // }
714
+ // watching for any transaction hash of this wallet
715
+ public watchAddress(callback: (txHash: string) => void): CancelWatchFn {
716
+ return (this.provider! as ElectrumNetworkProvider).watchAddress(
717
+ this.getDepositAddress(),
718
+ callback
719
+ );
720
+ }
721
+
722
+ // watching for any transaction of this wallet
723
+ public watchAddressTransactions(
724
+ callback: (tx: ElectrumRawTransaction) => void
725
+ ): CancelWatchFn {
726
+ return (this.provider! as ElectrumNetworkProvider).watchAddressTransactions(
727
+ this.getDepositAddress(),
728
+ callback
729
+ );
730
+ }
731
+
732
+ // watching for cashtoken transaction of this wallet
733
+ public watchAddressTokenTransactions(
734
+ callback: (tx: ElectrumRawTransaction) => void
735
+ ): CancelWatchFn {
736
+ return (
737
+ this.provider! as ElectrumNetworkProvider
738
+ ).watchAddressTokenTransactions(this.getDepositAddress(), callback);
739
+ }
733
740
 
734
741
  // sets up a callback to be called upon wallet's balance change
735
742
  // can be cancelled by calling the function returned from this one
@@ -1195,7 +1202,8 @@ export class Wallet extends BaseWallet {
1195
1202
  BigInt(spendAmount) + BigInt(feeEstimate),
1196
1203
  bestHeight,
1197
1204
  feePaidBy,
1198
- sendRequests
1205
+ sendRequests,
1206
+ options?.ensureUtxos || []
1199
1207
  );
1200
1208
  if (fundingUtxos.length === 0) {
1201
1209
  throw Error(
@@ -1603,7 +1611,7 @@ export class Wallet extends BaseWallet {
1603
1611
  return this.send([opReturn, ...changeSendRequests], {
1604
1612
  checkTokenQuantities: false,
1605
1613
  queryBalance: false,
1606
- utxoIds: utxoIds.length > 0 ? utxoIds : undefined,
1614
+ ensureUtxos: utxoIds.length > 0 ? utxoIds : undefined,
1607
1615
  });
1608
1616
  }
1609
1617
 
@@ -54,6 +54,7 @@ export interface SendRequestOptionsI {
54
54
  awaitTransactionPropagation?: boolean;
55
55
  feePaidBy?: FeePaidByEnum;
56
56
  checkTokenQuantities?: boolean; // true
57
+ ensureUtxos?: UtxoI[]; // ensure these inputs will be consumed in the transaction
57
58
  }
58
59
 
59
60
  export interface MnemonicI {
@@ -4,6 +4,8 @@ import { UnitEnum } from "../enum.js";
4
4
  import { NFTCapability, UtxoI } from "../interface.js";
5
5
  import { DELIMITER } from "../constant.js";
6
6
  import { utf8ToBin } from "@bitauth/libauth";
7
+ import { Config } from "../config.js";
8
+ import { checkTokenaddr } from "../util/deriveCashaddr.js";
7
9
 
8
10
  // These are the minimal models used to provide types for the express server
9
11
  //
@@ -116,6 +118,8 @@ export class TokenSendRequest {
116
118
  capability?: NFTCapability;
117
119
  commitment?: string;
118
120
  }) {
121
+ checkTokenaddr(cashaddr, Config.ValidateTokenAddresses);
122
+
119
123
  this.cashaddr = cashaddr;
120
124
  this.value = value;
121
125
  this.amount = amount || 0;
@@ -142,8 +146,7 @@ export class TokenMintRequest {
142
146
  cashaddr?: string;
143
147
  value?: number;
144
148
  }) {
145
- // be explicit about minting capability for new NFTs
146
- this.capability = capability || NFTCapability.none;
149
+ this.capability = capability;
147
150
  this.commitment = commitment;
148
151
  this.cashaddr = cashaddr;
149
152
  this.value = value;