mainnet-js 1.1.34 → 2.0.1

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 (122) hide show
  1. package/dist/index.html +1 -1
  2. package/dist/{mainnet-1.1.34.js → mainnet-2.0.1.js} +26 -338
  3. package/dist/module/db/SqlProvider.d.ts +2 -2
  4. package/dist/module/db/SqlProvider.d.ts.map +1 -1
  5. package/dist/module/db/SqlProvider.js +6 -24
  6. package/dist/module/db/SqlProvider.js.map +1 -1
  7. package/dist/module/index.d.ts +0 -3
  8. package/dist/module/index.d.ts.map +1 -1
  9. package/dist/module/index.js +3 -6
  10. package/dist/module/index.js.map +1 -1
  11. package/dist/module/transaction/Wif.d.ts +4 -8
  12. package/dist/module/transaction/Wif.d.ts.map +1 -1
  13. package/dist/module/transaction/Wif.js +6 -10
  14. package/dist/module/transaction/Wif.js.map +1 -1
  15. package/dist/module/util/deriveCashaddr.d.ts +1 -0
  16. package/dist/module/util/deriveCashaddr.d.ts.map +1 -1
  17. package/dist/module/util/deriveCashaddr.js +8 -1
  18. package/dist/module/util/deriveCashaddr.js.map +1 -1
  19. package/dist/module/wallet/Base.d.ts +1 -1
  20. package/dist/module/wallet/Base.js +1 -1
  21. package/dist/module/wallet/Bcmr.d.ts +3 -1
  22. package/dist/module/wallet/Bcmr.d.ts.map +1 -1
  23. package/dist/module/wallet/Bcmr.js +4 -8
  24. package/dist/module/wallet/Bcmr.js.map +1 -1
  25. package/dist/module/wallet/Util.d.ts +2 -2
  26. package/dist/module/wallet/Util.js +2 -2
  27. package/dist/module/wallet/Wif.d.ts +0 -28
  28. package/dist/module/wallet/Wif.d.ts.map +1 -1
  29. package/dist/module/wallet/Wif.js +2 -109
  30. package/dist/module/wallet/Wif.js.map +1 -1
  31. package/dist/module/wallet/createWallet.d.ts +0 -12
  32. package/dist/module/wallet/createWallet.d.ts.map +1 -1
  33. package/dist/module/wallet/createWallet.js +0 -43
  34. package/dist/module/wallet/createWallet.js.map +1 -1
  35. package/dist/module/wallet/interface.d.ts +0 -2
  36. package/dist/module/wallet/interface.d.ts.map +1 -1
  37. package/dist/module/webhook/Webhook.d.ts +1 -6
  38. package/dist/module/webhook/Webhook.d.ts.map +1 -1
  39. package/dist/module/webhook/Webhook.js +0 -4
  40. package/dist/module/webhook/Webhook.js.map +1 -1
  41. package/dist/module/webhook/index.d.ts +0 -1
  42. package/dist/module/webhook/index.d.ts.map +1 -1
  43. package/dist/module/webhook/index.js +0 -1
  44. package/dist/module/webhook/index.js.map +1 -1
  45. package/dist/module/webhook/interface.d.ts +0 -1
  46. package/dist/module/webhook/interface.d.ts.map +1 -1
  47. package/dist/tsconfig.tsbuildinfo +1 -1
  48. package/package.json +5 -10
  49. package/src/db/SqlProvider.test.ts +2 -18
  50. package/src/db/SqlProvider.ts +5 -26
  51. package/src/index.ts +3 -7
  52. package/src/transaction/Wif.ts +2 -19
  53. package/src/util/deriveCashaddr.test.ts +8 -0
  54. package/src/util/deriveCashaddr.ts +9 -0
  55. package/src/wallet/Base.ts +1 -1
  56. package/src/wallet/Bcmr.ts +4 -9
  57. package/src/wallet/Util.ts +2 -2
  58. package/src/wallet/Wif.test.ts +0 -23
  59. package/src/wallet/Wif.ts +2 -148
  60. package/src/wallet/createWallet.ts +0 -53
  61. package/src/wallet/interface.ts +0 -2
  62. package/src/webhook/Webhook.ts +4 -10
  63. package/src/webhook/index.ts +0 -1
  64. package/src/webhook/interface.ts +0 -1
  65. package/webpack.config.cjs +7 -7
  66. package/dist/module/slp/GsppProvider.d.ts +0 -55
  67. package/dist/module/slp/GsppProvider.d.ts.map +0 -1
  68. package/dist/module/slp/GsppProvider.js +0 -204
  69. package/dist/module/slp/GsppProvider.js.map +0 -1
  70. package/dist/module/slp/SlpDbProvider.d.ts +0 -52
  71. package/dist/module/slp/SlpDbProvider.d.ts.map +0 -1
  72. package/dist/module/slp/SlpDbProvider.js +0 -175
  73. package/dist/module/slp/SlpDbProvider.js.map +0 -1
  74. package/dist/module/slp/SlpDbTemplates.d.ts +0 -313
  75. package/dist/module/slp/SlpDbTemplates.d.ts.map +0 -1
  76. package/dist/module/slp/SlpDbTemplates.js +0 -375
  77. package/dist/module/slp/SlpDbTemplates.js.map +0 -1
  78. package/dist/module/slp/SlpLibAuth.d.ts +0 -210
  79. package/dist/module/slp/SlpLibAuth.d.ts.map +0 -1
  80. package/dist/module/slp/SlpLibAuth.js +0 -451
  81. package/dist/module/slp/SlpLibAuth.js.map +0 -1
  82. package/dist/module/slp/SlpProvider.d.ts +0 -24
  83. package/dist/module/slp/SlpProvider.d.ts.map +0 -1
  84. package/dist/module/slp/SlpProvider.js +0 -29
  85. package/dist/module/slp/SlpProvider.js.map +0 -1
  86. package/dist/module/slp/index.d.ts +0 -6
  87. package/dist/module/slp/index.d.ts.map +0 -1
  88. package/dist/module/slp/index.js +0 -5
  89. package/dist/module/slp/index.js.map +0 -1
  90. package/dist/module/slp/interface.d.ts +0 -114
  91. package/dist/module/slp/interface.d.ts.map +0 -1
  92. package/dist/module/slp/interface.js +0 -7
  93. package/dist/module/slp/interface.js.map +0 -1
  94. package/dist/module/util/bchaddr.d.ts +0 -2
  95. package/dist/module/util/bchaddr.d.ts.map +0 -1
  96. package/dist/module/util/bchaddr.js +0 -16
  97. package/dist/module/util/bchaddr.js.map +0 -1
  98. package/dist/module/wallet/Slp.d.ts +0 -431
  99. package/dist/module/wallet/Slp.d.ts.map +0 -1
  100. package/dist/module/wallet/Slp.js +0 -770
  101. package/dist/module/wallet/Slp.js.map +0 -1
  102. package/dist/module/webhook/WebhookSlp.d.ts +0 -15
  103. package/dist/module/webhook/WebhookSlp.d.ts.map +0 -1
  104. package/dist/module/webhook/WebhookSlp.js +0 -100
  105. package/dist/module/webhook/WebhookSlp.js.map +0 -1
  106. package/src/slp/GsppProvider.test.ts +0 -40
  107. package/src/slp/GsppProvider.ts +0 -329
  108. package/src/slp/SlpDbProvider.test.ts +0 -27
  109. package/src/slp/SlpDbProvider.ts +0 -291
  110. package/src/slp/SlpDbTemplates.ts +0 -400
  111. package/src/slp/SlpLibAuth.test.ts +0 -162
  112. package/src/slp/SlpLibAuth.ts +0 -532
  113. package/src/slp/SlpProvider.ts +0 -100
  114. package/src/slp/index.ts +0 -6
  115. package/src/slp/interface.ts +0 -128
  116. package/src/util/bchaddr.test.ts +0 -27
  117. package/src/util/bchaddr.ts +0 -27
  118. package/src/wallet/Slp.test.headless.js +0 -120
  119. package/src/wallet/Slp.test.ts +0 -1000
  120. package/src/wallet/Slp.ts +0 -1014
  121. package/src/webhook/WebhookSlp.test.ts +0 -288
  122. package/src/webhook/WebhookSlp.ts +0 -123
