@teleportdao/bitcoin 1.4.0 → 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-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,179 +1,179 @@
|
|
|
1
|
-
const { requestTypes: teleportRequestsType } = require("@teleportdao/configs").teleswap
|
|
2
|
-
const { BigNumber } = require("bignumber.js")
|
|
3
|
-
|
|
4
|
-
function parseTeleportAndExchangeRequest(data) {
|
|
5
|
-
let parsedData = {}
|
|
6
|
-
parsedData.requestType = "transfer"
|
|
7
|
-
|
|
8
|
-
let offset = 0
|
|
9
|
-
parsedData.chainId = Number(`0x${data.slice(offset, (offset += 2))}`) // 1 bytes
|
|
10
|
-
parsedData.appId = Number(`0x${data.slice(offset, (offset += 4))}`) // 2 bytes
|
|
11
|
-
parsedData.recipientAddress = `0x${data.slice(offset, (offset += 40))}` // 20 bytes
|
|
12
|
-
parsedData.percentageFee = Number(`0x${data.slice(offset, (offset += 4))}`) / 100 // 2 bytes
|
|
13
|
-
parsedData.speed = data.slice(offset, (offset += 2)) === "01" // 1 byte
|
|
14
|
-
if (data.length === offset) {
|
|
15
|
-
return {
|
|
16
|
-
status: true,
|
|
17
|
-
data: parsedData,
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
parsedData.requestType = "exchange"
|
|
22
|
-
parsedData.exchangeTokenAddress = `0x${data.slice(offset, (offset += 40))}` // 20 bytes
|
|
23
|
-
parsedData.outputAmount = new BigNumber(`0x${data.slice(offset, (offset += 56))}`).toFixed() // 28 bytes
|
|
24
|
-
parsedData.deadline = new BigNumber(`0x${data.slice(offset, (offset += 8))}`).toFixed() // 4 bytes
|
|
25
|
-
parsedData.isFixedToken = data.slice(offset, (offset += 2)) === "01" // 1 byte
|
|
26
|
-
if (data.length === offset) {
|
|
27
|
-
return {
|
|
28
|
-
status: true,
|
|
29
|
-
data: parsedData,
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
status: false,
|
|
35
|
-
message: `invalid OP_RETURN data for requestType: 'transfer or exchange'. invalid data length : ${data.length} - valid length : ${offset}`,
|
|
36
|
-
code: "INVALID_OP_RETURN",
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function parseLendAndBorrowRequest(data) {
|
|
41
|
-
let parsedData = {}
|
|
42
|
-
parsedData.requestType = "lend"
|
|
43
|
-
|
|
44
|
-
let offset = 0
|
|
45
|
-
parsedData.chainId = Number(`0x${data.slice(offset, (offset += 2))}`) // 1 bytes
|
|
46
|
-
parsedData.appId = Number(`0x${data.slice(offset, (offset += 4))}`) // 2 bytes
|
|
47
|
-
parsedData.recipientAddress = `0x${data.slice(offset, (offset += 40))}` // 20 bytes
|
|
48
|
-
parsedData.percentageFee = Number(`0x${data.slice(offset, (offset += 4))}`) / 100 // 2 bytes
|
|
49
|
-
parsedData.mode = Number(`0x${data.slice(offset, (offset += 2))}`) // 1 byte
|
|
50
|
-
if (data.length === offset) {
|
|
51
|
-
return {
|
|
52
|
-
status: true,
|
|
53
|
-
data: parsedData,
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
parsedData.requestType = "borrow"
|
|
57
|
-
parsedData.tokenAddress = `0x${data.slice(offset, (offset += 40))}` // 20 bytes
|
|
58
|
-
parsedData.borrowAmount = Number(`0x${data.slice(offset, (offset += 56))}`) // 28 bytes
|
|
59
|
-
if (data.length === offset) {
|
|
60
|
-
return {
|
|
61
|
-
status: true,
|
|
62
|
-
data: parsedData,
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return {
|
|
66
|
-
status: false,
|
|
67
|
-
message: `invalid OP_RETURN data for requestType: 'lend or borrow'. invalid data length : ${data.length} - valid length : ${offset}`,
|
|
68
|
-
code: "INVALID_OP_RETURN",
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
function parseRawRequest(opReturnData) {
|
|
73
|
-
let data = opReturnData.slice(2, 4) === "4c" ? opReturnData.slice(6) : opReturnData.slice(4)
|
|
74
|
-
|
|
75
|
-
// eslint-disable-next-line no-unused-vars
|
|
76
|
-
let _chainId = Number(`0x${data.slice(0, 2)}`) // 1 bytes
|
|
77
|
-
let appIdHex = data.slice(2, 6) // 2 bytes
|
|
78
|
-
if (!appIdHex) {
|
|
79
|
-
return {
|
|
80
|
-
status: false,
|
|
81
|
-
message: `invalid OP_RETURN data : ${data}`,
|
|
82
|
-
code: "INVALID_APP_ID",
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
let appId = Number(`0x${appIdHex}`) // 2 bytes
|
|
87
|
-
|
|
88
|
-
// get type base on appId
|
|
89
|
-
let requestType = teleportRequestsType.find(
|
|
90
|
-
(rs) => appId >= rs.appIdRange[0] && appId <= rs.appIdRange[1],
|
|
91
|
-
)?.type
|
|
92
|
-
|
|
93
|
-
switch (requestType) {
|
|
94
|
-
case "transfer":
|
|
95
|
-
case "exchange":
|
|
96
|
-
return parseTeleportAndExchangeRequest(data)
|
|
97
|
-
case "lend":
|
|
98
|
-
return parseLendAndBorrowRequest(data)
|
|
99
|
-
default:
|
|
100
|
-
return {
|
|
101
|
-
status: false,
|
|
102
|
-
message: `invalid appId : ${appId}`,
|
|
103
|
-
code: "INVALID_OP_RETURN",
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function validateRequestAndValue(
|
|
109
|
-
data,
|
|
110
|
-
requestOutputIndex,
|
|
111
|
-
value,
|
|
112
|
-
valueOutputIndex,
|
|
113
|
-
{ minTeleporterFeeAmount = 0 },
|
|
114
|
-
) {
|
|
115
|
-
if (!data) {
|
|
116
|
-
return {
|
|
117
|
-
status: false,
|
|
118
|
-
message: "no data to validate. it should not happen",
|
|
119
|
-
code: "NOT_ACCEPTED_BY_TELEPORTER",
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
if (+data.percentageFee > 100) {
|
|
124
|
-
return {
|
|
125
|
-
status: false,
|
|
126
|
-
message: `percentageFee greater than 100 is invalid. percentageFee: ${data.percentageFee}`,
|
|
127
|
-
code: "INVALID_FEE",
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if ((data.percentageFee / 100) * +value <= minTeleporterFeeAmount) {
|
|
132
|
-
return {
|
|
133
|
-
status: false,
|
|
134
|
-
message: `fee amount is less than or equal minimum teleporter fee amount.percentageFee: ${
|
|
135
|
-
data.percentageFee
|
|
136
|
-
} - value: ${value} - feeAmount ${((data.percentageFee / 100) * +value).toFixed(
|
|
137
|
-
8,
|
|
138
|
-
)} - minimumFee: ${minTeleporterFeeAmount}`,
|
|
139
|
-
code: "NOT_ACCEPTED_BY_TELEPORTER",
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
status: true,
|
|
145
|
-
data,
|
|
146
|
-
requestOutputIndex,
|
|
147
|
-
value,
|
|
148
|
-
valueOutputIndex,
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function checkAndParseProtocolRequest(vouts, address, config = { minTeleporterFeeAmount: 0 }) {
|
|
153
|
-
let requestOutputIndex = vouts.findIndex((vout_) => vout_.script.startsWith("6a"))
|
|
154
|
-
if (requestOutputIndex >= 0) {
|
|
155
|
-
let opReturnData = vouts[requestOutputIndex]?.script || null
|
|
156
|
-
let valueOutputIndex = vouts.findIndex((vout_) => vout_.address === address)?.value || 0
|
|
157
|
-
let value = valueOutputIndex >= 0 ? vouts[valueOutputIndex].value || 0 : 0
|
|
158
|
-
let dataResponse = parseRawRequest(opReturnData)
|
|
159
|
-
if (dataResponse.status) {
|
|
160
|
-
return validateRequestAndValue(
|
|
161
|
-
dataResponse.data,
|
|
162
|
-
requestOutputIndex,
|
|
163
|
-
value,
|
|
164
|
-
valueOutputIndex,
|
|
165
|
-
config,
|
|
166
|
-
)
|
|
167
|
-
}
|
|
168
|
-
return dataResponse
|
|
169
|
-
}
|
|
170
|
-
return {
|
|
171
|
-
status: false,
|
|
172
|
-
message: "transaction outputs should contain OP_RETURN",
|
|
173
|
-
code: "NO_OP_RETURN",
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
module.exports = {
|
|
178
|
-
checkAndParseProtocolRequest,
|
|
179
|
-
}
|
|
1
|
+
const { requestTypes: teleportRequestsType } = require("@teleportdao/configs").teleswap
|
|
2
|
+
const { BigNumber } = require("bignumber.js")
|
|
3
|
+
|
|
4
|
+
function parseTeleportAndExchangeRequest(data) {
|
|
5
|
+
let parsedData = {}
|
|
6
|
+
parsedData.requestType = "transfer"
|
|
7
|
+
|
|
8
|
+
let offset = 0
|
|
9
|
+
parsedData.chainId = Number(`0x${data.slice(offset, (offset += 2))}`) // 1 bytes
|
|
10
|
+
parsedData.appId = Number(`0x${data.slice(offset, (offset += 4))}`) // 2 bytes
|
|
11
|
+
parsedData.recipientAddress = `0x${data.slice(offset, (offset += 40))}` // 20 bytes
|
|
12
|
+
parsedData.percentageFee = Number(`0x${data.slice(offset, (offset += 4))}`) / 100 // 2 bytes
|
|
13
|
+
parsedData.speed = data.slice(offset, (offset += 2)) === "01" // 1 byte
|
|
14
|
+
if (data.length === offset) {
|
|
15
|
+
return {
|
|
16
|
+
status: true,
|
|
17
|
+
data: parsedData,
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
parsedData.requestType = "exchange"
|
|
22
|
+
parsedData.exchangeTokenAddress = `0x${data.slice(offset, (offset += 40))}` // 20 bytes
|
|
23
|
+
parsedData.outputAmount = new BigNumber(`0x${data.slice(offset, (offset += 56))}`).toFixed() // 28 bytes
|
|
24
|
+
parsedData.deadline = new BigNumber(`0x${data.slice(offset, (offset += 8))}`).toFixed() // 4 bytes
|
|
25
|
+
parsedData.isFixedToken = data.slice(offset, (offset += 2)) === "01" // 1 byte
|
|
26
|
+
if (data.length === offset) {
|
|
27
|
+
return {
|
|
28
|
+
status: true,
|
|
29
|
+
data: parsedData,
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
status: false,
|
|
35
|
+
message: `invalid OP_RETURN data for requestType: 'transfer or exchange'. invalid data length : ${data.length} - valid length : ${offset}`,
|
|
36
|
+
code: "INVALID_OP_RETURN",
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function parseLendAndBorrowRequest(data) {
|
|
41
|
+
let parsedData = {}
|
|
42
|
+
parsedData.requestType = "lend"
|
|
43
|
+
|
|
44
|
+
let offset = 0
|
|
45
|
+
parsedData.chainId = Number(`0x${data.slice(offset, (offset += 2))}`) // 1 bytes
|
|
46
|
+
parsedData.appId = Number(`0x${data.slice(offset, (offset += 4))}`) // 2 bytes
|
|
47
|
+
parsedData.recipientAddress = `0x${data.slice(offset, (offset += 40))}` // 20 bytes
|
|
48
|
+
parsedData.percentageFee = Number(`0x${data.slice(offset, (offset += 4))}`) / 100 // 2 bytes
|
|
49
|
+
parsedData.mode = Number(`0x${data.slice(offset, (offset += 2))}`) // 1 byte
|
|
50
|
+
if (data.length === offset) {
|
|
51
|
+
return {
|
|
52
|
+
status: true,
|
|
53
|
+
data: parsedData,
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
parsedData.requestType = "borrow"
|
|
57
|
+
parsedData.tokenAddress = `0x${data.slice(offset, (offset += 40))}` // 20 bytes
|
|
58
|
+
parsedData.borrowAmount = Number(`0x${data.slice(offset, (offset += 56))}`) // 28 bytes
|
|
59
|
+
if (data.length === offset) {
|
|
60
|
+
return {
|
|
61
|
+
status: true,
|
|
62
|
+
data: parsedData,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
status: false,
|
|
67
|
+
message: `invalid OP_RETURN data for requestType: 'lend or borrow'. invalid data length : ${data.length} - valid length : ${offset}`,
|
|
68
|
+
code: "INVALID_OP_RETURN",
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function parseRawRequest(opReturnData) {
|
|
73
|
+
let data = opReturnData.slice(2, 4) === "4c" ? opReturnData.slice(6) : opReturnData.slice(4)
|
|
74
|
+
|
|
75
|
+
// eslint-disable-next-line no-unused-vars
|
|
76
|
+
let _chainId = Number(`0x${data.slice(0, 2)}`) // 1 bytes
|
|
77
|
+
let appIdHex = data.slice(2, 6) // 2 bytes
|
|
78
|
+
if (!appIdHex) {
|
|
79
|
+
return {
|
|
80
|
+
status: false,
|
|
81
|
+
message: `invalid OP_RETURN data : ${data}`,
|
|
82
|
+
code: "INVALID_APP_ID",
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let appId = Number(`0x${appIdHex}`) // 2 bytes
|
|
87
|
+
|
|
88
|
+
// get type base on appId
|
|
89
|
+
let requestType = teleportRequestsType.find(
|
|
90
|
+
(rs) => appId >= rs.appIdRange[0] && appId <= rs.appIdRange[1],
|
|
91
|
+
)?.type
|
|
92
|
+
|
|
93
|
+
switch (requestType) {
|
|
94
|
+
case "transfer":
|
|
95
|
+
case "exchange":
|
|
96
|
+
return parseTeleportAndExchangeRequest(data)
|
|
97
|
+
case "lend":
|
|
98
|
+
return parseLendAndBorrowRequest(data)
|
|
99
|
+
default:
|
|
100
|
+
return {
|
|
101
|
+
status: false,
|
|
102
|
+
message: `invalid appId : ${appId}`,
|
|
103
|
+
code: "INVALID_OP_RETURN",
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function validateRequestAndValue(
|
|
109
|
+
data,
|
|
110
|
+
requestOutputIndex,
|
|
111
|
+
value,
|
|
112
|
+
valueOutputIndex,
|
|
113
|
+
{ minTeleporterFeeAmount = 0 },
|
|
114
|
+
) {
|
|
115
|
+
if (!data) {
|
|
116
|
+
return {
|
|
117
|
+
status: false,
|
|
118
|
+
message: "no data to validate. it should not happen",
|
|
119
|
+
code: "NOT_ACCEPTED_BY_TELEPORTER",
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (+data.percentageFee > 100) {
|
|
124
|
+
return {
|
|
125
|
+
status: false,
|
|
126
|
+
message: `percentageFee greater than 100 is invalid. percentageFee: ${data.percentageFee}`,
|
|
127
|
+
code: "INVALID_FEE",
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if ((data.percentageFee / 100) * +value <= minTeleporterFeeAmount) {
|
|
132
|
+
return {
|
|
133
|
+
status: false,
|
|
134
|
+
message: `fee amount is less than or equal minimum teleporter fee amount.percentageFee: ${
|
|
135
|
+
data.percentageFee
|
|
136
|
+
} - value: ${value} - feeAmount ${((data.percentageFee / 100) * +value).toFixed(
|
|
137
|
+
8,
|
|
138
|
+
)} - minimumFee: ${minTeleporterFeeAmount}`,
|
|
139
|
+
code: "NOT_ACCEPTED_BY_TELEPORTER",
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
status: true,
|
|
145
|
+
data,
|
|
146
|
+
requestOutputIndex,
|
|
147
|
+
value,
|
|
148
|
+
valueOutputIndex,
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function checkAndParseProtocolRequest(vouts, address, config = { minTeleporterFeeAmount: 0 }) {
|
|
153
|
+
let requestOutputIndex = vouts.findIndex((vout_) => vout_.script.startsWith("6a"))
|
|
154
|
+
if (requestOutputIndex >= 0) {
|
|
155
|
+
let opReturnData = vouts[requestOutputIndex]?.script || null
|
|
156
|
+
let valueOutputIndex = vouts.findIndex((vout_) => vout_.address === address)?.value || 0
|
|
157
|
+
let value = valueOutputIndex >= 0 ? vouts[valueOutputIndex].value || 0 : 0
|
|
158
|
+
let dataResponse = parseRawRequest(opReturnData)
|
|
159
|
+
if (dataResponse.status) {
|
|
160
|
+
return validateRequestAndValue(
|
|
161
|
+
dataResponse.data,
|
|
162
|
+
requestOutputIndex,
|
|
163
|
+
value,
|
|
164
|
+
valueOutputIndex,
|
|
165
|
+
config,
|
|
166
|
+
)
|
|
167
|
+
}
|
|
168
|
+
return dataResponse
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
status: false,
|
|
172
|
+
message: "transaction outputs should contain OP_RETURN",
|
|
173
|
+
code: "NO_OP_RETURN",
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
module.exports = {
|
|
178
|
+
checkAndParseProtocolRequest,
|
|
179
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// eslint-disable-next-line global-require
|
|
2
|
+
import { default as TeleportDaoPayment } from "./teleport-dao-payments"
|
|
3
|
+
import bitcoinUtils from "./bitcoin-utils"
|
|
4
|
+
import BitcoinInterface from "./bitcoin-interface"
|
|
5
|
+
import BitcoinInterfaceUtils from "./bitcoin-interface-utils"
|
|
6
|
+
import { BitcoinBase } from "./bitcoin-base"
|
|
7
|
+
|
|
8
|
+
export { TeleportDaoPayment, BitcoinInterface, BitcoinInterfaceUtils, bitcoinUtils, BitcoinBase }
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Psbt, crypto, Network, ECPair } from "bitcoinjs-lib"
|
|
2
|
+
// import ECPairFactory from "ecpair"
|
|
3
|
+
// import * as ecc from "tiny-secp256k1"
|
|
4
|
+
import { ExtendedUnsignedTransaction } from "../transaction-builder/transaction-builder"
|
|
5
|
+
// import * as bitcoin from "bitcoinjs-lib"
|
|
6
|
+
|
|
7
|
+
// bitcoin.initEccLib(ecc)
|
|
8
|
+
// // const bip32 = BIP32Factory(ecc)
|
|
9
|
+
// const ECPair = ECPairFactory(ecc)
|
|
10
|
+
|
|
11
|
+
// function tapTweakHash(pubKey: Buffer, h?: Buffer) {
|
|
12
|
+
// return crypto.taggedHash('TapTweak', Buffer.concat(h ? [pubKey, h] : [pubKey]))
|
|
13
|
+
// }
|
|
14
|
+
|
|
15
|
+
class BitcoinLikeSignTransaction {
|
|
16
|
+
network: Network
|
|
17
|
+
constructor(network: Network) {
|
|
18
|
+
this.network = network
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// tweakSigner(
|
|
22
|
+
// privateKey: Buffer,
|
|
23
|
+
// opts = {} as {
|
|
24
|
+
// [key: string]: Buffer
|
|
25
|
+
// },
|
|
26
|
+
// ) {
|
|
27
|
+
// let newPrv = privateKey
|
|
28
|
+
// let keyPair = ECPair.fromPrivateKey(privateKey, {
|
|
29
|
+
// network: this.network,
|
|
30
|
+
// compressed: true,
|
|
31
|
+
// })
|
|
32
|
+
|
|
33
|
+
// if (!keyPair.privateKey) throw new Error("private key not exist")
|
|
34
|
+
|
|
35
|
+
// if (keyPair.publicKey.toString("hex").startsWith("03")) {
|
|
36
|
+
// newPrv = ecc.privateNegate(keyPair.privateKey) as Buffer
|
|
37
|
+
// }
|
|
38
|
+
|
|
39
|
+
// const tweakedPrivateKey = ecc.privateAdd(
|
|
40
|
+
// newPrv,
|
|
41
|
+
// tapTweakHash(Buffer.from(keyPair.publicKey.toString("hex").slice(2), "hex"), opts?.tweakHash),
|
|
42
|
+
// )
|
|
43
|
+
// if (!tweakedPrivateKey) {
|
|
44
|
+
// throw new Error("Invalid tweaked private key!")
|
|
45
|
+
// }
|
|
46
|
+
|
|
47
|
+
// return ECPair.fromPrivateKey(Buffer.from(tweakedPrivateKey), {
|
|
48
|
+
// network: this.network,
|
|
49
|
+
// })
|
|
50
|
+
// }
|
|
51
|
+
|
|
52
|
+
// todo : change to psbt
|
|
53
|
+
async signPsbt(
|
|
54
|
+
unsignedPsbt: {
|
|
55
|
+
unsignedTransaction: string
|
|
56
|
+
},
|
|
57
|
+
privateKey: Buffer,
|
|
58
|
+
) {
|
|
59
|
+
const { network } = this
|
|
60
|
+
const keyPair = ECPair.fromPrivateKey(privateKey, {
|
|
61
|
+
network,
|
|
62
|
+
compressed: true,
|
|
63
|
+
})
|
|
64
|
+
const psbt = Psbt.fromBase64(unsignedPsbt.unsignedTransaction, {
|
|
65
|
+
network,
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
let numberOfInputs = psbt.inputCount
|
|
69
|
+
|
|
70
|
+
for (let i = 0; i < numberOfInputs; i += 1) {
|
|
71
|
+
await psbt.signInputAsync(i, keyPair)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// psbt.signAllInputs(keyPair)
|
|
75
|
+
const partialSigendPsbt = psbt.toBase64()
|
|
76
|
+
return partialSigendPsbt
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
finalizePsbts(psbtsBase64: string[] = []) {
|
|
80
|
+
const finals = psbtsBase64.map((psbtBase64) =>
|
|
81
|
+
Psbt.fromBase64(psbtBase64, { network: this.network }),
|
|
82
|
+
)
|
|
83
|
+
const psbt =
|
|
84
|
+
finals.length === 1 ? finals[0] : new Psbt({ network: this.network }).combine(...finals)
|
|
85
|
+
psbt.finalizeAllInputs()
|
|
86
|
+
|
|
87
|
+
// psbt.finalizeAllInputs()
|
|
88
|
+
// const tx = psbt.extractTransaction()
|
|
89
|
+
// const rawTx = tx.toBuffer()
|
|
90
|
+
// const hex = rawTx.toString("hex")
|
|
91
|
+
let finalizeTx = psbt.extractTransaction()
|
|
92
|
+
return finalizeTx.toHex()
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export default BitcoinLikeSignTransaction
|