@teleportdao/bitcoin 1.6.1 → 1.7.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 (129) hide show
  1. package/.tmp/check.ts +101 -0
  2. package/.tmp/psbt/sign-transaction.ts +121 -0
  3. package/.tmp/rbf.ts +45 -0
  4. package/dist/bitcoin-interface-ordinal.d.ts +109 -0
  5. package/dist/bitcoin-interface-ordinal.d.ts.map +1 -0
  6. package/dist/bitcoin-interface-ordinal.js +141 -0
  7. package/dist/bitcoin-interface-ordinal.js.map +1 -0
  8. package/dist/bitcoin-interface-teleswap.d.ts +148 -0
  9. package/dist/bitcoin-interface-teleswap.d.ts.map +1 -0
  10. package/dist/bitcoin-interface-teleswap.js +179 -0
  11. package/dist/bitcoin-interface-teleswap.js.map +1 -0
  12. package/dist/bitcoin-interface-utils.d.ts.map +1 -1
  13. package/dist/bitcoin-interface-utils.js.map +1 -1
  14. package/dist/bitcoin-interface.d.ts +45 -333
  15. package/dist/bitcoin-interface.d.ts.map +1 -1
  16. package/dist/bitcoin-interface.js +68 -202
  17. package/dist/bitcoin-interface.js.map +1 -1
  18. package/dist/bitcoin-utils.d.ts +12 -59
  19. package/dist/bitcoin-utils.d.ts.map +1 -1
  20. package/dist/bitcoin-utils.js +61 -61
  21. package/dist/bitcoin-utils.js.map +1 -1
  22. package/dist/{bitcoin-base.d.ts → bitcoin-wallet-base.d.ts} +9 -9
  23. package/dist/bitcoin-wallet-base.d.ts.map +1 -0
  24. package/dist/{bitcoin-base.js → bitcoin-wallet-base.js} +15 -14
  25. package/dist/bitcoin-wallet-base.js.map +1 -0
  26. package/dist/helper/brc20-helper.d.ts +43 -0
  27. package/dist/helper/brc20-helper.d.ts.map +1 -0
  28. package/dist/helper/brc20-helper.js +129 -0
  29. package/dist/helper/brc20-helper.js.map +1 -0
  30. package/dist/helper/index.d.ts +4 -0
  31. package/dist/helper/index.d.ts.map +1 -0
  32. package/dist/helper/index.js +30 -0
  33. package/dist/helper/index.js.map +1 -0
  34. package/dist/helper/ordinal-helper.d.ts +13 -0
  35. package/dist/helper/ordinal-helper.d.ts.map +1 -0
  36. package/dist/helper/ordinal-helper.js +127 -0
  37. package/dist/helper/ordinal-helper.js.map +1 -0
  38. package/dist/helper/teleswap-helper.d.ts +84 -0
  39. package/dist/helper/teleswap-helper.d.ts.map +1 -0
  40. package/dist/helper/teleswap-helper.js +181 -0
  41. package/dist/helper/teleswap-helper.js.map +1 -0
  42. package/dist/index.d.ts +8 -3
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +8 -3
  45. package/dist/index.js.map +1 -1
  46. package/dist/ordinal-wallet.d.ts +536 -0
  47. package/dist/ordinal-wallet.d.ts.map +1 -0
  48. package/dist/ordinal-wallet.js +448 -0
  49. package/dist/ordinal-wallet.js.map +1 -0
  50. package/dist/sign/sign-transaction.d.ts +2 -4
  51. package/dist/sign/sign-transaction.d.ts.map +1 -1
  52. package/dist/sign/sign-transaction.js +26 -22
  53. package/dist/sign/sign-transaction.js.map +1 -1
  54. package/dist/teleswap-wallet.d.ts +54 -0
  55. package/dist/teleswap-wallet.d.ts.map +1 -0
  56. package/dist/teleswap-wallet.js +87 -0
  57. package/dist/teleswap-wallet.js.map +1 -0
  58. package/dist/transaction-builder/bitcoin-transaction-builder.d.ts +2 -20
  59. package/dist/transaction-builder/bitcoin-transaction-builder.d.ts.map +1 -1
  60. package/dist/transaction-builder/bitcoin-transaction-builder.js +5 -4
  61. package/dist/transaction-builder/bitcoin-transaction-builder.js.map +1 -1
  62. package/dist/transaction-builder/index.d.ts +2 -1
  63. package/dist/transaction-builder/index.d.ts.map +1 -1
  64. package/dist/transaction-builder/index.js +2 -6
  65. package/dist/transaction-builder/index.js.map +1 -1
  66. package/dist/transaction-builder/ordinal-transaction-builder.d.ts +63 -0
  67. package/dist/transaction-builder/ordinal-transaction-builder.d.ts.map +1 -0
  68. package/dist/transaction-builder/ordinal-transaction-builder.js +131 -0
  69. package/dist/transaction-builder/ordinal-transaction-builder.js.map +1 -0
  70. package/dist/transaction-builder/transaction-builder.d.ts +10 -7
  71. package/dist/transaction-builder/transaction-builder.d.ts.map +1 -1
  72. package/dist/transaction-builder/transaction-builder.js +18 -9
  73. package/dist/transaction-builder/transaction-builder.js.map +1 -1
  74. package/dist/type.d.ts +43 -0
  75. package/dist/type.d.ts.map +1 -0
  76. package/dist/type.js +3 -0
  77. package/dist/type.js.map +1 -0
  78. package/dist/utils/tools.d.ts +4 -4
  79. package/dist/utils/tools.d.ts.map +1 -1
  80. package/dist/utils/tools.js +8 -5
  81. package/dist/utils/tools.js.map +1 -1
  82. package/package.json +6 -9
  83. package/src/bitcoin-interface-ordinal.ts +181 -0
  84. package/src/bitcoin-interface-teleswap.ts +255 -0
  85. package/src/bitcoin-interface-utils.ts +1 -1
  86. package/src/bitcoin-interface.ts +99 -303
  87. package/src/bitcoin-utils.ts +65 -90
  88. package/src/{bitcoin-base.ts → bitcoin-wallet-base.ts} +24 -19
  89. package/src/helper/brc20-helper.ts +181 -0
  90. package/src/helper/index.ts +3 -0
  91. package/src/helper/ordinal-helper.ts +118 -0
  92. package/src/helper/teleswap-helper.ts +300 -0
  93. package/src/index.ts +11 -3
  94. package/src/ordinal-wallet.ts +738 -0
  95. package/src/sign/sign-transaction.ts +42 -33
  96. package/src/teleswap-wallet.ts +155 -0
  97. package/src/transaction-builder/bitcoin-transaction-builder.ts +7 -24
  98. package/src/transaction-builder/index.ts +2 -1
  99. package/src/transaction-builder/ordinal-transaction-builder.ts +147 -0
  100. package/src/transaction-builder/transaction-builder.ts +33 -15
  101. package/src/type.ts +43 -0
  102. package/src/utils/tools.ts +17 -11
  103. package/tsconfig.json +1 -2
  104. package/dist/bitcoin-base.d.ts.map +0 -1
  105. package/dist/bitcoin-base.js.map +0 -1
  106. package/dist/bitcoin-utils-2.d.ts +0 -2
  107. package/dist/bitcoin-utils-2.d.ts.map +0 -1
  108. package/dist/bitcoin-utils-2.js +0 -13
  109. package/dist/bitcoin-utils-2.js.map +0 -1
  110. package/dist/bundle.js +0 -17
  111. package/dist/helper/burn-request-helper.d.ts +0 -7
  112. package/dist/helper/burn-request-helper.d.ts.map +0 -1
  113. package/dist/helper/burn-request-helper.js +0 -26
  114. package/dist/helper/burn-request-helper.js.map +0 -1
  115. package/dist/helper/teleport-request-helper.d.ts +0 -47
  116. package/dist/helper/teleport-request-helper.d.ts.map +0 -1
  117. package/dist/helper/teleport-request-helper.js +0 -146
  118. package/dist/helper/teleport-request-helper.js.map +0 -1
  119. package/dist/mempool-space.d.ts +0 -69
  120. package/dist/mempool-space.d.ts.map +0 -1
  121. package/dist/mempool-space.js +0 -266
  122. package/dist/mempool-space.js.map +0 -1
  123. package/dist/teleport-dao-payments.d.ts +0 -76
  124. package/dist/teleport-dao-payments.d.ts.map +0 -1
  125. package/dist/teleport-dao-payments.js +0 -217
  126. package/dist/teleport-dao-payments.js.map +0 -1
  127. package/src/helper/burn-request-helper.js +0 -27
  128. package/src/helper/teleport-request-helper.js +0 -181
  129. package/src/teleport-dao-payments.ts +0 -347
