@teleportdao/bitcoin 1.4.3 → 1.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bitcoin-base.d.ts +17 -16
- package/dist/bitcoin-base.d.ts.map +1 -1
- package/dist/bitcoin-base.js +12 -7
- package/dist/bitcoin-base.js.map +1 -1
- package/dist/bitcoin-utils.d.ts +1 -1
- package/dist/bitcoin-utils.d.ts.map +1 -1
- package/dist/bitcoin-utils.js +3 -0
- package/dist/bitcoin-utils.js.map +1 -1
- package/dist/bundle.js +4 -0
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -12
- package/dist/index.js.map +1 -1
- package/dist/sign/sign-transaction.d.ts +9 -5
- package/dist/sign/sign-transaction.d.ts.map +1 -1
- package/dist/sign/sign-transaction.js +14 -11
- package/dist/sign/sign-transaction.js.map +1 -1
- package/dist/teleport-dao-payments.d.ts +17 -6
- package/dist/teleport-dao-payments.d.ts.map +1 -1
- package/dist/teleport-dao-payments.js +4 -3
- package/dist/teleport-dao-payments.js.map +1 -1
- package/dist/transaction-builder/bitcoin-transaction-builder.d.ts +26 -11
- package/dist/transaction-builder/bitcoin-transaction-builder.d.ts.map +1 -1
- package/dist/transaction-builder/bitcoin-transaction-builder.js +36 -8
- package/dist/transaction-builder/bitcoin-transaction-builder.js.map +1 -1
- package/dist/transaction-builder/transaction-builder.d.ts +148 -9
- package/dist/transaction-builder/transaction-builder.d.ts.map +1 -1
- package/dist/transaction-builder/transaction-builder.js +230 -30
- package/dist/transaction-builder/transaction-builder.js.map +1 -1
- package/package.json +7 -5
- package/src/bitcoin-base.js +220 -219
- package/src/bitcoin-interface.js +350 -350
- package/src/bitcoin-utils.js +487 -483
- package/src/helper/teleport-request-helper.js +179 -179
- package/src/index.ts +8 -0
- package/src/sign/sign-transaction.ts +96 -0
- package/src/teleport-dao-payments.js +280 -280
- package/src/transaction-builder/bitcoin-transaction-builder.ts +57 -0
- package/src/transaction-builder/transaction-builder.ts +490 -0
- package/src/index.js +0 -15
- package/src/sign/sign-transaction.js +0 -36
- package/src/transaction-builder/bitcoin-transaction-builder.js +0 -37
- package/src/transaction-builder/transaction-builder-common.js +0 -236
- package/src/transaction-builder/transaction-builder.js +0 -159
|
@@ -1,280 +1,280 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
class TeleportDaoPayment extends BitcoinBase {
|
|
4
|
-
// payment
|
|
5
|
-
async payBurnRequest(receivers, feeSpeed = "normal") {
|
|
6
|
-
let extendedUtxo = await this.transactionBuilder.getExtendedUtxo({
|
|
7
|
-
address: this.currentAccount,
|
|
8
|
-
addressType: this.currentAccountType,
|
|
9
|
-
publicKey: this.publicKey.toString("hex"),
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
let feeRate = await this.transactionBuilder._getFeeRate(feeSpeed)
|
|
13
|
-
let unsignedTx = await this.transactionBuilder.processUnsignedTransaction({
|
|
14
|
-
extendedUtxo,
|
|
15
|
-
targets: receivers,
|
|
16
|
-
changeAddress: this.currentAccount,
|
|
17
|
-
feeRate,
|
|
18
|
-
fullAmount: false,
|
|
19
|
-
})
|
|
20
|
-
let signedPsbt = await this.signer.signPsbt(unsignedTx, this.privateKey)
|
|
21
|
-
let signedTx = this.signer.finalizePsbts([signedPsbt])
|
|
22
|
-
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
23
|
-
return txId
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// send
|
|
27
|
-
async transferBitcoinToEth({
|
|
28
|
-
lockerAddress,
|
|
29
|
-
amount,
|
|
30
|
-
fullAmount = false,
|
|
31
|
-
//-----------
|
|
32
|
-
chainId,
|
|
33
|
-
appId,
|
|
34
|
-
recipientAddress, // 20 bytes
|
|
35
|
-
percentageFee, // 2 bytes in satoshi
|
|
36
|
-
speed = 0, // 1 byte
|
|
37
|
-
isExchange = false,
|
|
38
|
-
exchangeTokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
39
|
-
outputAmount = 0, // 28 bytes
|
|
40
|
-
deadline, // 4 bytes
|
|
41
|
-
isFixedToken = false, // 1 byte
|
|
42
|
-
feeSpeed = "normal",
|
|
43
|
-
}) {
|
|
44
|
-
let extendedUtxo = await this.getExtendedUtxo({
|
|
45
|
-
address: this.currentAccount,
|
|
46
|
-
addressType: this.currentAccountType,
|
|
47
|
-
publicKey: this.publicKey.toString("hex"),
|
|
48
|
-
})
|
|
49
|
-
let unsignedTx = await this.getBitcoinToEthUnsignedPsbt({
|
|
50
|
-
changeAddress: this.currentAccount,
|
|
51
|
-
extendedUtxo,
|
|
52
|
-
lockerAddress,
|
|
53
|
-
amount,
|
|
54
|
-
fullAmount,
|
|
55
|
-
//-----------
|
|
56
|
-
chainId,
|
|
57
|
-
appId,
|
|
58
|
-
recipientAddress,
|
|
59
|
-
percentageFee,
|
|
60
|
-
speed,
|
|
61
|
-
isExchange,
|
|
62
|
-
exchangeTokenAddress,
|
|
63
|
-
outputAmount,
|
|
64
|
-
deadline,
|
|
65
|
-
isFixedToken,
|
|
66
|
-
feeSpeed,
|
|
67
|
-
})
|
|
68
|
-
let signedPsbt = await this.signer.signPsbt(unsignedTx, this.privateKey)
|
|
69
|
-
let txId = await this.sendSignedPsbt(signedPsbt)
|
|
70
|
-
return txId
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// get
|
|
74
|
-
async getBitcoinToEthTargetOutputs({
|
|
75
|
-
lockerAddress,
|
|
76
|
-
amount,
|
|
77
|
-
fullAmount = false,
|
|
78
|
-
//-----------
|
|
79
|
-
chainId,
|
|
80
|
-
appId,
|
|
81
|
-
recipientAddress, // 20 bytes
|
|
82
|
-
percentageFee, // 2 bytes in satoshi
|
|
83
|
-
speed = 0, // 1 byte
|
|
84
|
-
isExchange = false,
|
|
85
|
-
exchangeTokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
86
|
-
outputAmount = 0, // 28 bytes
|
|
87
|
-
deadline = 0, // 4 bytes
|
|
88
|
-
isFixedToken = false, // 1 byte
|
|
89
|
-
}) {
|
|
90
|
-
let dataHex = TeleportDaoPayment.getTransferOpReturnData({
|
|
91
|
-
chainId,
|
|
92
|
-
appId,
|
|
93
|
-
recipientAddress,
|
|
94
|
-
percentageFee,
|
|
95
|
-
speed,
|
|
96
|
-
isExchange,
|
|
97
|
-
exchangeTokenAddress,
|
|
98
|
-
outputAmount,
|
|
99
|
-
deadline,
|
|
100
|
-
isFixedToken,
|
|
101
|
-
})
|
|
102
|
-
let opTarget = this.transactionBuilder.getOpReturnTarget(dataHex)
|
|
103
|
-
return fullAmount
|
|
104
|
-
? [opTarget]
|
|
105
|
-
: [
|
|
106
|
-
{
|
|
107
|
-
address: lockerAddress,
|
|
108
|
-
value: amount,
|
|
109
|
-
},
|
|
110
|
-
opTarget,
|
|
111
|
-
]
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async getBitcoinToEthUnsignedPsbt({
|
|
115
|
-
changeAddress,
|
|
116
|
-
extendedUtxo,
|
|
117
|
-
lockerAddress,
|
|
118
|
-
amount,
|
|
119
|
-
fullAmount = false,
|
|
120
|
-
//-----------
|
|
121
|
-
chainId,
|
|
122
|
-
appId,
|
|
123
|
-
recipientAddress, // 20 bytes
|
|
124
|
-
percentageFee, // 2 bytes in satoshi
|
|
125
|
-
speed = 0, // 1 byte
|
|
126
|
-
isExchange = false,
|
|
127
|
-
exchangeTokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
128
|
-
outputAmount = 0, // 28 bytes
|
|
129
|
-
deadline = 0, // 4 bytes
|
|
130
|
-
isFixedToken = false, // 1 byte
|
|
131
|
-
feeSpeed = "normal",
|
|
132
|
-
}) {
|
|
133
|
-
let feeRate = await this.transactionBuilder._getFeeRate(feeSpeed)
|
|
134
|
-
let targets = await this.getBitcoinToEthTargetOutputs({
|
|
135
|
-
lockerAddress,
|
|
136
|
-
amount,
|
|
137
|
-
fullAmount,
|
|
138
|
-
chainId,
|
|
139
|
-
appId,
|
|
140
|
-
recipientAddress,
|
|
141
|
-
percentageFee,
|
|
142
|
-
speed,
|
|
143
|
-
isExchange,
|
|
144
|
-
exchangeTokenAddress,
|
|
145
|
-
outputAmount,
|
|
146
|
-
deadline,
|
|
147
|
-
isFixedToken,
|
|
148
|
-
})
|
|
149
|
-
let unsignedTx = await this.transactionBuilder.processUnsignedTransaction({
|
|
150
|
-
extendedUtxo,
|
|
151
|
-
targets,
|
|
152
|
-
changeAddress: fullAmount ? lockerAddress : changeAddress,
|
|
153
|
-
feeRate,
|
|
154
|
-
fullAmount,
|
|
155
|
-
})
|
|
156
|
-
return unsignedTx
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// send
|
|
160
|
-
async bitcoinToEthLend({
|
|
161
|
-
lockerAddress,
|
|
162
|
-
amount,
|
|
163
|
-
//-----------
|
|
164
|
-
chainId,
|
|
165
|
-
appId,
|
|
166
|
-
recipientAddress, // 20 bytes
|
|
167
|
-
percentageFee, // 2 bytes in satoshi
|
|
168
|
-
mode = 0, // 1 byte
|
|
169
|
-
isBorrow = false,
|
|
170
|
-
tokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
171
|
-
borrowAmount = 0, // 28 bytes
|
|
172
|
-
}) {
|
|
173
|
-
let dataHex = TeleportDaoPayment.getLendingOpReturnData({
|
|
174
|
-
chainId,
|
|
175
|
-
appId,
|
|
176
|
-
recipientAddress,
|
|
177
|
-
percentageFee,
|
|
178
|
-
mode,
|
|
179
|
-
isBorrow,
|
|
180
|
-
tokenAddress,
|
|
181
|
-
borrowAmount,
|
|
182
|
-
})
|
|
183
|
-
let opTarget = this.transactionBuilder.getOpReturnTarget(dataHex)
|
|
184
|
-
|
|
185
|
-
let extendedUtxo = await this.transactionBuilder.getExtendedUtxo({
|
|
186
|
-
address: this.currentAccount,
|
|
187
|
-
addressType: this.currentAccountType,
|
|
188
|
-
publicKey: this.publicKey.toString("hex"),
|
|
189
|
-
})
|
|
190
|
-
let unsignedTx = await this.transactionBuilder.processUnsignedTransaction({
|
|
191
|
-
extendedUtxo,
|
|
192
|
-
targets: [
|
|
193
|
-
{
|
|
194
|
-
address: lockerAddress,
|
|
195
|
-
value: amount,
|
|
196
|
-
},
|
|
197
|
-
opTarget,
|
|
198
|
-
],
|
|
199
|
-
changeAddress: this.currentAccount,
|
|
200
|
-
feeRate: 1,
|
|
201
|
-
fullAmount: false,
|
|
202
|
-
})
|
|
203
|
-
let signedPsbt = await this.signer.signPsbt(unsignedTx, this.privateKey)
|
|
204
|
-
let signedTx = this.signer.finalizePsbts([signedPsbt])
|
|
205
|
-
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
206
|
-
return txId
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
static getTransferOpReturnData({
|
|
210
|
-
chainId,
|
|
211
|
-
appId,
|
|
212
|
-
recipientAddress, // 20 bytes
|
|
213
|
-
percentageFee, // 2 bytes in satoshi
|
|
214
|
-
speed = 0, // 1 byte
|
|
215
|
-
isExchange = false,
|
|
216
|
-
exchangeTokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
217
|
-
outputAmount = 0, // 28 bytes
|
|
218
|
-
deadline, // 4 bytes
|
|
219
|
-
isFixedToken = false, // 1 byte
|
|
220
|
-
}) {
|
|
221
|
-
let chainIdHex = Number(chainId).toString(16).padStart(2, "0")
|
|
222
|
-
let appIdHex = Number(appId).toString(16).padStart(4, "0")
|
|
223
|
-
let recipientAddressHex = recipientAddress.replace("0x", "").toLowerCase().padStart(40, "0")
|
|
224
|
-
let percentageFeeHex = Number((percentageFee * 100).toFixed(0))
|
|
225
|
-
.toString(16)
|
|
226
|
-
.padStart(4, "0")
|
|
227
|
-
let speedHex = speed ? "01" : "00"
|
|
228
|
-
let dataHex = chainIdHex + appIdHex + recipientAddressHex + percentageFeeHex + speedHex
|
|
229
|
-
|
|
230
|
-
if (!isExchange) {
|
|
231
|
-
if (dataHex.length !== 26 * 2) throw new Error("invalid data length")
|
|
232
|
-
return dataHex
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
let exchangeTokenAddressHex = exchangeTokenAddress
|
|
236
|
-
.replace("0x", "")
|
|
237
|
-
.toLowerCase()
|
|
238
|
-
.padStart(40, "0")
|
|
239
|
-
let outputAmountHex = Number(outputAmount).toString(16).padStart(56, "0")
|
|
240
|
-
let deadlineHex = Number(deadline).toString(16).padStart(8, "0")
|
|
241
|
-
let isFixedTokenHex = isFixedToken ? "01" : "00"
|
|
242
|
-
|
|
243
|
-
dataHex = dataHex + exchangeTokenAddressHex + outputAmountHex + deadlineHex + isFixedTokenHex
|
|
244
|
-
if (dataHex.length !== 79 * 2) throw new Error("invalid data length")
|
|
245
|
-
return dataHex
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
static getLendingOpReturnData({
|
|
249
|
-
chainId, // 1 byte
|
|
250
|
-
appId, // 1 byte
|
|
251
|
-
recipientAddress, // 20 byte
|
|
252
|
-
percentageFee, // 2 byte
|
|
253
|
-
mode, // 1 byte
|
|
254
|
-
// ------
|
|
255
|
-
isBorrow = false,
|
|
256
|
-
tokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
257
|
-
borrowAmount = 0, // 28 bytes
|
|
258
|
-
}) {
|
|
259
|
-
let chainIdHex = Number(chainId).toString(16).padStart(2, "0")
|
|
260
|
-
let appIdHex = Number(appId).toString(16).padStart(4, "0")
|
|
261
|
-
let recipientAddressHex = recipientAddress.replace("0x", "").toLowerCase().padStart(40, "0")
|
|
262
|
-
let percentageFeeHex = Number((percentageFee * 100).toFixed(0))
|
|
263
|
-
.toString(16)
|
|
264
|
-
.padStart(4, "0")
|
|
265
|
-
let modeHex = Number(mode).toString(16).padStart(2, "0")
|
|
266
|
-
let dataHex = chainIdHex + appIdHex + recipientAddressHex + percentageFeeHex + modeHex
|
|
267
|
-
if (!isBorrow) {
|
|
268
|
-
if (dataHex.length !== 26 * 2) throw new Error("invalid data length")
|
|
269
|
-
return dataHex
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
let tokenAddressHex = tokenAddress.replace("0x", "").toLowerCase().padStart(40, "0")
|
|
273
|
-
let borrowAmountHex = Number(borrowAmount).toString(16).padStart(56, "0")
|
|
274
|
-
dataHex = dataHex + tokenAddressHex + borrowAmountHex
|
|
275
|
-
if (dataHex.length !== 74 * 2) throw new Error("invalid data length")
|
|
276
|
-
return dataHex
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
|
|
1
|
+
import { BitcoinBase } from "./bitcoin-base"
|
|
2
|
+
|
|
3
|
+
class TeleportDaoPayment extends BitcoinBase {
|
|
4
|
+
// payment
|
|
5
|
+
async payBurnRequest(receivers, feeSpeed = "normal") {
|
|
6
|
+
let extendedUtxo = await this.transactionBuilder.getExtendedUtxo({
|
|
7
|
+
address: this.currentAccount,
|
|
8
|
+
addressType: this.currentAccountType,
|
|
9
|
+
publicKey: this.publicKey.toString("hex"),
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
let feeRate = await this.transactionBuilder._getFeeRate(feeSpeed)
|
|
13
|
+
let unsignedTx = await this.transactionBuilder.processUnsignedTransaction({
|
|
14
|
+
extendedUtxo,
|
|
15
|
+
targets: receivers,
|
|
16
|
+
changeAddress: this.currentAccount,
|
|
17
|
+
feeRate,
|
|
18
|
+
fullAmount: false,
|
|
19
|
+
})
|
|
20
|
+
let signedPsbt = await this.signer.signPsbt(unsignedTx, this.privateKey)
|
|
21
|
+
let signedTx = this.signer.finalizePsbts([signedPsbt])
|
|
22
|
+
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
23
|
+
return txId
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// send
|
|
27
|
+
async transferBitcoinToEth({
|
|
28
|
+
lockerAddress,
|
|
29
|
+
amount,
|
|
30
|
+
fullAmount = false,
|
|
31
|
+
//-----------
|
|
32
|
+
chainId,
|
|
33
|
+
appId,
|
|
34
|
+
recipientAddress, // 20 bytes
|
|
35
|
+
percentageFee, // 2 bytes in satoshi
|
|
36
|
+
speed = 0, // 1 byte
|
|
37
|
+
isExchange = false,
|
|
38
|
+
exchangeTokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
39
|
+
outputAmount = 0, // 28 bytes
|
|
40
|
+
deadline, // 4 bytes
|
|
41
|
+
isFixedToken = false, // 1 byte
|
|
42
|
+
feeSpeed = "normal",
|
|
43
|
+
}) {
|
|
44
|
+
let extendedUtxo = await this.getExtendedUtxo({
|
|
45
|
+
address: this.currentAccount,
|
|
46
|
+
addressType: this.currentAccountType,
|
|
47
|
+
publicKey: this.publicKey.toString("hex"),
|
|
48
|
+
})
|
|
49
|
+
let unsignedTx = await this.getBitcoinToEthUnsignedPsbt({
|
|
50
|
+
changeAddress: this.currentAccount,
|
|
51
|
+
extendedUtxo,
|
|
52
|
+
lockerAddress,
|
|
53
|
+
amount,
|
|
54
|
+
fullAmount,
|
|
55
|
+
//-----------
|
|
56
|
+
chainId,
|
|
57
|
+
appId,
|
|
58
|
+
recipientAddress,
|
|
59
|
+
percentageFee,
|
|
60
|
+
speed,
|
|
61
|
+
isExchange,
|
|
62
|
+
exchangeTokenAddress,
|
|
63
|
+
outputAmount,
|
|
64
|
+
deadline,
|
|
65
|
+
isFixedToken,
|
|
66
|
+
feeSpeed,
|
|
67
|
+
})
|
|
68
|
+
let signedPsbt = await this.signer.signPsbt(unsignedTx, this.privateKey)
|
|
69
|
+
let txId = await this.sendSignedPsbt(signedPsbt)
|
|
70
|
+
return txId
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// get
|
|
74
|
+
async getBitcoinToEthTargetOutputs({
|
|
75
|
+
lockerAddress,
|
|
76
|
+
amount,
|
|
77
|
+
fullAmount = false,
|
|
78
|
+
//-----------
|
|
79
|
+
chainId,
|
|
80
|
+
appId,
|
|
81
|
+
recipientAddress, // 20 bytes
|
|
82
|
+
percentageFee, // 2 bytes in satoshi
|
|
83
|
+
speed = 0, // 1 byte
|
|
84
|
+
isExchange = false,
|
|
85
|
+
exchangeTokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
86
|
+
outputAmount = 0, // 28 bytes
|
|
87
|
+
deadline = 0, // 4 bytes
|
|
88
|
+
isFixedToken = false, // 1 byte
|
|
89
|
+
}) {
|
|
90
|
+
let dataHex = TeleportDaoPayment.getTransferOpReturnData({
|
|
91
|
+
chainId,
|
|
92
|
+
appId,
|
|
93
|
+
recipientAddress,
|
|
94
|
+
percentageFee,
|
|
95
|
+
speed,
|
|
96
|
+
isExchange,
|
|
97
|
+
exchangeTokenAddress,
|
|
98
|
+
outputAmount,
|
|
99
|
+
deadline,
|
|
100
|
+
isFixedToken,
|
|
101
|
+
})
|
|
102
|
+
let opTarget = this.transactionBuilder.getOpReturnTarget(dataHex)
|
|
103
|
+
return fullAmount
|
|
104
|
+
? [opTarget]
|
|
105
|
+
: [
|
|
106
|
+
{
|
|
107
|
+
address: lockerAddress,
|
|
108
|
+
value: amount,
|
|
109
|
+
},
|
|
110
|
+
opTarget,
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async getBitcoinToEthUnsignedPsbt({
|
|
115
|
+
changeAddress,
|
|
116
|
+
extendedUtxo,
|
|
117
|
+
lockerAddress,
|
|
118
|
+
amount,
|
|
119
|
+
fullAmount = false,
|
|
120
|
+
//-----------
|
|
121
|
+
chainId,
|
|
122
|
+
appId,
|
|
123
|
+
recipientAddress, // 20 bytes
|
|
124
|
+
percentageFee, // 2 bytes in satoshi
|
|
125
|
+
speed = 0, // 1 byte
|
|
126
|
+
isExchange = false,
|
|
127
|
+
exchangeTokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
128
|
+
outputAmount = 0, // 28 bytes
|
|
129
|
+
deadline = 0, // 4 bytes
|
|
130
|
+
isFixedToken = false, // 1 byte
|
|
131
|
+
feeSpeed = "normal",
|
|
132
|
+
}) {
|
|
133
|
+
let feeRate = await this.transactionBuilder._getFeeRate(feeSpeed)
|
|
134
|
+
let targets = await this.getBitcoinToEthTargetOutputs({
|
|
135
|
+
lockerAddress,
|
|
136
|
+
amount,
|
|
137
|
+
fullAmount,
|
|
138
|
+
chainId,
|
|
139
|
+
appId,
|
|
140
|
+
recipientAddress,
|
|
141
|
+
percentageFee,
|
|
142
|
+
speed,
|
|
143
|
+
isExchange,
|
|
144
|
+
exchangeTokenAddress,
|
|
145
|
+
outputAmount,
|
|
146
|
+
deadline,
|
|
147
|
+
isFixedToken,
|
|
148
|
+
})
|
|
149
|
+
let unsignedTx = await this.transactionBuilder.processUnsignedTransaction({
|
|
150
|
+
extendedUtxo,
|
|
151
|
+
targets,
|
|
152
|
+
changeAddress: fullAmount ? lockerAddress : changeAddress,
|
|
153
|
+
feeRate,
|
|
154
|
+
fullAmount,
|
|
155
|
+
})
|
|
156
|
+
return unsignedTx
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// send
|
|
160
|
+
async bitcoinToEthLend({
|
|
161
|
+
lockerAddress,
|
|
162
|
+
amount,
|
|
163
|
+
//-----------
|
|
164
|
+
chainId,
|
|
165
|
+
appId,
|
|
166
|
+
recipientAddress, // 20 bytes
|
|
167
|
+
percentageFee, // 2 bytes in satoshi
|
|
168
|
+
mode = 0, // 1 byte
|
|
169
|
+
isBorrow = false,
|
|
170
|
+
tokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
171
|
+
borrowAmount = 0, // 28 bytes
|
|
172
|
+
}) {
|
|
173
|
+
let dataHex = TeleportDaoPayment.getLendingOpReturnData({
|
|
174
|
+
chainId,
|
|
175
|
+
appId,
|
|
176
|
+
recipientAddress,
|
|
177
|
+
percentageFee,
|
|
178
|
+
mode,
|
|
179
|
+
isBorrow,
|
|
180
|
+
tokenAddress,
|
|
181
|
+
borrowAmount,
|
|
182
|
+
})
|
|
183
|
+
let opTarget = this.transactionBuilder.getOpReturnTarget(dataHex)
|
|
184
|
+
|
|
185
|
+
let extendedUtxo = await this.transactionBuilder.getExtendedUtxo({
|
|
186
|
+
address: this.currentAccount,
|
|
187
|
+
addressType: this.currentAccountType,
|
|
188
|
+
publicKey: this.publicKey.toString("hex"),
|
|
189
|
+
})
|
|
190
|
+
let unsignedTx = await this.transactionBuilder.processUnsignedTransaction({
|
|
191
|
+
extendedUtxo,
|
|
192
|
+
targets: [
|
|
193
|
+
{
|
|
194
|
+
address: lockerAddress,
|
|
195
|
+
value: amount,
|
|
196
|
+
},
|
|
197
|
+
opTarget,
|
|
198
|
+
],
|
|
199
|
+
changeAddress: this.currentAccount,
|
|
200
|
+
feeRate: 1,
|
|
201
|
+
fullAmount: false,
|
|
202
|
+
})
|
|
203
|
+
let signedPsbt = await this.signer.signPsbt(unsignedTx, this.privateKey)
|
|
204
|
+
let signedTx = this.signer.finalizePsbts([signedPsbt])
|
|
205
|
+
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
206
|
+
return txId
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
static getTransferOpReturnData({
|
|
210
|
+
chainId,
|
|
211
|
+
appId,
|
|
212
|
+
recipientAddress, // 20 bytes
|
|
213
|
+
percentageFee, // 2 bytes in satoshi
|
|
214
|
+
speed = 0, // 1 byte
|
|
215
|
+
isExchange = false,
|
|
216
|
+
exchangeTokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
217
|
+
outputAmount = 0, // 28 bytes
|
|
218
|
+
deadline, // 4 bytes
|
|
219
|
+
isFixedToken = false, // 1 byte
|
|
220
|
+
}) {
|
|
221
|
+
let chainIdHex = Number(chainId).toString(16).padStart(2, "0")
|
|
222
|
+
let appIdHex = Number(appId).toString(16).padStart(4, "0")
|
|
223
|
+
let recipientAddressHex = recipientAddress.replace("0x", "").toLowerCase().padStart(40, "0")
|
|
224
|
+
let percentageFeeHex = Number((percentageFee * 100).toFixed(0))
|
|
225
|
+
.toString(16)
|
|
226
|
+
.padStart(4, "0")
|
|
227
|
+
let speedHex = speed ? "01" : "00"
|
|
228
|
+
let dataHex = chainIdHex + appIdHex + recipientAddressHex + percentageFeeHex + speedHex
|
|
229
|
+
|
|
230
|
+
if (!isExchange) {
|
|
231
|
+
if (dataHex.length !== 26 * 2) throw new Error("invalid data length")
|
|
232
|
+
return dataHex
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
let exchangeTokenAddressHex = exchangeTokenAddress
|
|
236
|
+
.replace("0x", "")
|
|
237
|
+
.toLowerCase()
|
|
238
|
+
.padStart(40, "0")
|
|
239
|
+
let outputAmountHex = Number(outputAmount).toString(16).padStart(56, "0")
|
|
240
|
+
let deadlineHex = Number(deadline).toString(16).padStart(8, "0")
|
|
241
|
+
let isFixedTokenHex = isFixedToken ? "01" : "00"
|
|
242
|
+
|
|
243
|
+
dataHex = dataHex + exchangeTokenAddressHex + outputAmountHex + deadlineHex + isFixedTokenHex
|
|
244
|
+
if (dataHex.length !== 79 * 2) throw new Error("invalid data length")
|
|
245
|
+
return dataHex
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
static getLendingOpReturnData({
|
|
249
|
+
chainId, // 1 byte
|
|
250
|
+
appId, // 1 byte
|
|
251
|
+
recipientAddress, // 20 byte
|
|
252
|
+
percentageFee, // 2 byte
|
|
253
|
+
mode, // 1 byte
|
|
254
|
+
// ------
|
|
255
|
+
isBorrow = false,
|
|
256
|
+
tokenAddress = "0x0000000000000000000000000000000000000000", // 20 bytes
|
|
257
|
+
borrowAmount = 0, // 28 bytes
|
|
258
|
+
}) {
|
|
259
|
+
let chainIdHex = Number(chainId).toString(16).padStart(2, "0")
|
|
260
|
+
let appIdHex = Number(appId).toString(16).padStart(4, "0")
|
|
261
|
+
let recipientAddressHex = recipientAddress.replace("0x", "").toLowerCase().padStart(40, "0")
|
|
262
|
+
let percentageFeeHex = Number((percentageFee * 100).toFixed(0))
|
|
263
|
+
.toString(16)
|
|
264
|
+
.padStart(4, "0")
|
|
265
|
+
let modeHex = Number(mode).toString(16).padStart(2, "0")
|
|
266
|
+
let dataHex = chainIdHex + appIdHex + recipientAddressHex + percentageFeeHex + modeHex
|
|
267
|
+
if (!isBorrow) {
|
|
268
|
+
if (dataHex.length !== 26 * 2) throw new Error("invalid data length")
|
|
269
|
+
return dataHex
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
let tokenAddressHex = tokenAddress.replace("0x", "").toLowerCase().padStart(40, "0")
|
|
273
|
+
let borrowAmountHex = Number(borrowAmount).toString(16).padStart(56, "0")
|
|
274
|
+
dataHex = dataHex + tokenAddressHex + borrowAmountHex
|
|
275
|
+
if (dataHex.length !== 74 * 2) throw new Error("invalid data length")
|
|
276
|
+
return dataHex
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export default TeleportDaoPayment
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import BaseTransactionBuilder from "./transaction-builder"
|
|
2
|
+
import BitcoinInterface from "../bitcoin-interface"
|
|
3
|
+
import * as bitcoin from "bitcoinjs-lib"
|
|
4
|
+
|
|
5
|
+
export type BitcoinConnectionInfo = {
|
|
6
|
+
rpc?: {
|
|
7
|
+
enabled?: boolean
|
|
8
|
+
url: string
|
|
9
|
+
headers?: {
|
|
10
|
+
[key: string]: string
|
|
11
|
+
}
|
|
12
|
+
auth: any
|
|
13
|
+
}
|
|
14
|
+
api?: {
|
|
15
|
+
enabled?: boolean
|
|
16
|
+
provider: string
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
class BitcoinTransactionBuilder extends BaseTransactionBuilder {
|
|
20
|
+
btcInterface: BitcoinInterface
|
|
21
|
+
constructor(
|
|
22
|
+
connectionInfo: BitcoinConnectionInfo,
|
|
23
|
+
networkName: string,
|
|
24
|
+
network = bitcoin.networks.bitcoin,
|
|
25
|
+
) {
|
|
26
|
+
super({
|
|
27
|
+
network,
|
|
28
|
+
testnet: networkName?.includes("_testnet"),
|
|
29
|
+
dustLimit: 1000,
|
|
30
|
+
})
|
|
31
|
+
this.btcInterface = new BitcoinInterface(connectionInfo, networkName)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async _getUtxo(userAddress: string) {
|
|
35
|
+
let utxos = await this.btcInterface.getAddressesUtxo([userAddress])
|
|
36
|
+
return utxos.map((tx) => ({
|
|
37
|
+
hash: tx.txId as string,
|
|
38
|
+
value: +tx.value,
|
|
39
|
+
index: +tx.index,
|
|
40
|
+
}))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async _getFeeRate(speed: string) {
|
|
44
|
+
return this.btcInterface.getFeeRate(speed)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async _getTransactionHex(transactionId: string): Promise<string> {
|
|
48
|
+
return this.btcInterface.provider.getRawTransaction(transactionId)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async sendTx(txHex: string): Promise<string> {
|
|
52
|
+
let txId = await this.btcInterface.provider.sendRawTransaction(txHex)
|
|
53
|
+
return txId
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default BitcoinTransactionBuilder
|