@@ -1,162 +0,0 @@
1
- import { binToHex } from "@bitauth/libauth";
2
- import { parseSLP } from "slp-parser";
3
- import { DUST_UTXO_THRESHOLD } from "../constant";
4
- import {
5
- SlpGetGenesisOutputs,
6
- SlpGetMintOutputs,
7
- SlpGetSendOutputs,
8
- } from "../slp/SlpLibAuth";
9
- import {
10
- SlpGenesisOptions,
11
- SlpSendRequest,
12
- SlpTokenType,
13
- } from "../slp/interface";
14
- import { RegTestWallet } from "../wallet/Wif";
15
- import { SlpUtxoI } from "./interface";
16
- import BigNumber from "bignumber.js";
17
-
18
- test.skip("Test SLP genesis txo bytecode per SLP Spec", async () => {
19
- const wallet = await RegTestWallet.newRandom();
20
-
21
- const genesisOptions: SlpGenesisOptions = {
22
- name: "Tether Ltd. US dollar backed tokens",
23
- ticker: "USDT",
24
- decimals: 8,
25
- initialAmount: 100000000,
26
- documentUrl:
27
- "https://tether.to/wp-content/uploads/2016/06/TetherWhitePaper.pdf",
28
- documentHash:
29
- "db4451f11eda33950670aaf59e704da90117ff7057283b032cfaec7779313916",
30
- tokenReceiverSlpAddr: wallet.slp.slpaddr,
31
- batonReceiverSlpAddr: wallet.slp.slpaddr,
32
- };
33
-
34
- const result = await SlpGetGenesisOutputs(genesisOptions);
35
- const genesisTxoBytecode = result.SlpOutputs[0].lockingBytecode;
36
-
37
- const hex = binToHex(genesisTxoBytecode);
38
- expect(hex).toBe(
39
- "6a04534c500001010747454e45534953045553445423546574686572204c74642e20555320646f6c6c6172206261636b656420746f6b656e734168747470733a2f2f7465746865722e746f2f77702d636f6e74656e742f75706c6f6164732f323031362f30362f546574686572576869746550617065722e70646620db4451f11eda33950670aaf59e704da90117ff7057283b032cfaec77793139160108010208002386f26fc10000"
40
- );
41
-
42
- parseSLP(Buffer.from(hex, "hex"));
43
- });
44
-
45
- test("Test SLP genesis txo bytecode with empty strings", async () => {
46
- const wallet = await RegTestWallet.newRandom();
47
-
48
- const genesisOptions: SlpGenesisOptions = {
49
- name: "",
50
- ticker: "",
51
- decimals: 5,
52
- initialAmount: 1000,
53
- documentUrl: "",
54
- documentHash: "",
55
- tokenReceiverSlpAddr: wallet.slp.slpaddr,
56
- batonReceiverSlpAddr: wallet.slp.slpaddr,
57
- };
58
-
59
- const result = await SlpGetGenesisOutputs(genesisOptions);
60
- const genesisTxoBytecode = result.SlpOutputs[0].lockingBytecode;
61
-
62
- const hex = binToHex(genesisTxoBytecode);
63
- expect(hex).toBe(
64
- "6a04534c500001010747454e455349534c004c004c004c0001050102080000000005f5e100"
65
- );
66
-
67
- parseSLP(Buffer.from(hex, "hex"));
68
- });
69
-
70
- test("Test SLP genesis txo bytecode with utf strings", async () => {
71
- const wallet = await RegTestWallet.newRandom();
72
-
73
- const genesisOptions: SlpGenesisOptions = {
74
- name: "Music 🎵",
75
- ticker: "🎵",
76
- decimals: 0,
77
- initialAmount: 100000,
78
- documentUrl: "http://tiny.cc/gcmzcz",
79
- documentHash: "",
80
- tokenReceiverSlpAddr: wallet.slp.slpaddr,
81
- batonReceiverSlpAddr: wallet.slp.slpaddr,
82
- };
83
-
84
- const result = await SlpGetGenesisOutputs(genesisOptions);
85
- const genesisTxoBytecode = result.SlpOutputs[0].lockingBytecode;
86
-
87
- const hex = binToHex(genesisTxoBytecode);
88
- expect(hex).toBe(
89
- "6a04534c500001010747454e4553495304f09f8eb50a4d7573696320f09f8eb515687474703a2f2f74696e792e63632f67636d7a637a4c00010001020800000000000186a0"
90
- );
91
-
92
- parseSLP(Buffer.from(hex, "hex"));
93
- });
94
-
95
- test("Test SLP send txo bytecode per SLP Spec", async () => {
96
- const wallet = await RegTestWallet.newRandom();
97
- const fundingSlpUtxo: SlpUtxoI = {
98
- value: new BigNumber(100000000),
99
- decimals: 8,
100
- txid: "",
101
- vout: 1,
102
- satoshis: DUST_UTXO_THRESHOLD,
103
- ticker: "USDT",
104
- tokenId: "550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35",
105
- type: SlpTokenType.Type1,
106
- isBaton: false,
107
- };
108
- const sendRequest: SlpSendRequest = {
109
- slpaddr: wallet.slp.slpaddr,
110
- value: 1000000,
111
- tokenId: "550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35",
112
- };
113
-
114
- const result = await SlpGetSendOutputs(
115
- wallet.slp.slpaddr,
116
- [fundingSlpUtxo],
117
- [sendRequest]
118
- );
119
- const sendTxoBytecode = result.SlpOutputs[0].lockingBytecode;
120
-
121
- const hex = binToHex(sendTxoBytecode);
122
- expect(hex).toBe(
123
- "6a04534c500001010453454e4420550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b350800005af3107a40000800232bff5f46c000"
124
- );
125
-
126
- parseSLP(Buffer.from(hex, "hex"));
127
- });
128
-
129
- test("Test SLP mint txo bytecode per SLP Spec", async () => {
130
- const wallet = await RegTestWallet.newRandom();
131
- const batonSlpUtxo: SlpUtxoI = {
132
- value: new BigNumber(100000000),
133
- decimals: 8,
134
- txid: "",
135
- vout: 1,
136
- satoshis: DUST_UTXO_THRESHOLD,
137
- ticker: "USDT",
138
- tokenId: "550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35",
139
- type: 0x01,
140
- isBaton: false,
141
- };
142
-
143
- const result = await SlpGetMintOutputs(
144
- {
145
- tokenId:
146
- "550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35",
147
- value: 100000000,
148
- tokenReceiverSlpAddr: wallet.slp.slpaddr,
149
- batonReceiverSlpAddr: wallet.slp.slpaddr,
150
- endBaton: false,
151
- },
152
- [batonSlpUtxo]
153
- );
154
- const mintTxoBytecode = result.SlpOutputs[0].lockingBytecode;
155
-
156
- const hex = binToHex(mintTxoBytecode);
157
- expect(hex).toBe(
158
- "6a04534c50000101044d494e5420550d19eb820e616a54b8a73372c4420b5a0567d8dc00f613b71c5234dc884b35010208002386f26fc10000"
159
- );
160
-
161
- parseSLP(Buffer.from(hex, "hex"));
162
- });
@@ -1,532 +0,0 @@
1
- import {
2
- authenticationTemplateToCompilerBCH,
3
- bigIntToBinUint64LE,
4
- binToHex,
5
- hexToBin,
6
- importAuthenticationTemplate,
7
- Output,
8
- utf8ToBin,
9
- } from "@bitauth/libauth";
10
- import { parseSLP } from "slp-parser";
11
-
12
- import { SendRequest } from "../wallet/model.js";
13
- import {
14
- SlpGenesisOptions,
15
- SlpMintOptions,
16
- SlpSendRequest,
17
- SlpTokenType,
18
- SlpUtxoI,
19
- } from "../slp/interface.js";
20
-
21
- import BigNumber from "bignumber.js";
22
- import { DUST_UTXO_THRESHOLD } from "../constant.js";
23
- import { UnitEnum } from "../enum.js";
24
- import { isValidAddress, toCashAddress } from "../util/bchaddr.js";
25
-
26
- export const bigIntToBinUint64BE = (value) => {
27
- return bigIntToBinUint64LE(value).reverse();
28
- };
29
-
30
- const stringToBin = (value, hex = false) => {
31
- if (!value) return Uint8Array.from([0x4c, 0x00]);
32
-
33
- if (hex) return Uint8Array.from([...[value.length / 2], ...hexToBin(value)]);
34
-
35
- const length = new TextEncoder().encode(value).length;
36
- return Uint8Array.from([...[length], ...utf8ToBin(value)]);
37
- };
38
-
39
- const supportedTokenTypes = [
40
- SlpTokenType.Type1,
41
- SlpTokenType.NftParent,
42
- SlpTokenType.NftChild,
43
- ];
44
-
45
- export const SlpGetGenesisOutputs = async (options: SlpGenesisOptions) => {
46
- if (!isValidAddress(options.tokenReceiverSlpAddr!)) {
47
- throw new Error(
48
- `Invalid tokenReceiverSlpAddr ${options.tokenReceiverSlpAddr}`
49
- );
50
- }
51
-
52
- if (!isValidAddress(options.batonReceiverSlpAddr!)) {
53
- throw new Error(
54
- `Invalid batonReceiverSlpAddr ${options.batonReceiverSlpAddr}`
55
- );
56
- }
57
-
58
- if (!options.type) {
59
- options.type = SlpTokenType.Type1;
60
- }
61
-
62
- if (!supportedTokenTypes.includes(options.type)) {
63
- throw new Error(`Unsupported token type ${options.type}`);
64
- }
65
-
66
- // explicitly convert initial amount to bignumber
67
- options.initialAmount = new BigNumber(options.initialAmount);
68
- if (options.initialAmount.isLessThanOrEqualTo(0)) {
69
- throw Error("Initial genesis token amount should be greater than zero");
70
- }
71
-
72
- if (options.decimals < 0 || options.decimals > 9) {
73
- throw new Error("Genesis allows decimal places between 0");
74
- }
75
- const addrs = options.endBaton
76
- ? [options.tokenReceiverSlpAddr]
77
- : [options.tokenReceiverSlpAddr, options.batonReceiverSlpAddr];
78
- const bchSendRequests = addrs.map(
79
- (val) =>
80
- new SendRequest({
81
- cashaddr: toCashAddress(val!),
82
- value: DUST_UTXO_THRESHOLD,
83
- unit: UnitEnum.SAT,
84
- })
85
- );
86
-
87
- const template = importAuthenticationTemplate(SlpTxoTemplate);
88
- if (typeof template === "string") {
89
- throw new Error("Transaction template error");
90
- }
91
- const compiler = await authenticationTemplateToCompilerBCH(template);
92
-
93
- const rawTokenAmount = BigInt(
94
- options.initialAmount.shiftedBy(options.decimals)
95
- );
96
-
97
- const batonVout = options.endBaton ? [0x4c, 0x00] : [0x01, 0x02];
98
-
99
- let genesisTxoBytecode = compiler.generateBytecode({
100
- scriptId: "genesis_lock",
101
- data: {
102
- bytecode: {
103
- g_token_type: Uint8Array.from([...[0x01], ...[options.type]]),
104
- g_token_ticker: stringToBin(options.ticker),
105
- g_token_name: stringToBin(options.name),
106
- g_token_document_url: stringToBin(options.documentUrl),
107
- g_token_document_hash: stringToBin(options.documentHash, true),
108
- g_decimals: Uint8Array.from([...[0x01], ...[options.decimals]]),
109
- g_mint_baton_vout: Uint8Array.from(batonVout),
110
- g_initial_token_mint_quantity: Uint8Array.from([
111
- ...[0x08],
112
- ...bigIntToBinUint64BE(rawTokenAmount),
113
- ]),
114
- },
115
- },
116
- });
117
- if (!genesisTxoBytecode.success) {
118
- throw new Error(genesisTxoBytecode.errors.map((e) => e.error).join("\n"));
119
- }
120
-
121
- return {
122
- SlpOutputs: [
123
- {
124
- lockingBytecode: genesisTxoBytecode.bytecode,
125
- valueSatoshis: 0n,
126
- } as Output,
127
- ],
128
- FundingSlpUtxos: [],
129
- BchSendRequests: bchSendRequests,
130
- };
131
- };
132
-
133
- export const SlpGetMintOutputs = async (
134
- options: SlpMintOptions,
135
- slpBatonUtxos: SlpUtxoI[]
136
- ) => {
137
- if (!isValidAddress(options.tokenReceiverSlpAddr!)) {
138
- throw new Error(
139
- `Invalid tokenReceiverSlpAddr ${options.tokenReceiverSlpAddr}`
140
- );
141
- }
142
-
143
- if (!isValidAddress(options.batonReceiverSlpAddr!)) {
144
- throw new Error(
145
- `Invalid batonReceiverSlpAddr ${options.batonReceiverSlpAddr}`
146
- );
147
- }
148
-
149
- const tokenType = slpBatonUtxos[0].type;
150
-
151
- if (!supportedTokenTypes.includes(tokenType)) {
152
- throw new Error(`Unsupported token type ${tokenType}`);
153
- }
154
-
155
- const addrs = options.endBaton
156
- ? [options.tokenReceiverSlpAddr]
157
- : [options.tokenReceiverSlpAddr, options.batonReceiverSlpAddr];
158
- const bchSendRequests = addrs.map(
159
- (val) =>
160
- new SendRequest({
161
- cashaddr: toCashAddress(val!),
162
- value: DUST_UTXO_THRESHOLD,
163
- unit: UnitEnum.SAT,
164
- })
165
- );
166
-
167
- const template = importAuthenticationTemplate(SlpTxoTemplate);
168
- if (typeof template === "string") {
169
- throw new Error("Transaction template error");
170
- }
171
- const compiler = await authenticationTemplateToCompilerBCH(template);
172
- const decimals = slpBatonUtxos[0].decimals;
173
- const amount = new BigNumber(options.value).shiftedBy(decimals);
174
-
175
- const batonVout = options.endBaton ? [0x4c, 0x00] : [0x01, 0x02];
176
-
177
- let mintTxoBytecode = compiler.generateBytecode({
178
- scriptId: "mint_lock",
179
- data: {
180
- bytecode: {
181
- m_token_type: Uint8Array.from([...[0x01], ...[tokenType]]),
182
- m_token_id: hexToBin(options.tokenId),
183
- m_mint_baton_vout: Uint8Array.from(batonVout),
184
- m_additional_token_quantity: Uint8Array.from([
185
- ...[0x08],
186
- ...bigIntToBinUint64BE(BigInt(amount.toString())),
187
- ]),
188
- },
189
- },
190
- });
191
- if (!mintTxoBytecode.success) {
192
- throw new Error(mintTxoBytecode.errors.map((e) => e.error).join("\n"));
193
- }
194
-
195
- return {
196
- SlpOutputs: [
197
- {
198
- lockingBytecode: mintTxoBytecode.bytecode,
199
- valueSatoshis: 0n,
200
- } as Output,
201
- ],
202
- FundingSlpUtxos: slpBatonUtxos,
203
- BchSendRequests: bchSendRequests,
204
- };
205
- };
206
-
207
- export const SlpGetSendOutputs = async (
208
- changeSlpaddr: string,
209
- slpUtxos: SlpUtxoI[],
210
- sendRequests: SlpSendRequest[]
211
- ) => {
212
- if (!isValidAddress(changeSlpaddr!)) {
213
- throw new Error(`Invalid changeSlpaddr ${changeSlpaddr}`);
214
- }
215
-
216
- if (!slpUtxos.length) {
217
- throw new Error("No available tokens to spend");
218
- }
219
-
220
- const decimals = slpUtxos[0].decimals;
221
- const tokenId = slpUtxos[0].tokenId;
222
- const tokenType = slpUtxos[0].type;
223
-
224
- if (!supportedTokenTypes.includes(tokenType)) {
225
- throw new Error(`Unsupported token type ${tokenType}`);
226
- }
227
-
228
- // sort inputs in ascending order to eliminate the unnecessary splitting
229
- // and to prefer the consolidation of small inputs
230
- slpUtxos = slpUtxos.sort((a, b) => a.value.comparedTo(b.value));
231
-
232
- const slpAvailableAmount: BigNumber = slpUtxos
233
- .map((val) => new BigNumber(val.value))
234
- .reduce((a, b) => BigNumber.sum(a, b), new BigNumber(0));
235
- const slpSpendAmount: BigNumber = sendRequests
236
- .map((val) => new BigNumber(val.value))
237
- .reduce((a, b) => BigNumber.sum(a, b), new BigNumber(0));
238
-
239
- if (slpSpendAmount.isLessThanOrEqualTo(0)) {
240
- throw new Error("Refusing to spend 0 tokens");
241
- }
242
-
243
- if (slpSpendAmount.isGreaterThan(slpAvailableAmount)) {
244
- throw new Error("Not enough tokens to spend");
245
- }
246
-
247
- let fundingSlpUtxos: SlpUtxoI[] = [];
248
- let totalInputTokens = new BigNumber(0);
249
- for (let slputxo of slpUtxos) {
250
- const amountTooLow = totalInputTokens.isLessThan(slpSpendAmount);
251
- if (amountTooLow) {
252
- totalInputTokens = totalInputTokens.plus(slputxo.value);
253
- fundingSlpUtxos.push(slputxo);
254
- } else {
255
- break;
256
- }
257
- }
258
-
259
- const template = importAuthenticationTemplate(SlpTxoTemplate);
260
- if (typeof template === "string") {
261
- throw new Error("Transaction template error");
262
- }
263
- const compiler = await authenticationTemplateToCompilerBCH(template);
264
-
265
- const change = totalInputTokens.minus(slpSpendAmount);
266
- let values = sendRequests.map((val) => new BigNumber(val.value));
267
- if (change.isGreaterThan(new BigNumber(0))) {
268
- values.push(change);
269
- sendRequests.push({
270
- slpaddr: changeSlpaddr,
271
- tokenId: tokenId,
272
- value: new BigNumber(0),
273
- });
274
- }
275
-
276
- const bchSendRequests = sendRequests.map(
277
- (val) =>
278
- new SendRequest({
279
- cashaddr: toCashAddress(val.slpaddr),
280
- value: DUST_UTXO_THRESHOLD,
281
- unit: UnitEnum.SAT,
282
- })
283
- );
284
-
285
- values = values.map((val) => val.shiftedBy(decimals));
286
-
287
- let result: Uint8Array = new Uint8Array();
288
- for (const val of values) {
289
- result = new Uint8Array([
290
- ...result,
291
- ...[0x08],
292
- ...bigIntToBinUint64BE(BigInt(val.toString())),
293
- ]);
294
- }
295
-
296
- let sendTxoBytecode = compiler.generateBytecode({
297
- scriptId: "send_lock",
298
- data: {
299
- bytecode: {
300
- s_token_type: Uint8Array.from([...[0x01], ...[tokenType]]),
301
- s_token_id: hexToBin(tokenId!),
302
- s_token_output_quantities: result,
303
- },
304
- },
305
- });
306
- if (!sendTxoBytecode.success) {
307
- throw new Error(sendTxoBytecode.errors.map((e) => e.error).join("\n"));
308
- }
309
-
310
- // enforce checking
311
- parseSLP(Buffer.from(binToHex(sendTxoBytecode.bytecode), "hex"));
312
-
313
- return {
314
- SlpOutputs: [
315
- {
316
- lockingBytecode: sendTxoBytecode.bytecode,
317
- valueSatoshis: 0n,
318
- } as Output,
319
- ],
320
- FundingSlpUtxos: fundingSlpUtxos,
321
- BchSendRequests: bchSendRequests,
322
- };
323
- };
324
-
325
- // prettier-ignore
326
- export const SlpTxoTemplate = {
327
- "$schema": "https://bitauth.com/schemas/authentication-template-v0.schema.json",
328
- "description": "SLP Token transaction output templates",
329
- "name": "SLP",
330
- "entities": {
331
- "genesis_variables": {
332
- "description": "Variables used in genesis template.",
333
- "name": "Genesis_Variables",
334
- "scripts": [
335
- "genesis_lock",
336
- "genesis_unlock"
337
- ],
338
- "variables": {
339
- "g_token_type": {
340
- "description": "1 to 2 byte integer",
341
- "name": "token_type",
342
- "type": "AddressData"
343
- },
344
- "g_token_ticker": {
345
- "description": "0 to ∞ bytes, suggested utf-8",
346
- "name": "token_ticker",
347
- "type": "AddressData"
348
- },
349
- "g_token_name": {
350
- "description": "0 to ∞ bytes, suggested utf-8",
351
- "name": "token_name",
352
- "type": "AddressData"
353
- },
354
- "g_token_document_url": {
355
- "description": "0 to ∞ bytes, suggested ascii",
356
- "name": "token_document_url",
357
- "type": "AddressData"
358
- },
359
- "g_token_document_hash": {
360
- "description": "0 bytes or 32 bytes",
361
- "name": "token_document_hash",
362
- "type": "AddressData"
363
- },
364
- "g_decimals": {
365
- "description": "1 byte in range 0x00-0x09",
366
- "name": "decimals",
367
- "type": "AddressData"
368
- },
369
- "g_mint_baton_vout": {
370
- "description": "0 bytes, or 1 byte in range 0x02-0xff",
371
- "name": "mint_baton_vout",
372
- "type": "AddressData"
373
- },
374
- "g_initial_token_mint_quantity": {
375
- "description": "8 byte integer",
376
- "name": "initial_token_mint_quantity",
377
- "type": "AddressData"
378
- }
379
- }
380
- },
381
- "send_variables": {
382
- "description": "",
383
- "name": "Send_Variables",
384
- "scripts": [
385
- "send_lock",
386
- "send_unlock"
387
- ],
388
- "variables": {
389
- "s_token_type": {
390
- "description": "1 to 2 byte integer",
391
- "name": "token_type",
392
- "type": "AddressData"
393
- },
394
- "s_token_id": {
395
- "description": "Token Id, genesis transaction hex",
396
- "name": "Token_Id",
397
- "type": "AddressData"
398
- },
399
- "s_token_output_quantities": {
400
- "description": "N 8 byte integer token amounts (up to 19). At least one is required. Each one is a push.\nN BCH transaction outputs should be specified",
401
- "name": "Token Output Quantities",
402
- "type": "AddressData"
403
- }
404
- }
405
- },
406
- "mint_variables": {
407
- "description": "",
408
- "name": "Mint_Variables",
409
- "scripts": [
410
- "mint_lock",
411
- "mint_unlock"
412
- ],
413
- "variables": {
414
- "m_token_type": {
415
- "description": "1 to 2 byte integer",
416
- "name": "token_type",
417
- "type": "AddressData"
418
- },
419
- "m_token_id": {
420
- "description": "Token Id, genesis transaction hex",
421
- "name": "Token_Id",
422
- "type": "AddressData"
423
- },
424
- "m_mint_baton_vout": {
425
- "description": "0 bytes, or 1 byte in range 0x02-0xff",
426
- "name": "mint_baton_vout",
427
- "type": "AddressData"
428
- },
429
- "m_additional_token_quantity": {
430
- "description": "Amount of tokens to mint, 8 byte integer",
431
- "name": "Additinial token quantity",
432
- "type": "AddressData"
433
- }
434
- }
435
- }
436
- },
437
- "scenarios": {
438
- "genesis": {
439
- "data": {
440
- "bytecode": {
441
- "g_token_type": "0x01",
442
- "g_token_ticker": "0x00",
443
- "g_token_name": "0x00",
444
- "g_token_document_url": "0x00",
445
- "g_token_document_hash": "",
446
- "g_decimals": "0x09",
447
- "g_mint_baton_vout": "0x02",
448
- "g_initial_token_mint_quantity": "0x0102030405060708"
449
- }
450
- },
451
- "description": "Genesis",
452
- "name": "Genesis",
453
- "transaction": {
454
- "locktime": 100
455
- }
456
- },
457
- "send": {
458
- "data": {
459
- "bytecode": {
460
- "s_token_type": "0x01",
461
- "s_token_id": "0x0000000000000000'0000000000000000'0000000000000000'0000000000000000'",
462
- "s_token_output_quantities": "0x0000000000000000"
463
- }
464
- },
465
- "description": "Send",
466
- "name": "Send",
467
- "transaction": {
468
- "locktime": 100
469
- }
470
- },
471
- "mint": {
472
- "data": {
473
- "bytecode": {
474
- "m_token_type": "0x01",
475
- "m_token_id": "0x0000000000000000'0000000000000000'0000000000000000'0000000000000000'",
476
- "m_mint_baton_vout": "0x00",
477
- "m_additional_token_quantity": "0x0000000000000000"
478
- }
479
- },
480
- "description": "Mint",
481
- "name": "Mint",
482
- "transaction": {
483
- "locktime": 100
484
- }
485
- }
486
- },
487
- "scripts": {
488
- "genesis_unlock": {
489
- "fails": [
490
- "genesis"
491
- ],
492
- "name": "Genesis Unlock",
493
- "script": "// unlock script is required, so we leave it empty",
494
- "unlocks": "genesis_lock"
495
- },
496
- "send_unlock": {
497
- "fails": [
498
- "send"
499
- ],
500
- "name": "Send Unlock",
501
- "script": "",
502
- "unlocks": "send_lock"
503
- },
504
- "mint_unlock": {
505
- "fails": [
506
- "mint"
507
- ],
508
- "name": "Mint Unlock",
509
- "script": "",
510
- "unlocks": "mint_lock"
511
- },
512
- "genesis_lock": {
513
- "lockingType": "standard",
514
- "name": "Genesis",
515
- "script": "OP_RETURN <'SLP'0x00> g_token_type <'GENESIS'> g_token_ticker g_token_name g_token_document_url g_token_document_hash g_decimals g_mint_baton_vout g_initial_token_mint_quantity"
516
- },
517
- "send_lock": {
518
- "lockingType": "standard",
519
- "name": "Send",
520
- "script": "OP_RETURN <'SLP'0x00> s_token_type <'SEND'> <s_token_id> s_token_output_quantities"
521
- },
522
- "mint_lock": {
523
- "lockingType": "standard",
524
- "name": "Mint",
525
- "script": "OP_RETURN <'SLP'0x00> m_token_type <'MINT'> <m_token_id> m_mint_baton_vout m_additional_token_quantity"
526
- }
527
- },
528
- "supported": [
529
- "BCH_2020_05"
530
- ],
531
- "version": 0
532
- }