@@ -1,16 +1,18 @@
1
- import networks from "./utils/networks"
2
-
1
+ /* eslint-disable @typescript-eslint/no-var-requires */
3
2
  import * as bip39 from "bip39"
4
3
  import BIP32Factory from "bip32"
5
4
  import * as ecc from "@bitcoinerlab/secp256k1"
6
5
  import * as bitcoin from "bitcoinjs-lib"
7
6
  import * as bitcoinEcPair from "bitcoinjs-ecpair"
7
+ import networks from "./utils/networks"
8
+ import { Transaction } from "./type"
8
9
 
9
10
  const bip32 = BIP32Factory(ecc)
10
- const ECPair = bitcoinEcPair.ECPair
11
+ const { ECPair } = bitcoinEcPair
11
12
 
12
13
  bitcoin.initEccLib(ecc)
13
- let varUnit = require("varuint-bitcoin")
14
+
15
+ const varUnit = require("varuint-bitcoin")
14
16
  const fastRoot = require("merkle-lib/fastRoot")
15
17
  const merkle = require("merkle-lib")
16
18
  const merkleProof = require("merkle-lib/proof")
@@ -201,12 +203,66 @@ export function parseBlockHeader(headerHex: string) {
201
203
  }
202
204
  }
203
205
 
206
+ export function getAddressType(address: string, network = bitcoin.networks.bitcoin) {
207
+ if (address.startsWith(`${network.bech32}1p`)) {
208
+ // todo validate p2tr address
209
+ return "p2tr"
210
+ }
211
+ if (address.startsWith(network.bech32)) {
212
+ bitcoin.address.fromBech32(address)
213
+ return "p2wpkh"
214
+ }
215
+ let base58Data = bitcoin.address.fromBase58Check(address)
216
+ if (base58Data.version === Number(network.scriptHash)) {
217
+ return "p2sh"
218
+ }
219
+ if (base58Data.version === Number(network.pubKeyHash)) {
220
+ return "p2pkh"
221
+ }
222
+
223
+ throw new Error("invalid address")
224
+ }
225
+
226
+ export function createAddressObjectByAddress(address: string, network = bitcoin.networks.bitcoin) {
227
+ let addressType = getAddressType(address, network)
228
+ let addressObject
229
+ switch (addressType) {
230
+ case "p2pkh":
231
+ addressObject = bitcoin.payments.p2pkh({
232
+ address,
233
+ network,
234
+ })
235
+ break
236
+ case "p2wpkh":
237
+ addressObject = bitcoin.payments.p2wpkh({
238
+ address,
239
+ network,
240
+ })
241
+ break
242
+ case "p2sh":
243
+ addressObject = bitcoin.payments.p2sh({
244
+ address,
245
+ network,
246
+ })
247
+ break
248
+ case "p2tr":
249
+ addressObject = bitcoin.payments.p2tr({
250
+ address,
251
+ network,
252
+ })
253
+ break
254
+ default:
255
+ throw new Error("address type is incorrect")
256
+ }
257
+ return { addressObject, addressType }
258
+ }
259
+
204
260
  // used in block parser functions ( newt 2 functions )
