mainnet-js 3.1.7 → 4.0.0-next.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/module/cache/IndexedDbCache.d.ts +1 -1
- package/dist/module/cache/IndexedDbCache.d.ts.map +1 -1
- package/dist/module/cache/MemoryCache.d.ts +1 -1
- package/dist/module/cache/MemoryCache.d.ts.map +1 -1
- package/dist/module/cache/WebStorageCache.d.ts +1 -1
- package/dist/module/cache/WebStorageCache.d.ts.map +1 -1
- package/dist/module/cache/walletCache.d.ts +16 -6
- package/dist/module/cache/walletCache.d.ts.map +1 -1
- package/dist/module/cache/walletCache.js +92 -34
- package/dist/module/cache/walletCache.js.map +1 -1
- package/dist/module/cli.js +1 -2
- package/dist/module/cli.js.map +1 -1
- package/dist/module/db/index.d.ts +1 -1
- package/dist/module/db/index.d.ts.map +1 -1
- package/dist/module/db/index.js +1 -1
- package/dist/module/db/index.js.map +1 -1
- package/dist/module/enum.d.ts +1 -1
- package/dist/module/enum.d.ts.map +1 -1
- package/dist/module/history/getHistory.d.ts +1 -1
- package/dist/module/history/getHistory.d.ts.map +1 -1
- package/dist/module/history/getHistory.js +3 -3
- package/dist/module/history/getHistory.js.map +1 -1
- package/dist/module/index.d.ts +25 -22
- package/dist/module/index.d.ts.map +1 -1
- package/dist/module/index.js +33 -26
- package/dist/module/index.js.map +1 -1
- package/dist/module/interface.d.ts +12 -2
- package/dist/module/interface.d.ts.map +1 -1
- package/dist/module/interface.js.map +1 -1
- 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/mine/mine.d.ts +2 -7
- package/dist/module/mine/mine.d.ts.map +1 -1
- package/dist/module/mine/mine.js +6 -27
- package/dist/module/mine/mine.js.map +1 -1
- package/dist/module/network/Connection.d.ts +1 -12
- package/dist/module/network/Connection.d.ts.map +1 -1
- package/dist/module/network/Connection.js +24 -33
- package/dist/module/network/Connection.js.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.d.ts +16 -17
- package/dist/module/network/ElectrumNetworkProvider.d.ts.map +1 -1
- package/dist/module/network/ElectrumNetworkProvider.js +91 -93
- package/dist/module/network/ElectrumNetworkProvider.js.map +1 -1
- package/dist/module/network/MockNetworkProvider.d.ts +28 -0
- package/dist/module/network/MockNetworkProvider.d.ts.map +1 -0
- package/dist/module/network/MockNetworkProvider.js +74 -0
- package/dist/module/network/MockNetworkProvider.js.map +1 -0
- package/dist/module/network/NetworkProvider.d.ts +9 -2
- package/dist/module/network/NetworkProvider.d.ts.map +1 -1
- package/dist/module/network/configuration.d.ts +2 -4
- package/dist/module/network/configuration.d.ts.map +1 -1
- package/dist/module/network/configuration.js +25 -50
- package/dist/module/network/configuration.js.map +1 -1
- package/dist/module/network/constant.d.ts +7 -7
- package/dist/module/network/constant.d.ts.map +1 -1
- package/dist/module/network/constant.js +21 -24
- package/dist/module/network/constant.js.map +1 -1
- package/dist/module/network/default.d.ts +5 -3
- package/dist/module/network/default.d.ts.map +1 -1
- package/dist/module/network/default.js +29 -51
- package/dist/module/network/default.js.map +1 -1
- package/dist/module/network/index.d.ts +4 -4
- package/dist/module/network/index.d.ts.map +1 -1
- package/dist/module/network/index.js +2 -2
- package/dist/module/network/index.js.map +1 -1
- package/dist/module/network/interface.d.ts +0 -6
- package/dist/module/network/interface.d.ts.map +1 -1
- package/dist/module/rate/ExchangeRate.d.ts +1 -1
- package/dist/module/rate/ExchangeRate.d.ts.map +1 -1
- package/dist/module/rate/ExchangeRate.js +13 -7
- package/dist/module/rate/ExchangeRate.js.map +1 -1
- package/dist/module/transaction/Wif.d.ts +3 -3
- package/dist/module/transaction/Wif.d.ts.map +1 -1
- package/dist/module/transaction/Wif.js +4 -4
- package/dist/module/transaction/Wif.js.map +1 -1
- package/dist/module/transaction/allocateFee.d.ts +1 -1
- package/dist/module/transaction/allocateFee.d.ts.map +1 -1
- package/dist/module/transaction/allocateFee.js +2 -2
- package/dist/module/transaction/allocateFee.js.map +1 -1
- package/dist/module/util/deriveCashaddr.js.map +1 -1
- package/dist/module/util/deriveNetwork.js +1 -1
- package/dist/module/util/deriveNetwork.js.map +1 -1
- package/dist/module/util/getAddrsByXpubKey.js +1 -1
- package/dist/module/util/getAddrsByXpubKey.js.map +1 -1
- package/dist/module/util/getXPubKey.js +1 -1
- package/dist/module/util/getXPubKey.js.map +1 -1
- package/dist/module/util/hd.d.ts +2 -0
- package/dist/module/util/hd.d.ts.map +1 -1
- package/dist/module/util/hd.js +41 -0
- package/dist/module/util/hd.js.map +1 -1
- package/dist/module/util/index.d.ts +7 -9
- package/dist/module/util/index.d.ts.map +1 -1
- package/dist/module/util/index.js +7 -9
- package/dist/module/util/index.js.map +1 -1
- package/dist/module/util/transaction.js +1 -1
- package/dist/module/util/transaction.js.map +1 -1
- package/dist/module/wallet/Base.d.ts +13 -9
- package/dist/module/wallet/Base.d.ts.map +1 -1
- package/dist/module/wallet/Base.js +54 -58
- package/dist/module/wallet/Base.js.map +1 -1
- package/dist/module/wallet/HDWallet.d.ts.map +1 -1
- package/dist/module/wallet/HDWallet.js +19 -38
- package/dist/module/wallet/HDWallet.js.map +1 -1
- package/dist/module/wallet/Util.d.ts +4 -22
- package/dist/module/wallet/Util.d.ts.map +1 -1
- package/dist/module/wallet/Util.js +75 -102
- package/dist/module/wallet/Util.js.map +1 -1
- package/dist/module/wallet/Watch.d.ts +24 -5
- package/dist/module/wallet/Watch.d.ts.map +1 -1
- package/dist/module/wallet/Watch.js +141 -17
- package/dist/module/wallet/Watch.js.map +1 -1
- package/dist/module/wallet/Wif.d.ts +2 -6
- package/dist/module/wallet/Wif.d.ts.map +1 -1
- package/dist/module/wallet/Wif.js +3 -69
- package/dist/module/wallet/Wif.js.map +1 -1
- package/dist/module/wallet/createWallet.d.ts +1 -1
- package/dist/module/wallet/createWallet.d.ts.map +1 -1
- package/dist/module/wallet/createWallet.js +2 -1
- package/dist/module/wallet/createWallet.js.map +1 -1
- package/dist/module/wallet/interface.d.ts +3 -2
- package/dist/module/wallet/interface.d.ts.map +1 -1
- package/dist/module/wallet/model.d.ts +2 -1
- package/dist/module/wallet/model.d.ts.map +1 -1
- package/dist/module/wallet/model.js +1 -1
- package/dist/module/wallet/model.js.map +1 -1
- package/package.json +17 -29
- package/dist/index.html +0 -9
- package/dist/mainnet-3.1.7.js +0 -2066
- package/dist/module/network/util.d.ts +0 -3
- package/dist/module/network/util.d.ts.map +0 -1
- package/dist/module/network/util.js +0 -27
- package/dist/module/network/util.js.map +0 -1
- package/dist/module/test/expect.d.ts +0 -12
- package/dist/module/test/expect.d.ts.map +0 -1
- package/dist/module/test/expect.js +0 -47
- package/dist/module/test/expect.js.map +0 -1
- package/dist/module/test/fetch.d.ts +0 -3
- package/dist/module/test/fetch.d.ts.map +0 -1
- package/dist/module/test/fetch.js +0 -32
- package/dist/module/test/fetch.js.map +0 -1
- package/dist/module/util/randomBytes.d.ts +0 -2
- package/dist/module/util/randomBytes.d.ts.map +0 -1
- package/dist/module/util/randomBytes.js +0 -13
- package/dist/module/util/randomBytes.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/cache/IndexedDbCache.test.ts +0 -15
- package/src/cache/IndexedDbCache.ts +0 -172
- package/src/cache/MemoryCache.test.ts +0 -15
- package/src/cache/MemoryCache.ts +0 -32
- package/src/cache/WebStorageCache.test.ts +0 -15
- package/src/cache/WebStorageCache.ts +0 -38
- package/src/cache/index.ts +0 -2
- package/src/cache/interface.ts +0 -9
- package/src/cache/walletCache.ts +0 -254
- package/src/chain.ts +0 -3
- package/src/cli.ts +0 -32
- package/src/config.ts +0 -23
- package/src/constant.ts +0 -27
- package/src/db/ExchangeRateProvider.ts +0 -28
- package/src/db/StorageProvider.ts +0 -64
- package/src/db/index.ts +0 -2
- package/src/db/interface.ts +0 -11
- package/src/enum.ts +0 -34
- package/src/history/getHistory.test.ts +0 -290
- package/src/history/getHistory.ts +0 -411
- package/src/history/interface.ts +0 -24
- package/src/index.ts +0 -48
- package/src/interface.ts +0 -72
- package/src/libauth.ts +0 -11
- package/src/message/index.ts +0 -2
- package/src/message/interface.ts +0 -40
- package/src/message/signed.test.ts +0 -309
- package/src/message/signed.ts +0 -201
- package/src/mine/index.ts +0 -1
- package/src/mine/mine.test.ts +0 -10
- package/src/mine/mine.ts +0 -42
- package/src/network/Connection.test.ts +0 -51
- package/src/network/Connection.ts +0 -73
- package/src/network/ElectrumNetworkProvider.ts +0 -657
- package/src/network/NetworkProvider.ts +0 -180
- package/src/network/Rpc.test.ts +0 -130
- package/src/network/configuration.test.ts +0 -59
- package/src/network/configuration.ts +0 -72
- package/src/network/constant.ts +0 -43
- package/src/network/default.ts +0 -120
- package/src/network/electrum.test.ts +0 -28
- package/src/network/getRelayFeeCache.test.ts +0 -15
- package/src/network/getRelayFeeCache.ts +0 -23
- package/src/network/index.ts +0 -14
- package/src/network/interface.ts +0 -80
- package/src/network/util.test.ts +0 -24
- package/src/network/util.ts +0 -30
- package/src/rate/ExchangeRate.test.headless.js +0 -35
- package/src/rate/ExchangeRate.test.ts +0 -51
- package/src/rate/ExchangeRate.ts +0 -142
- package/src/test/expect.ts +0 -59
- package/src/test/fetch.ts +0 -39
- package/src/test/json.test.ts +0 -13
- package/src/transaction/Wif.ts +0 -680
- package/src/transaction/allocateFee.test.ts +0 -298
- package/src/transaction/allocateFee.ts +0 -149
- package/src/util/amountInSatoshi.test.ts +0 -27
- package/src/util/amountInSatoshi.ts +0 -33
- package/src/util/asSendRequestObject.ts +0 -81
- package/src/util/base64.test.ts +0 -39
- package/src/util/base64.ts +0 -12
- package/src/util/browserNotSupported.ts +0 -7
- package/src/util/checkForEmptySeed.ts +0 -9
- package/src/util/checkUtxos.ts +0 -29
- package/src/util/checkWifNetwork.ts +0 -24
- package/src/util/convert.test.ts +0 -46
- package/src/util/convert.ts +0 -50
- package/src/util/delay.ts +0 -3
- package/src/util/deriveCashaddr.test.ts +0 -164
- package/src/util/deriveCashaddr.ts +0 -143
- package/src/util/deriveLockscript.ts +0 -16
- package/src/util/deriveNetwork.ts +0 -19
- package/src/util/derivePublicKeyHash.test.ts +0 -55
- package/src/util/derivePublicKeyHash.ts +0 -64
- package/src/util/floor.test.ts +0 -21
- package/src/util/floor.ts +0 -4
- package/src/util/getAddrsByXpubKey.test.ts +0 -115
- package/src/util/getAddrsByXpubKey.ts +0 -86
- package/src/util/getRuntimePlatform.test.headless.js +0 -40
- package/src/util/getRuntimePlatform.test.ts +0 -5
- package/src/util/getRuntimePlatform.ts +0 -31
- package/src/util/getUsdRate.ts +0 -5
- package/src/util/getXPubKey.ts +0 -39
- package/src/util/hash160.test.ts +0 -18
- package/src/util/hash160.ts +0 -12
- package/src/util/hd.ts +0 -16
- package/src/util/header.test.ts +0 -34
- package/src/util/header.ts +0 -26
- package/src/util/index.ts +0 -33
- package/src/util/randomBytes.ts +0 -13
- package/src/util/randomInt.test.ts +0 -15
- package/src/util/randomInt.ts +0 -4
- package/src/util/sanitizeAddress.ts +0 -10
- package/src/util/sanitizeUnit.ts +0 -11
- package/src/util/satoshiToAmount.test.ts +0 -6
- package/src/util/satoshiToAmount.ts +0 -33
- package/src/util/sumSendRequestAmounts.ts +0 -34
- package/src/util/sumUtxoValue.ts +0 -27
- package/src/util/transaction.ts +0 -10
- package/src/wallet/Base.ts +0 -1563
- package/src/wallet/Cashtokens.test.headless.js +0 -730
- package/src/wallet/Cashtokens.test.ts +0 -1411
- package/src/wallet/HDWallet.test.ts +0 -1086
- package/src/wallet/HDWallet.ts +0 -992
- package/src/wallet/Util.test.ts +0 -134
- package/src/wallet/Util.ts +0 -191
- package/src/wallet/WalletCache.test.ts +0 -45
- package/src/wallet/Watch.ts +0 -441
- package/src/wallet/Wif.bip39.test.ts +0 -48
- package/src/wallet/Wif.test.ts +0 -1189
- package/src/wallet/Wif.ts +0 -687
- package/src/wallet/Wif.watchOnly.test.ts +0 -58
- package/src/wallet/createWallet.ts +0 -238
- package/src/wallet/enum.ts +0 -18
- package/src/wallet/interface.ts +0 -102
- package/src/wallet/model.test.ts +0 -24
- package/src/wallet/model.ts +0 -352
- package/tsconfig.browser.json +0 -11
- package/tsconfig.json +0 -33
- package/webpack.config.cjs +0 -132
package/src/transaction/Wif.ts
DELETED
|
@@ -1,680 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
walletTemplateP2pkhNonHd,
|
|
3
|
-
cashAddressToLockingBytecode,
|
|
4
|
-
Compiler,
|
|
5
|
-
encodeTransaction,
|
|
6
|
-
generateTransaction,
|
|
7
|
-
importWalletTemplate,
|
|
8
|
-
AnyCompilerConfiguration,
|
|
9
|
-
AuthenticationProgramStateCommon,
|
|
10
|
-
Output,
|
|
11
|
-
hexToBin,
|
|
12
|
-
verifyTransactionTokens,
|
|
13
|
-
decodeTransaction,
|
|
14
|
-
TransactionTemplateFixed,
|
|
15
|
-
CompilationContextBch,
|
|
16
|
-
walletTemplateToCompilerBch,
|
|
17
|
-
} from "@bitauth/libauth";
|
|
18
|
-
import { NFTCapability, TokenI, Utxo } from "../interface.js";
|
|
19
|
-
import { allocateFee } from "./allocateFee.js";
|
|
20
|
-
|
|
21
|
-
import { DUST_UTXO_THRESHOLD } from "../constant.js";
|
|
22
|
-
import {
|
|
23
|
-
OpReturnData,
|
|
24
|
-
SendRequest,
|
|
25
|
-
SendRequestType,
|
|
26
|
-
SourceOutput,
|
|
27
|
-
TokenSendRequest,
|
|
28
|
-
} from "../wallet/model.js";
|
|
29
|
-
import { sumSendRequestAmounts } from "../util/sumSendRequestAmounts.js";
|
|
30
|
-
import { sumUtxoValue } from "../util/sumUtxoValue.js";
|
|
31
|
-
import { FeePaidByEnum } from "../wallet/enum.js";
|
|
32
|
-
import { WalletCache } from "../cache/walletCache.js";
|
|
33
|
-
|
|
34
|
-
export const placeholderPrivateKey =
|
|
35
|
-
"0000000000000000000000000000000000000000000000000000000000000001";
|
|
36
|
-
export const placeholderPrivateKeyBin = hexToBin(placeholderPrivateKey);
|
|
37
|
-
|
|
38
|
-
// Build a transaction for a p2pkh transaction for a non HD wallet
|
|
39
|
-
export async function buildP2pkhNonHdTransaction({
|
|
40
|
-
inputs,
|
|
41
|
-
outputs,
|
|
42
|
-
signingKey,
|
|
43
|
-
fee = 0n,
|
|
44
|
-
discardChange = false,
|
|
45
|
-
feePaidBy = FeePaidByEnum.change,
|
|
46
|
-
changeAddress = "",
|
|
47
|
-
walletCache,
|
|
48
|
-
}: {
|
|
49
|
-
inputs: Utxo[];
|
|
50
|
-
outputs: Array<SendRequest | TokenSendRequest | OpReturnData>;
|
|
51
|
-
signingKey?: Uint8Array;
|
|
52
|
-
fee?: bigint;
|
|
53
|
-
discardChange?: boolean;
|
|
54
|
-
feePaidBy?: FeePaidByEnum;
|
|
55
|
-
changeAddress?: string;
|
|
56
|
-
walletCache: WalletCache;
|
|
57
|
-
}) {
|
|
58
|
-
if (!signingKey) {
|
|
59
|
-
throw new Error("Missing signing key when building transaction");
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const template = importWalletTemplate(walletTemplateP2pkhNonHd);
|
|
63
|
-
if (typeof template === "string") {
|
|
64
|
-
throw new Error("Transaction template error");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const compiler = walletTemplateToCompilerBch(template);
|
|
68
|
-
const inputAmount = sumUtxoValue(inputs);
|
|
69
|
-
|
|
70
|
-
const sendAmount = await sumSendRequestAmounts(outputs);
|
|
71
|
-
|
|
72
|
-
const changeAmount = BigInt(inputAmount) - BigInt(sendAmount) - BigInt(fee);
|
|
73
|
-
|
|
74
|
-
outputs = allocateFee(outputs, fee, feePaidBy, changeAmount);
|
|
75
|
-
|
|
76
|
-
const lockedOutputs = await prepareOutputs(outputs);
|
|
77
|
-
|
|
78
|
-
if (!changeAddress) {
|
|
79
|
-
changeAddress = inputs[0].address;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (discardChange !== true) {
|
|
83
|
-
if (changeAmount > DUST_UTXO_THRESHOLD) {
|
|
84
|
-
const changeLockingBytecode = cashAddressToLockingBytecode(changeAddress);
|
|
85
|
-
if (typeof changeLockingBytecode === "string") {
|
|
86
|
-
throw Error(changeLockingBytecode);
|
|
87
|
-
}
|
|
88
|
-
lockedOutputs.push({
|
|
89
|
-
lockingBytecode: changeLockingBytecode.bytecode,
|
|
90
|
-
valueSatoshis: BigInt(changeAmount),
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const { preparedInputs, sourceOutputs } = prepareInputs({
|
|
96
|
-
inputs,
|
|
97
|
-
compiler,
|
|
98
|
-
signingKey,
|
|
99
|
-
walletCache,
|
|
100
|
-
});
|
|
101
|
-
const result = generateTransaction({
|
|
102
|
-
inputs: preparedInputs,
|
|
103
|
-
locktime: 0,
|
|
104
|
-
outputs: lockedOutputs,
|
|
105
|
-
version: 2,
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
if (!result.success) {
|
|
109
|
-
throw Error("Error building transaction with fee");
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const tokenValidationResult = verifyTransactionTokens(
|
|
113
|
-
result.transaction,
|
|
114
|
-
sourceOutputs,
|
|
115
|
-
{ maximumTokenCommitmentLength: 40 }
|
|
116
|
-
);
|
|
117
|
-
if (tokenValidationResult !== true && fee > 0) {
|
|
118
|
-
throw tokenValidationResult;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return { transaction: result.transaction, sourceOutputs: sourceOutputs };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export function prepareInputs({
|
|
125
|
-
inputs,
|
|
126
|
-
compiler,
|
|
127
|
-
signingKey,
|
|
128
|
-
walletCache,
|
|
129
|
-
}: {
|
|
130
|
-
inputs: Utxo[];
|
|
131
|
-
compiler: Compiler<
|
|
132
|
-
CompilationContextBch,
|
|
133
|
-
AnyCompilerConfiguration<CompilationContextBch>,
|
|
134
|
-
AuthenticationProgramStateCommon
|
|
135
|
-
>;
|
|
136
|
-
signingKey: Uint8Array;
|
|
137
|
-
walletCache: WalletCache;
|
|
138
|
-
}) {
|
|
139
|
-
const preparedInputs: any[] = [];
|
|
140
|
-
const sourceOutputs: any[] = [];
|
|
141
|
-
for (const i of inputs) {
|
|
142
|
-
const utxoTxnValue = i.satoshis;
|
|
143
|
-
const utxoIndex = i.vout;
|
|
144
|
-
// slice will create a clone of the array
|
|
145
|
-
const utxoOutpointTransactionHash = new Uint8Array(
|
|
146
|
-
i.txid.match(/.{1,2}/g)!.map((byte) => parseInt(byte, 16))
|
|
147
|
-
);
|
|
148
|
-
// reverse the cloned copy
|
|
149
|
-
// utxoOutpointTransactionHash.reverse();
|
|
150
|
-
if (!utxoOutpointTransactionHash || utxoIndex === undefined) {
|
|
151
|
-
throw new Error("Missing unspent outpoint when building transaction");
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const libAuthToken = i.token && {
|
|
155
|
-
amount: BigInt(i.token.amount),
|
|
156
|
-
category: hexToBin(i.token.category),
|
|
157
|
-
nft:
|
|
158
|
-
i.token.nft?.capability !== undefined ||
|
|
159
|
-
i.token.nft?.commitment !== undefined
|
|
160
|
-
? {
|
|
161
|
-
capability: i.token.nft?.capability,
|
|
162
|
-
commitment:
|
|
163
|
-
i.token.nft?.commitment !== undefined &&
|
|
164
|
-
hexToBin(i.token.nft?.commitment!),
|
|
165
|
-
}
|
|
166
|
-
: undefined,
|
|
167
|
-
};
|
|
168
|
-
const key =
|
|
169
|
-
walletCache.get(i.address)?.privateKey ??
|
|
170
|
-
(signingKey?.length ? signingKey : Uint8Array.from(Array(32)));
|
|
171
|
-
const newInput = {
|
|
172
|
-
outpointIndex: utxoIndex,
|
|
173
|
-
outpointTransactionHash: utxoOutpointTransactionHash,
|
|
174
|
-
sequenceNumber: 0,
|
|
175
|
-
unlockingBytecode: {
|
|
176
|
-
compiler,
|
|
177
|
-
data: {
|
|
178
|
-
keys: { privateKeys: { key: key } },
|
|
179
|
-
},
|
|
180
|
-
valueSatoshis: BigInt(utxoTxnValue),
|
|
181
|
-
script: "unlock",
|
|
182
|
-
token: libAuthToken,
|
|
183
|
-
},
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
preparedInputs.push(newInput);
|
|
187
|
-
|
|
188
|
-
const lockingBytecode = cashAddressToLockingBytecode(i.address);
|
|
189
|
-
if (typeof lockingBytecode === "string") {
|
|
190
|
-
throw lockingBytecode;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
sourceOutputs.push({
|
|
194
|
-
outpointIndex: utxoIndex,
|
|
195
|
-
outpointTransactionHash: utxoOutpointTransactionHash,
|
|
196
|
-
sequenceNumber: 0,
|
|
197
|
-
unlockingBytecode: Uint8Array.from([]),
|
|
198
|
-
|
|
199
|
-
// additional info for sourceOutputs
|
|
200
|
-
lockingBytecode: lockingBytecode.bytecode,
|
|
201
|
-
valueSatoshis: BigInt(utxoTxnValue),
|
|
202
|
-
token: libAuthToken,
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
return { preparedInputs, sourceOutputs };
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
/**
|
|
209
|
-
* prepareOutputs - create outputs for a transaction from a list of send requests
|
|
210
|
-
*
|
|
211
|
-
* a wrapper function
|
|
212
|
-
*
|
|
213
|
-
* @returns A promise to a list of unspent outputs
|
|
214
|
-
*/
|
|
215
|
-
export async function prepareOutputs(
|
|
216
|
-
outputs: Array<SendRequest | TokenSendRequest | OpReturnData>
|
|
217
|
-
) {
|
|
218
|
-
const lockedOutputs: Output[] = [];
|
|
219
|
-
for (const output of outputs) {
|
|
220
|
-
if (output instanceof TokenSendRequest) {
|
|
221
|
-
lockedOutputs.push(prepareTokenOutputs(output));
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
if (output instanceof OpReturnData) {
|
|
226
|
-
lockedOutputs.push(prepareOpReturnOutput(output));
|
|
227
|
-
continue;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const outputLockingBytecode = cashAddressToLockingBytecode(output.cashaddr);
|
|
231
|
-
if (typeof outputLockingBytecode === "string")
|
|
232
|
-
throw new Error(outputLockingBytecode);
|
|
233
|
-
|
|
234
|
-
const sendAmount = Number(output.value);
|
|
235
|
-
if (sendAmount % 1 !== 0) {
|
|
236
|
-
throw Error(
|
|
237
|
-
`Cannot send ${sendAmount} satoshis, (fractional sats do not exist, yet), please use an integer number.`
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
const lockedOutput: Output = {
|
|
241
|
-
lockingBytecode: outputLockingBytecode.bytecode,
|
|
242
|
-
valueSatoshis: BigInt(sendAmount),
|
|
243
|
-
};
|
|
244
|
-
lockedOutputs.push(lockedOutput);
|
|
245
|
-
}
|
|
246
|
-
return lockedOutputs;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* prepareOpReturnOutput - create an output for OP_RETURN data
|
|
251
|
-
*
|
|
252
|
-
* @returns A promise to a list of unspent outputs
|
|
253
|
-
*/
|
|
254
|
-
export function prepareOpReturnOutput(request: OpReturnData): Output {
|
|
255
|
-
return {
|
|
256
|
-
lockingBytecode: request.buffer,
|
|
257
|
-
valueSatoshis: BigInt(0),
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* prepareOpReturnOutput - create an output for token data
|
|
263
|
-
*
|
|
264
|
-
* @returns A libauth Output
|
|
265
|
-
*/
|
|
266
|
-
export function prepareTokenOutputs(request: TokenSendRequest): Output {
|
|
267
|
-
const token: TokenI = request;
|
|
268
|
-
const outputLockingBytecode = cashAddressToLockingBytecode(request.cashaddr);
|
|
269
|
-
if (typeof outputLockingBytecode === "string")
|
|
270
|
-
throw new Error(outputLockingBytecode);
|
|
271
|
-
|
|
272
|
-
const libAuthToken = {
|
|
273
|
-
amount: BigInt(token.amount),
|
|
274
|
-
category: hexToBin(token.category),
|
|
275
|
-
nft:
|
|
276
|
-
token.nft?.capability !== undefined || token.nft?.commitment !== undefined
|
|
277
|
-
? {
|
|
278
|
-
capability: token.nft?.capability,
|
|
279
|
-
commitment:
|
|
280
|
-
token.nft?.commitment !== undefined &&
|
|
281
|
-
hexToBin(token.nft?.commitment!),
|
|
282
|
-
}
|
|
283
|
-
: undefined,
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
return {
|
|
287
|
-
lockingBytecode: outputLockingBytecode.bytecode,
|
|
288
|
-
valueSatoshis: BigInt(request.value || 1000),
|
|
289
|
-
token: libAuthToken,
|
|
290
|
-
} as Output;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* getSuitableUtxos - Filter a list of unspent transaction outputs to the minimum needed to complete a transaction
|
|
295
|
-
*
|
|
296
|
-
* a intermediate function
|
|
297
|
-
*
|
|
298
|
-
* @param unspentOutputs An unfiltered list of available unspent transaction outputs
|
|
299
|
-
*
|
|
300
|
-
* @returns A promise to a list of unspent outputs
|
|
301
|
-
*/
|
|
302
|
-
export async function getSuitableUtxos(
|
|
303
|
-
inputs: Utxo[],
|
|
304
|
-
amountRequired: bigint | undefined,
|
|
305
|
-
bestHeight: number,
|
|
306
|
-
feePaidBy: FeePaidByEnum,
|
|
307
|
-
requests: SendRequestType[],
|
|
308
|
-
ensureUtxos: Utxo[] = [],
|
|
309
|
-
tokenOperation: "send" | "genesis" | "mint" | "burn" = "send"
|
|
310
|
-
): Promise<Utxo[]> {
|
|
311
|
-
const utxoKey = (u: Utxo) => `${u.txid}:${u.vout}`;
|
|
312
|
-
const selectedSet = new Set<string>();
|
|
313
|
-
const suitableUtxos: Utxo[] = [];
|
|
314
|
-
|
|
315
|
-
for (const u of ensureUtxos) {
|
|
316
|
-
const key = utxoKey(u);
|
|
317
|
-
if (!selectedSet.has(key)) {
|
|
318
|
-
selectedSet.add(key);
|
|
319
|
-
suitableUtxos.push(u);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
let amountAvailable = suitableUtxos.reduce(
|
|
324
|
-
(sum, u) => sum + BigInt(u.satoshis),
|
|
325
|
-
BigInt(0)
|
|
326
|
-
);
|
|
327
|
-
const tokenRequests = requests.filter(
|
|
328
|
-
(val) => val instanceof TokenSendRequest
|
|
329
|
-
) as TokenSendRequest[];
|
|
330
|
-
|
|
331
|
-
const usedIndices = new Set<number>();
|
|
332
|
-
|
|
333
|
-
// Track how many times each selected UTXO has been "claimed" by a request
|
|
334
|
-
const claimedUtxos = new Map<string, number>();
|
|
335
|
-
|
|
336
|
-
// find matching utxos for token transfers
|
|
337
|
-
if (tokenOperation === "send") {
|
|
338
|
-
for (const request of tokenRequests) {
|
|
339
|
-
// Search suitableUtxos then inputs sequentially to find matching tokens
|
|
340
|
-
const matchCommitment = (val: Utxo) =>
|
|
341
|
-
val.token?.category === request.category &&
|
|
342
|
-
val.token?.nft?.capability === request.nft?.capability &&
|
|
343
|
-
val.token?.nft?.commitment === request.nft?.commitment;
|
|
344
|
-
|
|
345
|
-
// For NFTs (non-fungible), each request needs its own UTXO
|
|
346
|
-
// For FT-only requests, a single UTXO can satisfy multiple requests
|
|
347
|
-
const isFungibleOnly =
|
|
348
|
-
request.nft?.capability === undefined &&
|
|
349
|
-
request.nft?.commitment === undefined;
|
|
350
|
-
|
|
351
|
-
// Check already-selected suitable utxos first (no need to re-add)
|
|
352
|
-
let found = false;
|
|
353
|
-
if (isFungibleOnly) {
|
|
354
|
-
found = suitableUtxos.some(matchCommitment);
|
|
355
|
-
} else {
|
|
356
|
-
// For NFTs, find an unclaimed matching UTXO in suitableUtxos
|
|
357
|
-
for (const val of suitableUtxos) {
|
|
358
|
-
if (!matchCommitment(val)) continue;
|
|
359
|
-
const key = utxoKey(val);
|
|
360
|
-
const claims = claimedUtxos.get(key) || 0;
|
|
361
|
-
if (claims === 0) {
|
|
362
|
-
claimedUtxos.set(key, claims + 1);
|
|
363
|
-
found = true;
|
|
364
|
-
break;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
if (!found) {
|
|
370
|
-
// Search available inputs for same commitment match
|
|
371
|
-
for (let i = 0; i < inputs.length; i++) {
|
|
372
|
-
if (usedIndices.has(i)) continue;
|
|
373
|
-
const val = inputs[i];
|
|
374
|
-
if (val.token?.category !== request.category) continue;
|
|
375
|
-
if (!matchCommitment(val)) continue;
|
|
376
|
-
const key = utxoKey(val);
|
|
377
|
-
if (selectedSet.has(key)) continue;
|
|
378
|
-
|
|
379
|
-
selectedSet.add(key);
|
|
380
|
-
suitableUtxos.push(val);
|
|
381
|
-
usedIndices.add(i);
|
|
382
|
-
amountAvailable += BigInt(val.satoshis);
|
|
383
|
-
if (!isFungibleOnly) {
|
|
384
|
-
claimedUtxos.set(key, 1);
|
|
385
|
-
}
|
|
386
|
-
found = true;
|
|
387
|
-
break;
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
if (found) continue;
|
|
392
|
-
|
|
393
|
-
if (
|
|
394
|
-
request.nft?.capability === NFTCapability.minting ||
|
|
395
|
-
request.nft?.capability === NFTCapability.mutable
|
|
396
|
-
) {
|
|
397
|
-
// Check already-selected suitable utxos first
|
|
398
|
-
const alreadyHas = suitableUtxos.some(
|
|
399
|
-
(val) =>
|
|
400
|
-
val.token?.category === request.category &&
|
|
401
|
-
val.token?.nft?.capability === request.nft?.capability
|
|
402
|
-
);
|
|
403
|
-
if (alreadyHas) continue;
|
|
404
|
-
|
|
405
|
-
let foundCapability = false;
|
|
406
|
-
for (let i = 0; i < inputs.length; i++) {
|
|
407
|
-
if (usedIndices.has(i)) continue;
|
|
408
|
-
const val = inputs[i];
|
|
409
|
-
if (
|
|
410
|
-
val.token?.category === request.category &&
|
|
411
|
-
val.token?.nft?.capability === request.nft?.capability
|
|
412
|
-
) {
|
|
413
|
-
const key = utxoKey(val);
|
|
414
|
-
if (selectedSet.has(key)) continue;
|
|
415
|
-
|
|
416
|
-
selectedSet.add(key);
|
|
417
|
-
suitableUtxos.push(val);
|
|
418
|
-
usedIndices.add(i);
|
|
419
|
-
amountAvailable += BigInt(val.satoshis);
|
|
420
|
-
foundCapability = true;
|
|
421
|
-
break;
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
if (foundCapability) continue;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
// handle splitting the hybrid (FT+NFT) token into its parts
|
|
428
|
-
if (
|
|
429
|
-
request.nft?.capability === undefined &&
|
|
430
|
-
request.nft?.commitment === undefined
|
|
431
|
-
) {
|
|
432
|
-
const hasCategoryInSuitable = suitableUtxos.some(
|
|
433
|
-
(val) => val.token?.category === request.category
|
|
434
|
-
);
|
|
435
|
-
const hasCategoryInInputs =
|
|
436
|
-
!hasCategoryInSuitable &&
|
|
437
|
-
inputs.some(
|
|
438
|
-
(val, i) =>
|
|
439
|
-
!usedIndices.has(i) && val.token?.category === request.category
|
|
440
|
-
);
|
|
441
|
-
if (hasCategoryInSuitable || hasCategoryInInputs) {
|
|
442
|
-
continue;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
throw Error(
|
|
447
|
-
`No suitable token utxos available to send token with id "${request.category}", capability "${request.nft?.capability}", commitment "${request.nft?.commitment}"`
|
|
448
|
-
);
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// find plain bch outputs
|
|
453
|
-
for (let i = 0; i < inputs.length; i++) {
|
|
454
|
-
// check early if we already have enough
|
|
455
|
-
if (amountRequired && amountAvailable > amountRequired) {
|
|
456
|
-
break;
|
|
457
|
-
}
|
|
458
|
-
if (usedIndices.has(i)) continue;
|
|
459
|
-
const u = inputs[i];
|
|
460
|
-
if (u.token) continue;
|
|
461
|
-
|
|
462
|
-
const key = utxoKey(u);
|
|
463
|
-
if (selectedSet.has(key)) continue;
|
|
464
|
-
|
|
465
|
-
selectedSet.add(key);
|
|
466
|
-
suitableUtxos.push(u);
|
|
467
|
-
amountAvailable += BigInt(u.satoshis);
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// if the fee is split with a feePaidBy option, skip checking change.
|
|
471
|
-
if (feePaidBy && feePaidBy != FeePaidByEnum.change) {
|
|
472
|
-
return suitableUtxos;
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
// If the amount needed is met, or no amount is given, return
|
|
476
|
-
if (typeof amountRequired === "undefined") {
|
|
477
|
-
return suitableUtxos;
|
|
478
|
-
} else if (amountAvailable < amountRequired) {
|
|
479
|
-
const e = Error(
|
|
480
|
-
`Amount required was not met, ${amountRequired} satoshis needed, ${amountAvailable} satoshis available`
|
|
481
|
-
);
|
|
482
|
-
e["data"] = {
|
|
483
|
-
required: amountRequired,
|
|
484
|
-
available: amountAvailable,
|
|
485
|
-
};
|
|
486
|
-
throw e;
|
|
487
|
-
} else {
|
|
488
|
-
return suitableUtxos;
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
// model-based imprecise and fast fee estimation
|
|
493
|
-
export async function getFeeAmountSimple({
|
|
494
|
-
utxos,
|
|
495
|
-
sendRequests,
|
|
496
|
-
relayFeePerByteInSatoshi,
|
|
497
|
-
discardChange,
|
|
498
|
-
}: {
|
|
499
|
-
utxos: Utxo[];
|
|
500
|
-
sendRequests: Array<SendRequest | TokenSendRequest | OpReturnData>;
|
|
501
|
-
sourceAddress: string;
|
|
502
|
-
relayFeePerByteInSatoshi: number;
|
|
503
|
-
feePaidBy: FeePaidByEnum;
|
|
504
|
-
discardChange?: boolean;
|
|
505
|
-
}): Promise<bigint> {
|
|
506
|
-
const inputSizeP2pkh = 148;
|
|
507
|
-
const outputSizeP2pkh = 34;
|
|
508
|
-
|
|
509
|
-
const inputTotalSize = utxos.reduce(
|
|
510
|
-
(prev, curr) =>
|
|
511
|
-
prev +
|
|
512
|
-
(curr.token
|
|
513
|
-
? inputSizeP2pkh +
|
|
514
|
-
1 +
|
|
515
|
-
34 +
|
|
516
|
-
Math.round(1 + (curr.token.nft?.commitment?.length ?? 0) / 2) +
|
|
517
|
-
(curr.token.amount ? 9 : 0)
|
|
518
|
-
: inputSizeP2pkh),
|
|
519
|
-
0
|
|
520
|
-
);
|
|
521
|
-
|
|
522
|
-
const outputSize = (sendRequest: SendRequestType) => {
|
|
523
|
-
if (sendRequest.hasOwnProperty("category")) {
|
|
524
|
-
const tokenRequest = sendRequest as TokenSendRequest;
|
|
525
|
-
return (
|
|
526
|
-
outputSizeP2pkh +
|
|
527
|
-
1 +
|
|
528
|
-
34 +
|
|
529
|
-
Math.round(1 + (tokenRequest.nft?.commitment?.length ?? 0) / 2) +
|
|
530
|
-
(tokenRequest.amount ? 9 : 0)
|
|
531
|
-
);
|
|
532
|
-
} else if (sendRequest.hasOwnProperty("buffer")) {
|
|
533
|
-
return 9 + (sendRequest as OpReturnData).buffer.length;
|
|
534
|
-
} else {
|
|
535
|
-
return outputSizeP2pkh;
|
|
536
|
-
}
|
|
537
|
-
};
|
|
538
|
-
|
|
539
|
-
const outputTotalSize =
|
|
540
|
-
sendRequests.reduce((prev, curr) => prev + outputSize(curr), 0) +
|
|
541
|
-
(discardChange ? 0 : outputSizeP2pkh);
|
|
542
|
-
|
|
543
|
-
return BigInt(
|
|
544
|
-
Math.ceil(
|
|
545
|
-
(inputTotalSize + outputTotalSize + 16) * relayFeePerByteInSatoshi
|
|
546
|
-
)
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
// precise fee estimation
|
|
551
|
-
export async function getFeeAmount({
|
|
552
|
-
utxos,
|
|
553
|
-
sendRequests,
|
|
554
|
-
sourceAddress,
|
|
555
|
-
relayFeePerByteInSatoshi,
|
|
556
|
-
feePaidBy,
|
|
557
|
-
discardChange,
|
|
558
|
-
walletCache,
|
|
559
|
-
}: {
|
|
560
|
-
utxos: Utxo[];
|
|
561
|
-
sendRequests: Array<SendRequest | TokenSendRequest | OpReturnData>;
|
|
562
|
-
sourceAddress: string;
|
|
563
|
-
relayFeePerByteInSatoshi: number;
|
|
564
|
-
feePaidBy: FeePaidByEnum;
|
|
565
|
-
discardChange?: boolean;
|
|
566
|
-
walletCache: WalletCache;
|
|
567
|
-
}) {
|
|
568
|
-
// build transaction
|
|
569
|
-
if (utxos) {
|
|
570
|
-
// Build the transaction to get the approximate size
|
|
571
|
-
const { encodedTransaction: draftTransaction } =
|
|
572
|
-
await buildEncodedTransaction({
|
|
573
|
-
inputs: utxos,
|
|
574
|
-
outputs: sendRequests,
|
|
575
|
-
signingKey: placeholderPrivateKeyBin,
|
|
576
|
-
fee: 0n, //DUST_UTXO_THRESHOLD
|
|
577
|
-
discardChange: discardChange ?? false,
|
|
578
|
-
feePaidBy,
|
|
579
|
-
changeAddress: "",
|
|
580
|
-
walletCache,
|
|
581
|
-
});
|
|
582
|
-
|
|
583
|
-
return BigInt(
|
|
584
|
-
Math.ceil(draftTransaction.length * relayFeePerByteInSatoshi + 1)
|
|
585
|
-
);
|
|
586
|
-
} else {
|
|
587
|
-
throw Error(
|
|
588
|
-
"The available inputs in the wallet cannot satisfy this send request"
|
|
589
|
-
);
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
// Build encoded transaction
|
|
594
|
-
export async function buildEncodedTransaction({
|
|
595
|
-
inputs,
|
|
596
|
-
outputs,
|
|
597
|
-
signingKey,
|
|
598
|
-
fee = 0n,
|
|
599
|
-
discardChange = false,
|
|
600
|
-
feePaidBy = FeePaidByEnum.change,
|
|
601
|
-
changeAddress = "",
|
|
602
|
-
buildUnsigned = false,
|
|
603
|
-
walletCache,
|
|
604
|
-
}: {
|
|
605
|
-
inputs: Utxo[];
|
|
606
|
-
outputs: Array<SendRequest | TokenSendRequest | OpReturnData>;
|
|
607
|
-
signingKey: Uint8Array;
|
|
608
|
-
fee?: bigint;
|
|
609
|
-
discardChange?: boolean;
|
|
610
|
-
feePaidBy?: FeePaidByEnum;
|
|
611
|
-
changeAddress?: string;
|
|
612
|
-
buildUnsigned?: boolean;
|
|
613
|
-
walletCache: WalletCache;
|
|
614
|
-
}) {
|
|
615
|
-
const { transaction, sourceOutputs } = await buildP2pkhNonHdTransaction({
|
|
616
|
-
inputs,
|
|
617
|
-
outputs,
|
|
618
|
-
signingKey,
|
|
619
|
-
fee,
|
|
620
|
-
discardChange,
|
|
621
|
-
feePaidBy,
|
|
622
|
-
changeAddress,
|
|
623
|
-
walletCache,
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
if (buildUnsigned === true) {
|
|
627
|
-
transaction.inputs.forEach(
|
|
628
|
-
(input) => (input.unlockingBytecode = Uint8Array.from([]))
|
|
629
|
-
);
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
return { encodedTransaction: encodeTransaction(transaction), sourceOutputs };
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
export async function signUnsignedTransaction(
|
|
636
|
-
transaction: Uint8Array | string,
|
|
637
|
-
sourceOutputs: SourceOutput[],
|
|
638
|
-
signingKey: Uint8Array
|
|
639
|
-
): Promise<Uint8Array> {
|
|
640
|
-
if (typeof transaction === "string") {
|
|
641
|
-
transaction = hexToBin(transaction);
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
const decoded = decodeTransaction(transaction);
|
|
645
|
-
if (typeof decoded === "string") {
|
|
646
|
-
throw decoded;
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
const template = importWalletTemplate(walletTemplateP2pkhNonHd);
|
|
650
|
-
if (typeof template === "string") {
|
|
651
|
-
throw new Error("Transaction template error");
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
const compiler = walletTemplateToCompilerBch(template);
|
|
655
|
-
const transactionTemplate: Readonly<
|
|
656
|
-
TransactionTemplateFixed<typeof compiler>
|
|
657
|
-
> = { ...decoded };
|
|
658
|
-
for (const [index, input] of decoded.inputs.entries()) {
|
|
659
|
-
const sourceOutput = sourceOutputs[index];
|
|
660
|
-
transactionTemplate.inputs[index] = {
|
|
661
|
-
...input,
|
|
662
|
-
unlockingBytecode: {
|
|
663
|
-
compiler,
|
|
664
|
-
data: {
|
|
665
|
-
keys: { privateKeys: { key: signingKey } },
|
|
666
|
-
},
|
|
667
|
-
valueSatoshis: sourceOutput.valueSatoshis,
|
|
668
|
-
script: "unlock",
|
|
669
|
-
token: sourceOutput.token,
|
|
670
|
-
},
|
|
671
|
-
};
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
const result = generateTransaction(transactionTemplate);
|
|
675
|
-
if (!result.success) {
|
|
676
|
-
throw result.errors;
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
return encodeTransaction(result.transaction);
|
|
680
|
-
}
|