@teleportdao/bitcoin 1.7.7 → 1.7.10
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/helper/teleswap-helper.d.ts.map +1 -1
- package/dist/helper/teleswap-helper.js +4 -3
- package/dist/helper/teleswap-helper.js.map +1 -1
- package/package.json +3 -3
- package/src/bitcoin-interface-ordinal.ts +181 -181
- package/src/bitcoin-interface-teleswap.ts +252 -252
- package/src/bitcoin-interface-utils.ts +59 -59
- package/src/bitcoin-interface.ts +247 -247
- package/src/bitcoin-utils.ts +591 -591
- package/src/bitcoin-wallet-base.ts +310 -310
- package/src/helper/brc20-helper.ts +181 -181
- package/src/helper/ordinal-helper.ts +118 -118
- package/src/helper/teleswap-helper.ts +11 -3
- package/src/index.ts +15 -15
- package/src/ordinal-wallet.ts +738 -738
- package/src/sign/index.ts +1 -1
- package/src/sign/sign-transaction.ts +108 -108
- package/src/teleswap-wallet.ts +152 -152
- package/src/transaction-builder/bitcoin-transaction-builder.ts +44 -44
- package/src/transaction-builder/index.ts +3 -3
- package/src/transaction-builder/ordinal-transaction-builder.ts +147 -147
- package/src/transaction-builder/transaction-builder.ts +706 -706
- package/src/type.ts +43 -43
- package/src/utils/networks.ts +33 -33
- package/src/utils/tools.ts +89 -89
- package/tsconfig.json +9 -9
- package/webpack.config.js +16 -16
- package/dist/bitcoin-base.d.ts +0 -93
- package/dist/bitcoin-base.d.ts.map +0 -1
- package/dist/bitcoin-base.js +0 -236
- package/dist/bitcoin-base.js.map +0 -1
- package/dist/helper/burn-request-helper.d.ts +0 -7
- package/dist/helper/burn-request-helper.d.ts.map +0 -1
- package/dist/helper/burn-request-helper.js +0 -26
- package/dist/helper/burn-request-helper.js.map +0 -1
- package/dist/helper/teleport-request-helper.d.ts +0 -47
- package/dist/helper/teleport-request-helper.d.ts.map +0 -1
- package/dist/helper/teleport-request-helper.js +0 -146
- package/dist/helper/teleport-request-helper.js.map +0 -1
- package/dist/teleport-dao-payments.d.ts +0 -76
- package/dist/teleport-dao-payments.d.ts.map +0 -1
- package/dist/teleport-dao-payments.js +0 -217
- package/dist/teleport-dao-payments.js.map +0 -1
|
@@ -1,310 +1,310 @@
|
|
|
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 BigNumber from "bignumber.js"
|
|
7
|
-
import { BitcoinTransactionBuilder } from "./transaction-builder"
|
|
8
|
-
import type { BitcoinConnectionInfo } from "./type"
|
|
9
|
-
|
|
10
|
-
import type { ExtendedUtxo, SignerInfo, Target } from "./transaction-builder/transaction-builder"
|
|
11
|
-
import BitcoinSign from "./sign/sign-transaction"
|
|
12
|
-
|
|
13
|
-
import { getPubKeyFromPrivateKeyHex } from "./bitcoin-utils"
|
|
14
|
-
import networks from "./utils/networks"
|
|
15
|
-
import { BitcoinInterface } from "./bitcoin-interface"
|
|
16
|
-
|
|
17
|
-
const bip32 = BIP32Factory(ecc)
|
|
18
|
-
|
|
19
|
-
export class BitcoinBaseWallet {
|
|
20
|
-
network: Network
|
|
21
|
-
hdWalletPath: {
|
|
22
|
-
p2pkh: string
|
|
23
|
-
p2wpkh: string
|
|
24
|
-
"p2sh-p2wpkh": string
|
|
25
|
-
p2sh: string
|
|
26
|
-
p2wsh: string
|
|
27
|
-
"p2sh-p2wsh": string
|
|
28
|
-
p2tr: string
|
|
29
|
-
}
|
|
30
|
-
transactionBuilder: BitcoinTransactionBuilder
|
|
31
|
-
btcInterface: BitcoinInterface
|
|
32
|
-
signer: BitcoinSign
|
|
33
|
-
currentAccount?: string
|
|
34
|
-
currentAccountType?: string
|
|
35
|
-
privateKey?: Buffer
|
|
36
|
-
publicKey?: Buffer
|
|
37
|
-
publicKeys?: Buffer[]
|
|
38
|
-
addressObj?: Payment
|
|
39
|
-
bitcoinAddress: string | undefined
|
|
40
|
-
constructor(
|
|
41
|
-
networkName: string,
|
|
42
|
-
connectionInfo: BitcoinConnectionInfo = {
|
|
43
|
-
api: {
|
|
44
|
-
provider: "BlockStream",
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
) {
|
|
48
|
-
this.network = networks[networkName]
|
|
49
|
-
this.hdWalletPath = hdWalletPath.bitcoin
|
|
50
|
-
|
|
51
|
-
this.transactionBuilder = new BitcoinTransactionBuilder(
|
|
52
|
-
connectionInfo,
|
|
53
|
-
networkName,
|
|
54
|
-
this.network,
|
|
55
|
-
)
|
|
56
|
-
this.btcInterface = this.transactionBuilder.btcInterface
|
|
57
|
-
|
|
58
|
-
this.signer = new BitcoinSign(this.network)
|
|
59
|
-
|
|
60
|
-
this.currentAccount = undefined
|
|
61
|
-
this.currentAccountType = undefined
|
|
62
|
-
|
|
63
|
-
this.privateKey = undefined
|
|
64
|
-
this.publicKey = undefined
|
|
65
|
-
// todo multisig
|
|
66
|
-
this.publicKeys = []
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
get signerInfo() {
|
|
70
|
-
return this.privateKey
|
|
71
|
-
? {
|
|
72
|
-
address: this.bitcoinAddress!,
|
|
73
|
-
publicKey: this.publicKey!.toString("hex"),
|
|
74
|
-
addressType: this.currentAccountType!,
|
|
75
|
-
}
|
|
76
|
-
: undefined
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
createTransactionInputsAndOutputs({
|
|
80
|
-
targets,
|
|
81
|
-
extendedUtxo,
|
|
82
|
-
changeAddress,
|
|
83
|
-
feeRate,
|
|
84
|
-
}: {
|
|
85
|
-
targets: Target[]
|
|
86
|
-
extendedUtxo: ExtendedUtxo[]
|
|
87
|
-
changeAddress: string
|
|
88
|
-
feeRate: number
|
|
89
|
-
fullAmount?: boolean
|
|
90
|
-
}) {
|
|
91
|
-
return this.transactionBuilder.helperHandleInputsAndOutputs({
|
|
92
|
-
targets,
|
|
93
|
-
extendedUtxo,
|
|
94
|
-
changeObject: {
|
|
95
|
-
address: changeAddress,
|
|
96
|
-
},
|
|
97
|
-
feeRate,
|
|
98
|
-
})
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
checkBalanceIsSufficient({
|
|
102
|
-
targets,
|
|
103
|
-
extendedUtxo,
|
|
104
|
-
changeAddress,
|
|
105
|
-
feeRate,
|
|
106
|
-
fullAmount = false,
|
|
107
|
-
}: {
|
|
108
|
-
targets: Target[]
|
|
109
|
-
extendedUtxo: ExtendedUtxo[]
|
|
110
|
-
changeAddress: string
|
|
111
|
-
feeRate: number
|
|
112
|
-
fullAmount?: boolean
|
|
113
|
-
}) {
|
|
114
|
-
try {
|
|
115
|
-
this.transactionBuilder.helperHandleInputsAndOutputs({
|
|
116
|
-
targets,
|
|
117
|
-
extendedUtxo,
|
|
118
|
-
changeObject: {
|
|
119
|
-
address: changeAddress,
|
|
120
|
-
},
|
|
121
|
-
feeRate,
|
|
122
|
-
})
|
|
123
|
-
return true
|
|
124
|
-
} catch (err) {
|
|
125
|
-
return false
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// todo : not completed
|
|
130
|
-
setMultiSigAccount(accountType = "p2sh") {
|
|
131
|
-
throw new Error("not supported yet")
|
|
132
|
-
|
|
133
|
-
/* eslint-disable no-unreachable */
|
|
134
|
-
// todo : not completed
|
|
135
|
-
switch (accountType) {
|
|
136
|
-
// case 'p2sh':
|
|
137
|
-
// this.currentAccount = ''
|
|
138
|
-
// break
|
|
139
|
-
// case 'p2wsh':
|
|
140
|
-
// this.currentAccount = ''
|
|
141
|
-
// break
|
|
142
|
-
// case 'p2sh-p2wsh':
|
|
143
|
-
// this.currentAccount = ''
|
|
144
|
-
// break
|
|
145
|
-
default:
|
|
146
|
-
throw new Error("accountType is incorrect")
|
|
147
|
-
}
|
|
148
|
-
this.currentAccountType = accountType
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
setAccountPrivateKey(privateKeyHex: string) {
|
|
152
|
-
this.privateKey = Buffer.from(privateKeyHex, "hex")
|
|
153
|
-
let publicKey = getPubKeyFromPrivateKeyHex(privateKeyHex, this.network)
|
|
154
|
-
this.publicKey = publicKey
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
setAccountPrivateKeyByMnemonic({
|
|
158
|
-
mnemonic,
|
|
159
|
-
mnemonicPassword = "",
|
|
160
|
-
index = 0,
|
|
161
|
-
walletNumber = 0,
|
|
162
|
-
addressType = "p2sh-p2wpkh",
|
|
163
|
-
}: {
|
|
164
|
-
mnemonic: string
|
|
165
|
-
mnemonicPassword?: string
|
|
166
|
-
index?: number
|
|
167
|
-
walletNumber?: number
|
|
168
|
-
addressType?: string
|
|
169
|
-
}) {
|
|
170
|
-
if (!bip39.validateMnemonic(mnemonic)) throw new Error("invalid mnemonic")
|
|
171
|
-
const seed = bip39.mnemonicToSeedSync(mnemonic, mnemonicPassword)
|
|
172
|
-
const node = bip32.fromSeed(seed)
|
|
173
|
-
|
|
174
|
-
let basePath = this.hdWalletPath[addressType as keyof typeof this.hdWalletPath]
|
|
175
|
-
if (!basePath) {
|
|
176
|
-
throw new Error("incorrect path or addressType")
|
|
177
|
-
}
|
|
178
|
-
const path = `${basePath}/${walletNumber}`
|
|
179
|
-
const account = node.derivePath(path)
|
|
180
|
-
const userKeyPair = account.derive(index)
|
|
181
|
-
this.setAccountPrivateKey(userKeyPair.privateKey!.toString("hex"))
|
|
182
|
-
return this.setAccount(addressType)
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
setAccountPublicKey(publicKeyHex: string) {
|
|
186
|
-
this.publicKey = Buffer.from(publicKeyHex, "hex")
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
setAccount(accountType = "p2pkh") {
|
|
190
|
-
if (!this.publicKey) {
|
|
191
|
-
throw new Error("account not initialized")
|
|
192
|
-
}
|
|
193
|
-
let addressObj = this.transactionBuilder.createAddressObject({
|
|
194
|
-
addressType: accountType,
|
|
195
|
-
publicKey: this.publicKey,
|
|
196
|
-
})
|
|
197
|
-
this.currentAccount = addressObj.address
|
|
198
|
-
this.currentAccountType = accountType
|
|
199
|
-
this.addressObj = addressObj
|
|
200
|
-
this.bitcoinAddress = addressObj.address
|
|
201
|
-
return addressObj.address
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
async getExtendedUtxo(input: SignerInfo) {
|
|
207
|
-
return this.transactionBuilder.getExtendedUtxo(input)
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
async send(
|
|
211
|
-
receiverAddress: string,
|
|
212
|
-
amount: string | number,
|
|
213
|
-
fullAmount = false,
|
|
214
|
-
speed: "normal" | "slow" | "fast" = "normal",
|
|
215
|
-
) {
|
|
216
|
-
if (!this.currentAccount || !this.currentAccountType || !this.publicKey || !this.privateKey) {
|
|
217
|
-
throw new Error("account not initialized")
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
let extendedUtxo = await this.getExtendedUtxo({
|
|
221
|
-
address: this.currentAccount,
|
|
222
|
-
addressType: this.currentAccountType,
|
|
223
|
-
publicKey: this.publicKey.toString("hex"),
|
|
224
|
-
})
|
|
225
|
-
if (!fullAmount && BigNumber(amount).isEqualTo(0))
|
|
226
|
-
throw new Error("incorrect amount. amount should be in satoshi")
|
|
227
|
-
let feeRate = await this.transactionBuilder._getFeeRate(speed)
|
|
228
|
-
let unsignedTx = await this.transactionBuilder.processUnsignedTransaction({
|
|
229
|
-
extendedUtxo,
|
|
230
|
-
targets: [
|
|
231
|
-
{
|
|
232
|
-
address: receiverAddress,
|
|
233
|
-
value: +amount,
|
|
234
|
-
},
|
|
235
|
-
],
|
|
236
|
-
changeAddress: this.currentAccount,
|
|
237
|
-
feeRate,
|
|
238
|
-
fullAmount,
|
|
239
|
-
})
|
|
240
|
-
let signedPsbt = await this.signer.signPsbt(unsignedTx, this.privateKey)
|
|
241
|
-
let signedTx = this.signer.finalizePsbts([signedPsbt])
|
|
242
|
-
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
243
|
-
return txId
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
async sendSignedPsbt(signedPsbt: string) {
|
|
247
|
-
let signedTx = this.signer.finalizePsbts([signedPsbt])
|
|
248
|
-
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
249
|
-
return txId
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
async sendSignedTx(signedTx: string) {
|
|
253
|
-
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
254
|
-
return txId
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
async sendMultiSignedPsbt(signedPsbts: string[] = []) {
|
|
258
|
-
let signedTx = this.signer.finalizePsbts(signedPsbts)
|
|
259
|
-
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
260
|
-
return txId
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
async increaseTransactionFeeUnsignedPsbt(
|
|
264
|
-
txId: string,
|
|
265
|
-
signerInfos: SignerInfo[],
|
|
266
|
-
extraExtendedUtxo: ExtendedUtxo[],
|
|
267
|
-
changeAddress: string,
|
|
268
|
-
staticFeeRate?: number,
|
|
269
|
-
) {
|
|
270
|
-
let transaction = await this.btcInterface.apiProvider.getTransaction(txId)
|
|
271
|
-
|
|
272
|
-
let extendedUtxo = transaction.vin.map((vi) => ({
|
|
273
|
-
signerInfo: signerInfos.find((s) => s.address === vi.address)!,
|
|
274
|
-
hash: vi.txId,
|
|
275
|
-
value: +vi.value,
|
|
276
|
-
index: vi.index,
|
|
277
|
-
}))
|
|
278
|
-
|
|
279
|
-
if (extendedUtxo.find((x) => !x.signerInfo?.address)) {
|
|
280
|
-
throw new Error("signerInfo not match")
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
let changeIndex = transaction.vout.findIndex((vo) =>
|
|
284
|
-
transaction.vin.find((vi) => vo.address === vi.address || vo.address === changeAddress),
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
const feeRate = staticFeeRate || (await this.transactionBuilder._getFeeRate("fast"))
|
|
288
|
-
|
|
289
|
-
let targets = transaction.vout
|
|
290
|
-
.filter((_, index) => index !== changeIndex)
|
|
291
|
-
.map((vo) =>
|
|
292
|
-
vo.address
|
|
293
|
-
? {
|
|
294
|
-
address: vo.address,
|
|
295
|
-
value: vo.value,
|
|
296
|
-
}
|
|
297
|
-
: {
|
|
298
|
-
script: Buffer.from(vo.script, "hex"),
|
|
299
|
-
value: vo.value,
|
|
300
|
-
},
|
|
301
|
-
)
|
|
302
|
-
return this.transactionBuilder.processUnsignedTransaction({
|
|
303
|
-
extendedUtxo: [...extendedUtxo, ...extraExtendedUtxo],
|
|
304
|
-
targets,
|
|
305
|
-
feeRate,
|
|
306
|
-
changeAddress: changeIndex >= 0 ? transaction.vout[changeIndex].address : changeAddress,
|
|
307
|
-
selectType: "inOrder",
|
|
308
|
-
})
|
|
309
|
-
}
|
|
310
|
-
}
|
|
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 BigNumber from "bignumber.js"
|
|
7
|
+
import { BitcoinTransactionBuilder } from "./transaction-builder"
|
|
8
|
+
import type { BitcoinConnectionInfo } from "./type"
|
|
9
|
+
|
|
10
|
+
import type { ExtendedUtxo, SignerInfo, Target } from "./transaction-builder/transaction-builder"
|
|
11
|
+
import BitcoinSign from "./sign/sign-transaction"
|
|
12
|
+
|
|
13
|
+
import { getPubKeyFromPrivateKeyHex } from "./bitcoin-utils"
|
|
14
|
+
import networks from "./utils/networks"
|
|
15
|
+
import { BitcoinInterface } from "./bitcoin-interface"
|
|
16
|
+
|
|
17
|
+
const bip32 = BIP32Factory(ecc)
|
|
18
|
+
|
|
19
|
+
export class BitcoinBaseWallet {
|
|
20
|
+
network: Network
|
|
21
|
+
hdWalletPath: {
|
|
22
|
+
p2pkh: string
|
|
23
|
+
p2wpkh: string
|
|
24
|
+
"p2sh-p2wpkh": string
|
|
25
|
+
p2sh: string
|
|
26
|
+
p2wsh: string
|
|
27
|
+
"p2sh-p2wsh": string
|
|
28
|
+
p2tr: string
|
|
29
|
+
}
|
|
30
|
+
transactionBuilder: BitcoinTransactionBuilder
|
|
31
|
+
btcInterface: BitcoinInterface
|
|
32
|
+
signer: BitcoinSign
|
|
33
|
+
currentAccount?: string
|
|
34
|
+
currentAccountType?: string
|
|
35
|
+
privateKey?: Buffer
|
|
36
|
+
publicKey?: Buffer
|
|
37
|
+
publicKeys?: Buffer[]
|
|
38
|
+
addressObj?: Payment
|
|
39
|
+
bitcoinAddress: string | undefined
|
|
40
|
+
constructor(
|
|
41
|
+
networkName: string,
|
|
42
|
+
connectionInfo: BitcoinConnectionInfo = {
|
|
43
|
+
api: {
|
|
44
|
+
provider: "BlockStream",
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
) {
|
|
48
|
+
this.network = networks[networkName]
|
|
49
|
+
this.hdWalletPath = hdWalletPath.bitcoin
|
|
50
|
+
|
|
51
|
+
this.transactionBuilder = new BitcoinTransactionBuilder(
|
|
52
|
+
connectionInfo,
|
|
53
|
+
networkName,
|
|
54
|
+
this.network,
|
|
55
|
+
)
|
|
56
|
+
this.btcInterface = this.transactionBuilder.btcInterface
|
|
57
|
+
|
|
58
|
+
this.signer = new BitcoinSign(this.network)
|
|
59
|
+
|
|
60
|
+
this.currentAccount = undefined
|
|
61
|
+
this.currentAccountType = undefined
|
|
62
|
+
|
|
63
|
+
this.privateKey = undefined
|
|
64
|
+
this.publicKey = undefined
|
|
65
|
+
// todo multisig
|
|
66
|
+
this.publicKeys = []
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get signerInfo() {
|
|
70
|
+
return this.privateKey
|
|
71
|
+
? {
|
|
72
|
+
address: this.bitcoinAddress!,
|
|
73
|
+
publicKey: this.publicKey!.toString("hex"),
|
|
74
|
+
addressType: this.currentAccountType!,
|
|
75
|
+
}
|
|
76
|
+
: undefined
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
createTransactionInputsAndOutputs({
|
|
80
|
+
targets,
|
|
81
|
+
extendedUtxo,
|
|
82
|
+
changeAddress,
|
|
83
|
+
feeRate,
|
|
84
|
+
}: {
|
|
85
|
+
targets: Target[]
|
|
86
|
+
extendedUtxo: ExtendedUtxo[]
|
|
87
|
+
changeAddress: string
|
|
88
|
+
feeRate: number
|
|
89
|
+
fullAmount?: boolean
|
|
90
|
+
}) {
|
|
91
|
+
return this.transactionBuilder.helperHandleInputsAndOutputs({
|
|
92
|
+
targets,
|
|
93
|
+
extendedUtxo,
|
|
94
|
+
changeObject: {
|
|
95
|
+
address: changeAddress,
|
|
96
|
+
},
|
|
97
|
+
feeRate,
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
checkBalanceIsSufficient({
|
|
102
|
+
targets,
|
|
103
|
+
extendedUtxo,
|
|
104
|
+
changeAddress,
|
|
105
|
+
feeRate,
|
|
106
|
+
fullAmount = false,
|
|
107
|
+
}: {
|
|
108
|
+
targets: Target[]
|
|
109
|
+
extendedUtxo: ExtendedUtxo[]
|
|
110
|
+
changeAddress: string
|
|
111
|
+
feeRate: number
|
|
112
|
+
fullAmount?: boolean
|
|
113
|
+
}) {
|
|
114
|
+
try {
|
|
115
|
+
this.transactionBuilder.helperHandleInputsAndOutputs({
|
|
116
|
+
targets,
|
|
117
|
+
extendedUtxo,
|
|
118
|
+
changeObject: {
|
|
119
|
+
address: changeAddress,
|
|
120
|
+
},
|
|
121
|
+
feeRate,
|
|
122
|
+
})
|
|
123
|
+
return true
|
|
124
|
+
} catch (err) {
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// todo : not completed
|
|
130
|
+
setMultiSigAccount(accountType = "p2sh") {
|
|
131
|
+
throw new Error("not supported yet")
|
|
132
|
+
|
|
133
|
+
/* eslint-disable no-unreachable */
|
|
134
|
+
// todo : not completed
|
|
135
|
+
switch (accountType) {
|
|
136
|
+
// case 'p2sh':
|
|
137
|
+
// this.currentAccount = ''
|
|
138
|
+
// break
|
|
139
|
+
// case 'p2wsh':
|
|
140
|
+
// this.currentAccount = ''
|
|
141
|
+
// break
|
|
142
|
+
// case 'p2sh-p2wsh':
|
|
143
|
+
// this.currentAccount = ''
|
|
144
|
+
// break
|
|
145
|
+
default:
|
|
146
|
+
throw new Error("accountType is incorrect")
|
|
147
|
+
}
|
|
148
|
+
this.currentAccountType = accountType
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
setAccountPrivateKey(privateKeyHex: string) {
|
|
152
|
+
this.privateKey = Buffer.from(privateKeyHex, "hex")
|
|
153
|
+
let publicKey = getPubKeyFromPrivateKeyHex(privateKeyHex, this.network)
|
|
154
|
+
this.publicKey = publicKey
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
setAccountPrivateKeyByMnemonic({
|
|
158
|
+
mnemonic,
|
|
159
|
+
mnemonicPassword = "",
|
|
160
|
+
index = 0,
|
|
161
|
+
walletNumber = 0,
|
|
162
|
+
addressType = "p2sh-p2wpkh",
|
|
163
|
+
}: {
|
|
164
|
+
mnemonic: string
|
|
165
|
+
mnemonicPassword?: string
|
|
166
|
+
index?: number
|
|
167
|
+
walletNumber?: number
|
|
168
|
+
addressType?: string
|
|
169
|
+
}) {
|
|
170
|
+
if (!bip39.validateMnemonic(mnemonic)) throw new Error("invalid mnemonic")
|
|
171
|
+
const seed = bip39.mnemonicToSeedSync(mnemonic, mnemonicPassword)
|
|
172
|
+
const node = bip32.fromSeed(seed)
|
|
173
|
+
|
|
174
|
+
let basePath = this.hdWalletPath[addressType as keyof typeof this.hdWalletPath]
|
|
175
|
+
if (!basePath) {
|
|
176
|
+
throw new Error("incorrect path or addressType")
|
|
177
|
+
}
|
|
178
|
+
const path = `${basePath}/${walletNumber}`
|
|
179
|
+
const account = node.derivePath(path)
|
|
180
|
+
const userKeyPair = account.derive(index)
|
|
181
|
+
this.setAccountPrivateKey(userKeyPair.privateKey!.toString("hex"))
|
|
182
|
+
return this.setAccount(addressType)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
setAccountPublicKey(publicKeyHex: string) {
|
|
186
|
+
this.publicKey = Buffer.from(publicKeyHex, "hex")
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
setAccount(accountType = "p2pkh") {
|
|
190
|
+
if (!this.publicKey) {
|
|
191
|
+
throw new Error("account not initialized")
|
|
192
|
+
}
|
|
193
|
+
let addressObj = this.transactionBuilder.createAddressObject({
|
|
194
|
+
addressType: accountType,
|
|
195
|
+
publicKey: this.publicKey,
|
|
196
|
+
})
|
|
197
|
+
this.currentAccount = addressObj.address
|
|
198
|
+
this.currentAccountType = accountType
|
|
199
|
+
this.addressObj = addressObj
|
|
200
|
+
this.bitcoinAddress = addressObj.address
|
|
201
|
+
return addressObj.address
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
//
|
|
205
|
+
|
|
206
|
+
async getExtendedUtxo(input: SignerInfo) {
|
|
207
|
+
return this.transactionBuilder.getExtendedUtxo(input)
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async send(
|
|
211
|
+
receiverAddress: string,
|
|
212
|
+
amount: string | number,
|
|
213
|
+
fullAmount = false,
|
|
214
|
+
speed: "normal" | "slow" | "fast" = "normal",
|
|
215
|
+
) {
|
|
216
|
+
if (!this.currentAccount || !this.currentAccountType || !this.publicKey || !this.privateKey) {
|
|
217
|
+
throw new Error("account not initialized")
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let extendedUtxo = await this.getExtendedUtxo({
|
|
221
|
+
address: this.currentAccount,
|
|
222
|
+
addressType: this.currentAccountType,
|
|
223
|
+
publicKey: this.publicKey.toString("hex"),
|
|
224
|
+
})
|
|
225
|
+
if (!fullAmount && BigNumber(amount).isEqualTo(0))
|
|
226
|
+
throw new Error("incorrect amount. amount should be in satoshi")
|
|
227
|
+
let feeRate = await this.transactionBuilder._getFeeRate(speed)
|
|
228
|
+
let unsignedTx = await this.transactionBuilder.processUnsignedTransaction({
|
|
229
|
+
extendedUtxo,
|
|
230
|
+
targets: [
|
|
231
|
+
{
|
|
232
|
+
address: receiverAddress,
|
|
233
|
+
value: +amount,
|
|
234
|
+
},
|
|
235
|
+
],
|
|
236
|
+
changeAddress: this.currentAccount,
|
|
237
|
+
feeRate,
|
|
238
|
+
fullAmount,
|
|
239
|
+
})
|
|
240
|
+
let signedPsbt = await this.signer.signPsbt(unsignedTx, this.privateKey)
|
|
241
|
+
let signedTx = this.signer.finalizePsbts([signedPsbt])
|
|
242
|
+
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
243
|
+
return txId
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async sendSignedPsbt(signedPsbt: string) {
|
|
247
|
+
let signedTx = this.signer.finalizePsbts([signedPsbt])
|
|
248
|
+
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
249
|
+
return txId
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async sendSignedTx(signedTx: string) {
|
|
253
|
+
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
254
|
+
return txId
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async sendMultiSignedPsbt(signedPsbts: string[] = []) {
|
|
258
|
+
let signedTx = this.signer.finalizePsbts(signedPsbts)
|
|
259
|
+
let txId = await this.transactionBuilder.sendTx(signedTx)
|
|
260
|
+
return txId
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async increaseTransactionFeeUnsignedPsbt(
|
|
264
|
+
txId: string,
|
|
265
|
+
signerInfos: SignerInfo[],
|
|
266
|
+
extraExtendedUtxo: ExtendedUtxo[],
|
|
267
|
+
changeAddress: string,
|
|
268
|
+
staticFeeRate?: number,
|
|
269
|
+
) {
|
|
270
|
+
let transaction = await this.btcInterface.apiProvider.getTransaction(txId)
|
|
271
|
+
|
|
272
|
+
let extendedUtxo = transaction.vin.map((vi) => ({
|
|
273
|
+
signerInfo: signerInfos.find((s) => s.address === vi.address)!,
|
|
274
|
+
hash: vi.txId,
|
|
275
|
+
value: +vi.value,
|
|
276
|
+
index: vi.index,
|
|
277
|
+
}))
|
|
278
|
+
|
|
279
|
+
if (extendedUtxo.find((x) => !x.signerInfo?.address)) {
|
|
280
|
+
throw new Error("signerInfo not match")
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
let changeIndex = transaction.vout.findIndex((vo) =>
|
|
284
|
+
transaction.vin.find((vi) => vo.address === vi.address || vo.address === changeAddress),
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
const feeRate = staticFeeRate || (await this.transactionBuilder._getFeeRate("fast"))
|
|
288
|
+
|
|
289
|
+
let targets = transaction.vout
|
|
290
|
+
.filter((_, index) => index !== changeIndex)
|
|
291
|
+
.map((vo) =>
|
|
292
|
+
vo.address
|
|
293
|
+
? {
|
|
294
|
+
address: vo.address,
|
|
295
|
+
value: vo.value,
|
|
296
|
+
}
|
|
297
|
+
: {
|
|
298
|
+
script: Buffer.from(vo.script, "hex"),
|
|
299
|
+
value: vo.value,
|
|
300
|
+
},
|
|
301
|
+
)
|
|
302
|
+
return this.transactionBuilder.processUnsignedTransaction({
|
|
303
|
+
extendedUtxo: [...extendedUtxo, ...extraExtendedUtxo],
|
|
304
|
+
targets,
|
|
305
|
+
feeRate,
|
|
306
|
+
changeAddress: changeIndex >= 0 ? transaction.vout[changeIndex].address : changeAddress,
|
|
307
|
+
selectType: "inOrder",
|
|
308
|
+
})
|
|
309
|
+
}
|
|
310
|
+
}
|