205
261
  export function convertBitcoinScriptToAddress(script: Buffer, network = bitcoin.networks.bitcoin) {
206
262
  try {
207
263
  return bitcoin.address.fromOutputScript(script, network)
208
264
  } catch (error) {
209
- return null
265
+ return undefined
210
266
  }
211
267
  }
212
268
 
@@ -250,7 +306,7 @@ export function extractTransactionsAndBlockInfoFromRawBlock(
250
306
  inputTxIds: {
251
307
  txId: string
252
308
  index: number
253
- address?: string
309
+ address: string
254
310
  script?: string
255
311
  value?: number
256
312
  }[] = [],
@@ -274,32 +330,6 @@ export function extractTransactionsAndBlockInfoFromRawBlock(
274
330
 
275
331
  let blockTxIds = block.transactions!.map((tx) => tx.getId())
276
332
 
277
- type Transaction = {
278
- txId: string
279
- version: number
280
- locktime: number
281
- blockNumber: number
282
- blockHash: string
283
- merkleProof: {
284
- intermediateNodes: string
285
- transactionIndex: number
286
- }
287
- vout: {
288
- address: string | null
289
- script: string
290
- value: number
291
- }[]
292
- vin: {
293
- txId: string
294
- index: number
295
- address?: string | null
296
- script?: string | null
297
- value?: number | null
298
- }[]
299
- address: string
300
- addressScript: string
301
- }
302
-
303
333
  let withdrawTxs: Transaction[] = []
304
334
  let depositTxs: Transaction[] = []
305
335
  block.transactions?.forEach((tx) => {
@@ -333,9 +363,9 @@ export function extractTransactionsAndBlockInfoFromRawBlock(
333
363
  return {
334
364
  txId: Buffer.from(vi.hash).reverse().toString("hex"),
335
365
  index: vi.index,
336
- address: viInput?.address || null,
337
- script: viInput?.script || null,
338
- value: viInput?.value || null,
366
+ address: viInput?.address,
367
+ script: viInput?.script,
368
+ value: viInput?.value,
339
369
  }
340
370
  }),
341
371
  address: inputTxAddress,
@@ -359,7 +389,6 @@ export function extractTransactionsAndBlockInfoFromRawBlock(
359
389
  })
360
390
 
361
391
  if (isDeposit && addressIndex >= 0) {
362
- // todo we can optimize this calculation (in following function, merkle tree calculate each times but we can do this once for block)
363
392
  let txMerkleProof = calculateMerkleProof(blockTxIds, txId, merkleRoot)
364
393
  depositTxs.push({
365
394
  txId: tx.getId(),
@@ -412,26 +441,6 @@ function toXOnlyPublicKey(pubKey: Buffer) {
412
441
  return pubKey.length === 32 ? pubKey : pubKey.slice(1, 33)
413
442
  }
414
443
 
415
- export function getAddressType(address: string, network = bitcoin.networks.bitcoin) {
416
- if (address.startsWith(`${network.bech32}1p`)) {
417
- // todo validate p2tr address
418
- return "p2tr"
419
- }
420
- if (address.startsWith(network.bech32)) {
421
- bitcoin.address.fromBech32(address)
422
- return "p2wpkh"
423
- }
424
- let base58Data = bitcoin.address.fromBase58Check(address)
425
- if (base58Data.version === Number(network.scriptHash)) {
426
- return "p2sh"
427
- }
428
- if (base58Data.version === Number(network.pubKeyHash)) {
429
- return "p2pkh"
430
- }
431
-
432
- throw new Error("invalid address")
433
- }
434
-
435
444
  export function createAddressObjectByScript(
436
445
  { addressType, script }: { addressType: string; script: Buffer },
437
446
  network: bitcoin.Network = bitcoin.networks.bitcoin,
@@ -556,40 +565,6 @@ export function createAddressObjectByPublicKey(
556
565
  return addressObject
557
566
  }
558
567
 
559
- export function createAddressObjectByAddress(address: string, network = bitcoin.networks.bitcoin) {
560
- let addressType = getAddressType(address, network)
561
- let addressObject
562
- switch (addressType) {
563
- case "p2pkh":
564
- addressObject = bitcoin.payments.p2pkh({
565
- address,
566
- network,
567
- })
568
- break
569
- case "p2wpkh":
570
- addressObject = bitcoin.payments.p2wpkh({
571
- address,
572
- network,
573
- })
574
- break
575
- case "p2sh":
576
- addressObject = bitcoin.payments.p2sh({
577
- address,
578
- network,
579
- })
580
- break
581
- case "p2tr":
582
- addressObject = bitcoin.payments.p2tr({
583
- address,
584
- network,
585
- })
586
- break
587
- default:
588
- throw new Error("address type is incorrect")
589
- }
590
- return { addressObject, addressType }
591
- }
592
-
593
568
  export function publicKeyConvertor(publicKeyHex: string, compressed = true) {
594
569
  let pubkey = ECPair.fromPublicKey(Buffer.from(publicKeyHex, "hex"), {
595
570
  compressed,
@@ -1,23 +1,21 @@
1
- import TransactionBuilder, {
2
- BitcoinConnectionInfo,
3
- } from "./transaction-builder/bitcoin-transaction-builder"
1
+ import * as bip39 from "bip39"
2
+ import { hdWalletPath } from "@teleportdao/configs"
3
+ import { Network, Payment } from "bitcoinjs-lib"
4
+ import BIP32Factory from "bip32"
5
+ import ecc from "@bitcoinerlab/secp256k1"
6
+ import { BitcoinTransactionBuilder } from "./transaction-builder"
7
+ import type { BitcoinConnectionInfo } from "./type"
4
8
 
5
9
  import type { ExtendedUtxo, SignerInfo, Target } from "./transaction-builder/transaction-builder"
6
10
  import BitcoinSign from "./sign/sign-transaction"
7
11
 
8
- import * as bip39 from "bip39"
9
- import { hdWalletPath } from "@teleportdao/configs"
10
12
  import { getPubKeyFromPrivateKeyHex } from "./bitcoin-utils"
11
13
  import networks from "./utils/networks"
12
- import { Network, Payment, Psbt } from "bitcoinjs-lib"
13
14
  import { BitcoinInterface } from "./bitcoin-interface"
14
15
 
15
- import BIP32Factory from "bip32"
16
- import ecc from "@bitcoinerlab/secp256k1"
17
-
18
16
  const bip32 = BIP32Factory(ecc)
19
17
 
20
- class BitcoinBase {
18
+ export class BitcoinBaseWallet {
21
19
  network: Network
22
20
  hdWalletPath: {
23
21
  p2pkh: string
@@ -28,7 +26,7 @@ class BitcoinBase {
28
26
  "p2sh-p2wsh": string
29
27
  p2tr: string
30
28
  }
31
- transactionBuilder: TransactionBuilder
29
+ transactionBuilder: BitcoinTransactionBuilder
32
30
  btcInterface: BitcoinInterface
33
31
  signer: BitcoinSign
34
32
  currentAccount?: string
@@ -42,7 +40,6 @@ class BitcoinBase {
42
40
  networkName: string,
43
41
  connectionInfo: BitcoinConnectionInfo = {
44
42
  api: {
45
- enabled: true,
46
43
  provider: "BlockStream",
47
44
  },
48
45
  },
@@ -50,7 +47,11 @@ class BitcoinBase {
50
47
  this.network = networks[networkName]
51
48
  this.hdWalletPath = hdWalletPath.bitcoin
52
49
 
53
- this.transactionBuilder = new TransactionBuilder(connectionInfo, networkName, this.network)
50
+ this.transactionBuilder = new BitcoinTransactionBuilder(
51
+ connectionInfo,
52
+ networkName,
53
+ this.network,
54
+ )
54
55
  this.btcInterface = this.transactionBuilder.btcInterface
55
56
 
56
57
  this.signer = new BitcoinSign(this.network)
@@ -126,6 +127,8 @@ class BitcoinBase {
126
127
 
127
128
  // todo : not completed
128
129
  setMultiSigAccount(accountType = "p2sh") {
130
+ throw new Error("not supported yet")
131
+
129
132
  /* eslint-disable no-unreachable */
130
133
  // todo : not completed
131
134
  switch (accountType) {
@@ -150,10 +153,6 @@ class BitcoinBase {
150
153
  this.publicKey = publicKey
151
154
  }
152
155
 
153
- setAccountPublicKey(publicKeyHex: string) {
154
- this.publicKey = Buffer.from(publicKeyHex, "hex")
155
- }
156
-
157
156
  setAccountPrivateKeyByMnemonic({
158
157
  mnemonic,
159
158
  mnemonicPassword = "",
@@ -182,6 +181,10 @@ class BitcoinBase {
182
181
  return this.setAccount(addressType)
183
182
  }
184
183
 
184
+ setAccountPublicKey(publicKeyHex: string) {
185
+ this.publicKey = Buffer.from(publicKeyHex, "hex")
186
+ }
187
+
185
188
  setAccount(accountType = "p2pkh") {
186
189
  if (!this.publicKey) {
187
190
  throw new Error("account not initialized")
@@ -197,6 +200,8 @@ class BitcoinBase {
197
200
  return addressObj.address
198
201
  }
199
202
 
203
+ //
204
+
200
205
  async getExtendedUtxo(input: SignerInfo) {
201
206
  return this.transactionBuilder.getExtendedUtxo(input)
202
207
  }
@@ -266,7 +271,7 @@ class BitcoinBase {
266
271
  changeAddress: string,
267
272
  staticFeeRate?: number,
268
273
  ) {
269
- let transaction = await this.btcInterface.getTransaction(txId)
274
+ let transaction = await this.btcInterface.apiProvider.getTransaction(txId)
270
275
 
271
276
  let extendedUtxo = transaction.vin.map((vi) => ({
272
277
  signerInfo: signerInfos.find((s) => s.address === vi.address)!,
@@ -303,7 +308,7 @@ class BitcoinBase {
303
308
  targets,
304
309
  feeRate,
305
310
  changeAddress: changeIndex >= 0 ? transaction.vout[changeIndex].address : changeAddress,
311
+ selectType: "inOrder",
306
312
  })
307
313
  }
308
314
  }
309
- export { BitcoinBase }
@@ -0,0 +1,181 @@
1
+ import BigNumber from "bignumber.js"
2
+ import { brc20 } from "@teleportdao/configs"
3
+
4
+ export type WrapOpReturn = {
5
+ chainId: number
6
+ appId: number
7
+ brc20TokenId: number
8
+ recipientAddress: string
9
+ inputAmount: string
10
+ outputAmount?: string
11
+ outputToken?: string
12
+ thirdPartyId?: number
13
+ }
14
+ export type WrapOpReturnAndType = WrapOpReturn & {
15
+ requestType: "wrap" | "wrapAndExchange"
16
+ }
17
+
18
+ const brc20WrapRequests = brc20.requestAppId
19
+
20
+ export function generateBrc2OpReturn({
21
+ chainId,
22
+ appId,
23
+ brc20TokenId,
24
+ inputAmount,
25
+ recipientAddress,
26
+ thirdPartyId = 0,
27
+ isExchange = false,
28
+ outputToken,
29
+ outputAmount,
30
+ }: WrapOpReturn & {
31
+ isExchange?: boolean
32
+ }) {
33
+ let data = ""
34
+ if (chainId.toString(16).length > 4) throw new Error("chainId should be less than 2 bytes")
35
+ data += chainId.toString(16).padStart(4, "0") // 2 bytes
36
+ data += appId.toString(16).padStart(2, "0") // 1 bytes
37
+ data += brc20TokenId.toString(16).padStart(4, "0") // 2 bytes
38
+ data += BigNumber(inputAmount).toString(16).padStart(26, "0") // 13 bytes
39
+ data += recipientAddress.replace("0x", "").toLowerCase().padStart(40, "0") // 20 bytes
40
+ data += BigNumber(thirdPartyId).toString(16).padStart(2, "0") // 1 bytes
41
+ if (isExchange) {
42
+ if (!outputAmount || !outputToken) {
43
+ throw new Error("outputAmount and outputToken are required for exchange")
44
+ }
45
+ data += outputToken.replace("0x", "").toLowerCase().padStart(40, "0") // 20 bytes
46
+ data += BigNumber(outputAmount).toString(16).padStart(26, "0") // 13 bytes
47
+ }
48
+ return data
49
+ }
50
+
51
+ export function parseBrc20OpReturn(data: string) {
52
+ let parsedData: any = {}
53
+ parsedData.chainId = Number(`0x${data.slice(0, 4)}`) // 2 bytes
54
+ parsedData.appId = Number(`0x${data.slice(4, 6)}`) // 1 bytes
55
+ parsedData.brc20TokenId = Number(`0x${data.slice(6, 10)}`) // 2 bytes
56
+ parsedData.inputAmount = new BigNumber(`0x${data.slice(10, 36)}`).toFixed(0) // 11 bytes
57
+ parsedData.recipientAddress = `0x${data.slice(36, 76)}` // 20 bytes
58
+ parsedData.thirdPartyId = `0x${data.slice(76, 78)}` // 20 bytes
59
+ if (data.length === 78) {
60
+ parsedData.requestType = "wrap"
61
+ return {
62
+ status: true,
63
+ data: parsedData as WrapOpReturnAndType,
64
+ }
65
+ }
66
+ parsedData.outputToken = `0x${data.slice(78, 118)}` // 20 bytes
67
+ parsedData.outputAmount = new BigNumber(`0x${data.slice(118, 144)}`).toFixed(0) // 20 bytes
68
+ if (data.length === 144) {
69
+ parsedData.requestType = "swapAndWrap"
70
+ return {
71
+ status: true,
72
+ data: parsedData as WrapOpReturnAndType,
73
+ }
74
+ }
75
+
76
+ return {
77
+ status: false,
78
+ message: `invalid OP_RETURN data for requestType: 'wrap or exchange'. invalid data length : ${data.length} - valid length : 144 , 78`,
79
+ code: "INVALID_OP_RETURN",
80
+ }
81
+ }
82
+
83
+ function parseBrc20RawRequest(opReturnData: string): {
84
+ status: boolean
85
+ data?: WrapOpReturnAndType
86
+ message?: string
87
+ code?: string
88
+ } {
89
+ let data = opReturnData.slice(2, 4) === "4c" ? opReturnData.slice(6) : opReturnData.slice(4)
90
+ // eslint-disable-next-line no-unused-vars
91
+ let appIdHex = data.slice(4, 6) // 2 bytes
92
+ if (!appIdHex) {
93
+ return {
94
+ status: false,
95
+ message: `invalid OP_RETURN data : ${data}`,
96
+ code: "INVALID_APP_ID",
97
+ }
98
+ }
99
+
100
+ let appId = Number(`0x${appIdHex}`) // 2 bytes
101
+
102
+ // get type base on appId
103
+ let requestType = Object.keys(brc20WrapRequests).find(
104
+ (key) =>
105
+ appId >= brc20WrapRequests[key as keyof typeof brc20WrapRequests].appIdRange[0] &&
106
+ appId <= brc20WrapRequests[key as keyof typeof brc20WrapRequests].appIdRange[1],
107
+ )
108
+
109
+ switch (requestType) {
110
+ case "wrap":
111
+ case "wrapAndExchange":
112
+ return parseBrc20OpReturn(data)
113
+ default:
114
+ return {
115
+ status: false,
116
+ message: `invalid appId : ${appId}`,
117
+ code: "INVALID_OP_RETURN",
118
+ }
119
+ }
120
+ }
121
+
122
+ export function checkAndParseBrc20Request(
123
+ vouts: {
124
+ address?: string
125
+ script: string
126
+ value: number
127
+ }[],
128
+ address: string,
129
+ ): {
130
+ status: boolean
131
+ data?: WrapOpReturnAndType
132
+ dataOutputIndex?: number
133
+ lockerFeeValue?: number
134
+ lockerFeeOutputIndex?: number
135
+ brc20OutputIndex?: number
136
+ brc20OutputValue?: number
137
+ message?: string
138
+ code?: string
139
+ } {
140
+ let requestOutputIndex = vouts.findIndex((vout_) => vout_.script.startsWith("6a"))
141
+ if (requestOutputIndex >= 0) {
142
+ let opReturnData = vouts[requestOutputIndex]?.script
143
+ if (!opReturnData) {
144
+ return {
145
+ status: false,
146
+ message: "invalid OP_RETURN",
147
+ code: "INVALID_OP_RETURN",
148
+ }
149
+ }
150
+
151
+ let brc20Transfer = vouts[0]
152
+ if (brc20Transfer.address !== address || brc20Transfer.value < 546) {
153
+ return {
154
+ status: false,
155
+ message: "no brc20 transfer output",
156
+ code: "NO_BRC20_TRANSFER",
157
+ }
158
+ }
159
+
160
+ let dataResponse = parseBrc20RawRequest(opReturnData)
161
+ if (dataResponse.status) {
162
+ let lockerFeeOutputIndex = vouts.findIndex((vout_, i) => vout_.address === address && +i > 0)
163
+ let lockerFeeValue = lockerFeeOutputIndex >= 0 ? vouts[lockerFeeOutputIndex].value : 0
164
+ return {
165
+ status: true,
166
+ data: dataResponse.data!,
167
+ dataOutputIndex: requestOutputIndex,
168
+ lockerFeeValue,
169
+ lockerFeeOutputIndex,
170
+ brc20OutputIndex: 0,
171
+ brc20OutputValue: brc20Transfer.value,
172
+ }
173
+ }
174
+ return dataResponse
175
+ }
176
+ return {
177
+ status: false,
178
+ message: "transaction outputs should contain OP_RETURN",
179
+ code: "NO_OP_RETURN",
180
+ }
181
+ }
@@ -0,0 +1,3 @@
1
+ export * as brc20Helper from "./brc20-helper"
2
+ export * as teleswapHelper from "./teleswap-helper"
3
+ export * as ordinalHelper from "./ordinal-helper"
@@ -0,0 +1,118 @@
1
+ import * as bitcoin from "bitcoinjs-lib"
2
+ import * as ecc from "tiny-secp256k1"
3
+
4
+ bitcoin.initEccLib(ecc)
5
+
6
+ // eslint-disable-next-line consistent-return
7
+ export function createAddressObjectByScriptNoType(
8
+ script: Buffer,
9
+ network: bitcoin.Network = bitcoin.networks.bitcoin,
10
+ ) {
11
+ let addressObject: bitcoin.payments.Payment
12
+
13
+ try {
14
+ addressObject = bitcoin.payments.p2pkh({
15
+ output: script,
16
+ network,
17
+ })
18
+ if (addressObject.address) {
19
+ return {
20
+ addressObject,
21
+ addressType: "p2pkh",
22
+ }
23
+ }
24
+ } catch (err) {
25
+ /* empty */
26
+ }
27
+
28
+ try {
29
+ addressObject = bitcoin.payments.p2wpkh({
30
+ output: script,
31
+ network,
32
+ })
33
+ if (addressObject.address) {
34
+ return {
35
+ addressObject,
36
+ addressType: "p2wpkh",
37
+ }
38
+ }
39
+ } catch (err) {
40
+ /* empty */
41
+ }
42
+
43
+ try {
44
+ addressObject = bitcoin.payments.p2sh({
45
+ output: script,
46
+ network,
47
+ })
48
+ if (addressObject.address) {
49
+ return {
50
+ addressObject,
51
+ addressType: "p2sh",
52
+ }
53
+ }
54
+ } catch (err) {
55
+ /* empty */
56
+ }
57
+
58
+ try {
59
+ addressObject = bitcoin.payments.p2wsh({
60
+ output: script,
61
+ network,
62
+ })
63
+ if (addressObject.address) {
64
+ return {
65
+ addressObject,
66
+ addressType: "p2wsh",
67
+ }
68
+ }
69
+ } catch (err) {
70
+ /* empty */
71
+ }
72
+
73
+ try {
74
+ addressObject = bitcoin.payments.p2tr({
75
+ output: script,
76
+ network,
77
+ })
78
+ if (addressObject.address) {
79
+ return {
80
+ addressObject,
81
+ addressType: "p2tr",
82
+ }
83
+ }
84
+ } catch (err) {
85
+ /* empty */
86
+ }
87
+ }
88
+
89
+ export function splitBuffer(buffer: Buffer, partLength: number) {
90
+ const parts: Buffer[] = []
91
+ for (let i = 0; i < buffer.length; i += partLength) {
92
+ const part = buffer.subarray(i, i + partLength)
93
+ parts.push(part)
94
+ }
95
+ return parts
96
+ }
97
+
98
+ export function getOrdinalScript(
99
+ file: { buffer: Buffer; type: string },
100
+ internalPublicKeyHex: string,
101
+ ) {
102
+ let bufferParts = splitBuffer(file.buffer, 520)
103
+ const splittedFileHex = bufferParts.map((part) => part.toString("hex")).join(" ")
104
+ const fileTypeHex = Buffer.from(file.type!, "utf8").toString("hex")
105
+ const ORDINAL_ORD_HEX = Buffer.from("ord", "utf8").toString("hex")
106
+ const script = `${internalPublicKeyHex} OP_CHECKSIG OP_FALSE OP_IF ${ORDINAL_ORD_HEX} 00000000000000000000 ${fileTypeHex} OP_0 ${splittedFileHex} OP_ENDIF`
107
+
108
+ // we add 00000000000000000000 so we can modify INCORRECT OPCODE
109
+ const leafScript = Buffer.from(
110
+ bitcoin.script.fromASM(script).toString("hex").replace("0a00000000000000000000", "0101"),
111
+ "hex",
112
+ )
113
+ return leafScript
114
+ }
115
+
116
+ export function toXOnly(pubKey: Buffer) {
117
+ return pubKey.length === 32 ? pubKey : pubKey.subarray(1, 33)
118
+ }