mainnet-js 1.1.0 → 1.1.2
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/index.html +1 -1
- package/dist/{mainnet-1.1.0.js → mainnet-1.1.2.js} +4 -4
- package/dist/module/libauth.d.ts +1 -1
- package/dist/module/libauth.d.ts.map +1 -1
- package/dist/module/libauth.js +1 -1
- package/dist/module/libauth.js.map +1 -1
- package/dist/module/transaction/Wif.d.ts +42 -7
- package/dist/module/transaction/Wif.d.ts.map +1 -1
- package/dist/module/transaction/Wif.js +127 -106
- package/dist/module/transaction/Wif.js.map +1 -1
- package/dist/module/wallet/Slp.d.ts.map +1 -1
- package/dist/module/wallet/Slp.js +11 -1
- package/dist/module/wallet/Slp.js.map +1 -1
- package/dist/module/wallet/Wif.d.ts +14 -6
- package/dist/module/wallet/Wif.d.ts.map +1 -1
- package/dist/module/wallet/Wif.js +131 -59
- package/dist/module/wallet/Wif.js.map +1 -1
- package/dist/module/wallet/interface.d.ts +2 -0
- package/dist/module/wallet/interface.d.ts.map +1 -1
- package/dist/module/wallet/model.d.ts +4 -0
- package/dist/module/wallet/model.d.ts.map +1 -1
- package/dist/module/wallet/model.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/libauth.ts +1 -0
- package/src/transaction/Wif.ts +200 -154
- package/src/wallet/Cashtokens.test.headless.js +162 -1
- package/src/wallet/Cashtokens.test.ts +338 -2
- package/src/wallet/Slp.ts +10 -7
- package/src/wallet/Wif.test.ts +101 -1
- package/src/wallet/Wif.ts +185 -98
- package/src/wallet/interface.ts +2 -0
- package/src/wallet/model.ts +6 -0
package/src/transaction/Wif.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
CompilationContextBCH,
|
|
13
13
|
Output,
|
|
14
14
|
hexToBin,
|
|
15
|
+
verifyTransactionTokens,
|
|
15
16
|
} from "@bitauth/libauth";
|
|
16
17
|
import { NFTCapability, TokenI, UtxoI } from "../interface.js";
|
|
17
18
|
import { allocateFee } from "./allocateFee.js";
|
|
@@ -29,16 +30,27 @@ import { sumUtxoValue } from "../util/sumUtxoValue.js";
|
|
|
29
30
|
import { FeePaidByEnum } from "../wallet/enum.js";
|
|
30
31
|
|
|
31
32
|
// Build a transaction for a p2pkh transaction for a non HD wallet
|
|
32
|
-
export async function buildP2pkhNonHdTransaction(
|
|
33
|
-
inputs
|
|
34
|
-
outputs
|
|
35
|
-
signingKey
|
|
36
|
-
|
|
33
|
+
export async function buildP2pkhNonHdTransaction({
|
|
34
|
+
inputs,
|
|
35
|
+
outputs,
|
|
36
|
+
signingKey,
|
|
37
|
+
sourceAddress,
|
|
38
|
+
fee = 0,
|
|
37
39
|
discardChange = false,
|
|
38
|
-
slpOutputs
|
|
39
|
-
feePaidBy
|
|
40
|
-
changeAddress
|
|
41
|
-
|
|
40
|
+
slpOutputs = [],
|
|
41
|
+
feePaidBy = FeePaidByEnum.change,
|
|
42
|
+
changeAddress = "",
|
|
43
|
+
}: {
|
|
44
|
+
inputs: UtxoI[];
|
|
45
|
+
outputs: Array<SendRequest | TokenSendRequest | OpReturnData>;
|
|
46
|
+
signingKey: Uint8Array;
|
|
47
|
+
sourceAddress: string;
|
|
48
|
+
fee?: number;
|
|
49
|
+
discardChange?: boolean;
|
|
50
|
+
slpOutputs?: Output[];
|
|
51
|
+
feePaidBy?: FeePaidByEnum;
|
|
52
|
+
changeAddress?: string;
|
|
53
|
+
}) {
|
|
42
54
|
if (!signingKey) {
|
|
43
55
|
throw new Error("Missing signing key when building transaction");
|
|
44
56
|
}
|
|
@@ -59,7 +71,7 @@ export async function buildP2pkhNonHdTransaction(
|
|
|
59
71
|
|
|
60
72
|
outputs = allocateFee(outputs, fee, feePaidBy, changeAmount);
|
|
61
73
|
|
|
62
|
-
|
|
74
|
+
const lockedOutputs = await prepareOutputs(outputs);
|
|
63
75
|
|
|
64
76
|
if (discardChange !== true) {
|
|
65
77
|
if (changeAmount > DUST_UTXO_THRESHOLD) {
|
|
@@ -85,31 +97,56 @@ export async function buildP2pkhNonHdTransaction(
|
|
|
85
97
|
}
|
|
86
98
|
}
|
|
87
99
|
|
|
88
|
-
|
|
100
|
+
const { preparedInputs, sourceOutputs } = prepareInputs({
|
|
101
|
+
inputs,
|
|
102
|
+
compiler,
|
|
103
|
+
signingKey,
|
|
104
|
+
sourceAddress,
|
|
105
|
+
});
|
|
89
106
|
const result = generateTransaction({
|
|
90
|
-
inputs:
|
|
107
|
+
inputs: preparedInputs,
|
|
91
108
|
locktime: 0,
|
|
92
109
|
outputs: [...slpOutputs, ...lockedOutputs],
|
|
93
110
|
version: 2,
|
|
94
111
|
});
|
|
95
|
-
|
|
112
|
+
|
|
113
|
+
if (!result.success) {
|
|
114
|
+
throw Error("Error building transaction with fee");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const tokenValidationResult = verifyTransactionTokens(
|
|
118
|
+
result.transaction,
|
|
119
|
+
sourceOutputs
|
|
120
|
+
);
|
|
121
|
+
if (tokenValidationResult !== true && fee > 0) {
|
|
122
|
+
throw tokenValidationResult;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return { transaction: result.transaction, sourceOutputs: sourceOutputs };
|
|
96
126
|
}
|
|
97
127
|
|
|
98
|
-
export function prepareInputs(
|
|
99
|
-
inputs
|
|
128
|
+
export function prepareInputs({
|
|
129
|
+
inputs,
|
|
130
|
+
compiler,
|
|
131
|
+
signingKey,
|
|
132
|
+
sourceAddress,
|
|
133
|
+
}: {
|
|
134
|
+
inputs: UtxoI[];
|
|
100
135
|
compiler: Compiler<
|
|
101
136
|
CompilationContextBCH,
|
|
102
137
|
AnyCompilerConfiguration<CompilationContextBCH>,
|
|
103
138
|
AuthenticationProgramStateCommon
|
|
104
|
-
|
|
105
|
-
signingKey: Uint8Array
|
|
106
|
-
|
|
107
|
-
|
|
139
|
+
>;
|
|
140
|
+
signingKey: Uint8Array;
|
|
141
|
+
sourceAddress: string;
|
|
142
|
+
}) {
|
|
143
|
+
const preparedInputs: any[] = [];
|
|
144
|
+
const sourceOutputs: any[] = [];
|
|
108
145
|
for (const i of inputs) {
|
|
109
146
|
const utxoTxnValue = i.satoshis;
|
|
110
147
|
const utxoIndex = i.vout;
|
|
111
148
|
// slice will create a clone of the array
|
|
112
|
-
|
|
149
|
+
const utxoOutpointTransactionHash = new Uint8Array(
|
|
113
150
|
i.txid.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))
|
|
114
151
|
);
|
|
115
152
|
// reverse the cloned copy
|
|
@@ -122,30 +159,51 @@ export function prepareInputs(
|
|
|
122
159
|
amount: BigInt(i.token.amount),
|
|
123
160
|
category: hexToBin(i.token.tokenId),
|
|
124
161
|
nft:
|
|
125
|
-
i.token.capability || i.token.commitment
|
|
162
|
+
i.token.capability !== undefined || i.token.commitment !== undefined
|
|
126
163
|
? {
|
|
127
164
|
capability: i.token.capability,
|
|
128
|
-
commitment:
|
|
165
|
+
commitment:
|
|
166
|
+
i.token.commitment !== undefined &&
|
|
167
|
+
hexToBin(i.token.commitment!),
|
|
129
168
|
}
|
|
130
169
|
: undefined,
|
|
131
170
|
};
|
|
132
|
-
|
|
171
|
+
const newInput = signingKey?.length
|
|
172
|
+
? {
|
|
173
|
+
outpointIndex: utxoIndex,
|
|
174
|
+
outpointTransactionHash: utxoOutpointTransactionHash,
|
|
175
|
+
sequenceNumber: 0,
|
|
176
|
+
unlockingBytecode: {
|
|
177
|
+
compiler,
|
|
178
|
+
data: {
|
|
179
|
+
keys: { privateKeys: { key: signingKey } },
|
|
180
|
+
},
|
|
181
|
+
valueSatoshis: BigInt(utxoTxnValue),
|
|
182
|
+
script: "unlock",
|
|
183
|
+
token: libAuthToken,
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
: {
|
|
187
|
+
outpointIndex: utxoIndex,
|
|
188
|
+
outpointTransactionHash: utxoOutpointTransactionHash,
|
|
189
|
+
sequenceNumber: 0,
|
|
190
|
+
unlockingBytecode: Uint8Array.from([]),
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
preparedInputs.push(newInput);
|
|
194
|
+
sourceOutputs.push({
|
|
133
195
|
outpointIndex: utxoIndex,
|
|
134
196
|
outpointTransactionHash: utxoOutpointTransactionHash,
|
|
135
197
|
sequenceNumber: 0,
|
|
136
|
-
unlockingBytecode:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
token: libAuthToken,
|
|
144
|
-
},
|
|
145
|
-
};
|
|
146
|
-
signedInputs.push(newInput);
|
|
198
|
+
unlockingBytecode: Uint8Array.from([]),
|
|
199
|
+
|
|
200
|
+
// additional info for sourceOutputs
|
|
201
|
+
lockingBytecode: cashAddressToLockingBytecode(sourceAddress),
|
|
202
|
+
valueSatoshis: BigInt(utxoTxnValue),
|
|
203
|
+
token: libAuthToken,
|
|
204
|
+
});
|
|
147
205
|
}
|
|
148
|
-
return
|
|
206
|
+
return { preparedInputs, sourceOutputs };
|
|
149
207
|
}
|
|
150
208
|
|
|
151
209
|
/**
|
|
@@ -156,13 +214,12 @@ export function prepareInputs(
|
|
|
156
214
|
* @returns A promise to a list of unspent outputs
|
|
157
215
|
*/
|
|
158
216
|
export async function prepareOutputs(
|
|
159
|
-
outputs: Array<SendRequest | TokenSendRequest | OpReturnData
|
|
160
|
-
inputs: UtxoI[]
|
|
217
|
+
outputs: Array<SendRequest | TokenSendRequest | OpReturnData>
|
|
161
218
|
) {
|
|
162
|
-
|
|
219
|
+
const lockedOutputs: Output[] = [];
|
|
163
220
|
for (const output of outputs) {
|
|
164
221
|
if (output instanceof TokenSendRequest) {
|
|
165
|
-
lockedOutputs.push(prepareTokenOutputs(output
|
|
222
|
+
lockedOutputs.push(prepareTokenOutputs(output));
|
|
166
223
|
continue;
|
|
167
224
|
}
|
|
168
225
|
|
|
@@ -207,48 +264,9 @@ export function prepareOpReturnOutput(request: OpReturnData): Output {
|
|
|
207
264
|
*
|
|
208
265
|
* @returns A libauth Output
|
|
209
266
|
*/
|
|
210
|
-
export function prepareTokenOutputs(
|
|
211
|
-
request: TokenSendRequest,
|
|
212
|
-
inputs: UtxoI[]
|
|
213
|
-
): Output {
|
|
267
|
+
export function prepareTokenOutputs(request: TokenSendRequest): Output {
|
|
214
268
|
const token: TokenI = request;
|
|
215
|
-
const
|
|
216
|
-
let satValue = 0;
|
|
217
|
-
if (isGenesis) {
|
|
218
|
-
const genesisInputs = inputs.filter((val) => val.vout === 0);
|
|
219
|
-
if (genesisInputs.length === 0) {
|
|
220
|
-
throw new Error(
|
|
221
|
-
"No suitable inputs with vout=0 available for new token genesis"
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
token.tokenId = genesisInputs[0].txid;
|
|
225
|
-
satValue = request.value || 1000;
|
|
226
|
-
(request as any)._isGenesis = true;
|
|
227
|
-
} else {
|
|
228
|
-
const tokenInputs = inputs.filter(
|
|
229
|
-
(val) => val.token?.tokenId === request.tokenId
|
|
230
|
-
);
|
|
231
|
-
if (!tokenInputs.length) {
|
|
232
|
-
throw new Error(`No token utxos available to send ${request.tokenId}`);
|
|
233
|
-
}
|
|
234
|
-
if (!token.capability && tokenInputs[0].token?.capability) {
|
|
235
|
-
token.capability = tokenInputs[0].token!.capability;
|
|
236
|
-
}
|
|
237
|
-
if (!token.commitment && tokenInputs[0].token?.commitment) {
|
|
238
|
-
token.commitment = tokenInputs[0].token!.commitment;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (
|
|
242
|
-
tokenInputs[0].token?.capability === NFTCapability.none &&
|
|
243
|
-
tokenInputs[0].token?.commitment !== token.commitment
|
|
244
|
-
) {
|
|
245
|
-
throw new Error("Can not change the commitment of an immutable token");
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
satValue = request.value || tokenInputs[0].satoshis;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
let outputLockingBytecode = cashAddressToLockingBytecode(request.cashaddr);
|
|
269
|
+
const outputLockingBytecode = cashAddressToLockingBytecode(request.cashaddr);
|
|
252
270
|
if (typeof outputLockingBytecode === "string")
|
|
253
271
|
throw new Error(outputLockingBytecode);
|
|
254
272
|
|
|
@@ -256,17 +274,18 @@ export function prepareTokenOutputs(
|
|
|
256
274
|
amount: BigInt(token.amount),
|
|
257
275
|
category: hexToBin(token.tokenId),
|
|
258
276
|
nft:
|
|
259
|
-
token.capability || token.commitment
|
|
277
|
+
token.capability !== undefined || token.commitment !== undefined
|
|
260
278
|
? {
|
|
261
279
|
capability: token.capability,
|
|
262
|
-
commitment:
|
|
280
|
+
commitment:
|
|
281
|
+
token.commitment !== undefined && hexToBin(token.commitment!),
|
|
263
282
|
}
|
|
264
283
|
: undefined,
|
|
265
284
|
};
|
|
266
285
|
|
|
267
286
|
return {
|
|
268
287
|
lockingBytecode: outputLockingBytecode.bytecode,
|
|
269
|
-
valueSatoshis: BigInt(
|
|
288
|
+
valueSatoshis: BigInt(request.value || 1000),
|
|
270
289
|
token: libAuthToken,
|
|
271
290
|
} as Output;
|
|
272
291
|
}
|
|
@@ -286,61 +305,72 @@ export async function getSuitableUtxos(
|
|
|
286
305
|
bestHeight: number,
|
|
287
306
|
feePaidBy: FeePaidByEnum,
|
|
288
307
|
requests: SendRequestType[],
|
|
289
|
-
ensureUtxos: UtxoI[] = []
|
|
308
|
+
ensureUtxos: UtxoI[] = [],
|
|
309
|
+
tokenOperation: "send" | "genesis" | "mint" | "burn" = "send"
|
|
290
310
|
): Promise<UtxoI[]> {
|
|
291
|
-
|
|
311
|
+
const suitableUtxos: UtxoI[] = [...ensureUtxos];
|
|
292
312
|
let amountAvailable = BigInt(0);
|
|
293
|
-
const tokenAmountsRequired: any[] = [];
|
|
294
313
|
const tokenRequests = requests.filter(
|
|
295
314
|
(val) => val instanceof TokenSendRequest
|
|
296
315
|
) as TokenSendRequest[];
|
|
297
316
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
)
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
317
|
+
const availableInputs = inputs.slice();
|
|
318
|
+
|
|
319
|
+
// find matching utxos for token transfers
|
|
320
|
+
if (tokenOperation === "send") {
|
|
321
|
+
for (const request of tokenRequests) {
|
|
322
|
+
const tokenInputs = availableInputs.filter(
|
|
323
|
+
(val) => val.token?.tokenId === request.tokenId
|
|
324
|
+
);
|
|
325
|
+
const sameCommitmentTokens = [...suitableUtxos, ...tokenInputs].filter(
|
|
326
|
+
(val) =>
|
|
327
|
+
val.token?.capability === request.capability &&
|
|
328
|
+
val.token?.commitment === request.commitment
|
|
329
|
+
);
|
|
330
|
+
if (sameCommitmentTokens.length) {
|
|
331
|
+
const input = sameCommitmentTokens[0];
|
|
332
|
+
const index = availableInputs.indexOf(input);
|
|
333
|
+
if (index !== -1) {
|
|
334
|
+
suitableUtxos.push(input);
|
|
335
|
+
availableInputs.splice(index, 1);
|
|
336
|
+
amountAvailable += BigInt(input.satoshis);
|
|
337
|
+
}
|
|
316
338
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (
|
|
343
|
+
request.capability === NFTCapability.minting ||
|
|
344
|
+
request.capability === NFTCapability.mutable
|
|
345
|
+
) {
|
|
346
|
+
const changeCommitmentTokens = [
|
|
347
|
+
...suitableUtxos,
|
|
348
|
+
...tokenInputs,
|
|
349
|
+
].filter((val) => val.token?.capability === request.capability);
|
|
350
|
+
if (changeCommitmentTokens.length) {
|
|
351
|
+
const input = changeCommitmentTokens[0];
|
|
352
|
+
const index = availableInputs.indexOf(input);
|
|
353
|
+
if (index !== -1) {
|
|
354
|
+
suitableUtxos.push(input);
|
|
355
|
+
availableInputs.splice(index, 1);
|
|
356
|
+
amountAvailable += BigInt(input.satoshis);
|
|
357
|
+
}
|
|
358
|
+
continue;
|
|
331
359
|
}
|
|
332
360
|
}
|
|
361
|
+
throw Error(
|
|
362
|
+
`No suitable token utxos available to send token with id "${request.tokenId}", capability "${request.capability}", commitment "${request.commitment}"`
|
|
363
|
+
);
|
|
333
364
|
}
|
|
334
365
|
}
|
|
335
|
-
|
|
336
366
|
// find plain bch outputs
|
|
337
|
-
for (const u of
|
|
367
|
+
for (const u of availableInputs) {
|
|
338
368
|
if (u.token) {
|
|
339
369
|
continue;
|
|
340
370
|
}
|
|
341
371
|
|
|
342
372
|
if (u.coinbase && u.height && bestHeight) {
|
|
343
|
-
|
|
373
|
+
const age = bestHeight - u.height;
|
|
344
374
|
if (age > 100) {
|
|
345
375
|
suitableUtxos.push(u);
|
|
346
376
|
amountAvailable += BigInt(u.satoshis);
|
|
@@ -356,8 +386,11 @@ export async function getSuitableUtxos(
|
|
|
356
386
|
}
|
|
357
387
|
|
|
358
388
|
const addEnsured = (suitableUtxos) => {
|
|
359
|
-
return [...
|
|
360
|
-
(val, index, array) =>
|
|
389
|
+
return [...ensureUtxos, ...suitableUtxos].filter(
|
|
390
|
+
(val, index, array) =>
|
|
391
|
+
array.findIndex(
|
|
392
|
+
(other) => other.txid === val.txid && other.vout === val.vout
|
|
393
|
+
) === index
|
|
361
394
|
);
|
|
362
395
|
};
|
|
363
396
|
|
|
@@ -370,7 +403,7 @@ export async function getSuitableUtxos(
|
|
|
370
403
|
if (typeof amountRequired === "undefined") {
|
|
371
404
|
return addEnsured(suitableUtxos);
|
|
372
405
|
} else if (amountAvailable < amountRequired) {
|
|
373
|
-
|
|
406
|
+
const e = Error(
|
|
374
407
|
`Amount required was not met, ${amountRequired} satoshis needed, ${amountAvailable} satoshis available`
|
|
375
408
|
);
|
|
376
409
|
e["data"] = {
|
|
@@ -387,6 +420,7 @@ export async function getFeeAmount({
|
|
|
387
420
|
utxos,
|
|
388
421
|
sendRequests,
|
|
389
422
|
privateKey,
|
|
423
|
+
sourceAddress,
|
|
390
424
|
relayFeePerByteInSatoshi,
|
|
391
425
|
slpOutputs,
|
|
392
426
|
feePaidBy,
|
|
@@ -395,6 +429,7 @@ export async function getFeeAmount({
|
|
|
395
429
|
utxos: UtxoI[];
|
|
396
430
|
sendRequests: Array<SendRequest | TokenSendRequest | OpReturnData>;
|
|
397
431
|
privateKey: Uint8Array;
|
|
432
|
+
sourceAddress: string;
|
|
398
433
|
relayFeePerByteInSatoshi: number;
|
|
399
434
|
slpOutputs: Output[];
|
|
400
435
|
feePaidBy: FeePaidByEnum;
|
|
@@ -403,15 +438,18 @@ export async function getFeeAmount({
|
|
|
403
438
|
// build transaction
|
|
404
439
|
if (utxos) {
|
|
405
440
|
// Build the transaction to get the approximate size
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
441
|
+
const { encodedTransaction: draftTransaction } =
|
|
442
|
+
await buildEncodedTransaction({
|
|
443
|
+
inputs: utxos,
|
|
444
|
+
outputs: sendRequests,
|
|
445
|
+
signingKey: privateKey,
|
|
446
|
+
sourceAddress,
|
|
447
|
+
fee: 0, //DUST_UTXO_THRESHOLD
|
|
448
|
+
discardChange: discardChange ?? false,
|
|
449
|
+
slpOutputs,
|
|
450
|
+
feePaidBy,
|
|
451
|
+
changeAddress: "",
|
|
452
|
+
});
|
|
415
453
|
|
|
416
454
|
return draftTransaction.length * relayFeePerByteInSatoshi + 1;
|
|
417
455
|
} else {
|
|
@@ -422,30 +460,38 @@ export async function getFeeAmount({
|
|
|
422
460
|
}
|
|
423
461
|
|
|
424
462
|
// Build encoded transaction
|
|
425
|
-
export async function buildEncodedTransaction(
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
463
|
+
export async function buildEncodedTransaction({
|
|
464
|
+
inputs,
|
|
465
|
+
outputs,
|
|
466
|
+
signingKey,
|
|
467
|
+
sourceAddress,
|
|
468
|
+
fee = 0,
|
|
430
469
|
discardChange = false,
|
|
431
|
-
slpOutputs
|
|
432
|
-
feePaidBy
|
|
433
|
-
changeAddress
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
470
|
+
slpOutputs = [],
|
|
471
|
+
feePaidBy = FeePaidByEnum.change,
|
|
472
|
+
changeAddress = "",
|
|
473
|
+
}: {
|
|
474
|
+
inputs: UtxoI[];
|
|
475
|
+
outputs: Array<SendRequest | TokenSendRequest | OpReturnData>;
|
|
476
|
+
signingKey: Uint8Array;
|
|
477
|
+
sourceAddress: string;
|
|
478
|
+
fee?: number;
|
|
479
|
+
discardChange?: boolean;
|
|
480
|
+
slpOutputs?: Output[];
|
|
481
|
+
feePaidBy?: FeePaidByEnum;
|
|
482
|
+
changeAddress?: string;
|
|
483
|
+
}) {
|
|
484
|
+
const { transaction, sourceOutputs } = await buildP2pkhNonHdTransaction({
|
|
485
|
+
inputs,
|
|
486
|
+
outputs,
|
|
487
|
+
signingKey,
|
|
488
|
+
sourceAddress,
|
|
439
489
|
fee,
|
|
440
490
|
discardChange,
|
|
441
491
|
slpOutputs,
|
|
442
492
|
feePaidBy,
|
|
443
|
-
changeAddress
|
|
444
|
-
);
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
return encodeTransaction(txn.transaction);
|
|
448
|
-
} else {
|
|
449
|
-
throw Error("Error building transaction with fee");
|
|
450
|
-
}
|
|
493
|
+
changeAddress,
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
return { encodedTransaction: encodeTransaction(transaction), sourceOutputs };
|
|
451
497
|
}
|