beignet 0.0.1
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/.eslintignore +4 -0
- package/.eslintrc +40 -0
- package/.prettierrc +9 -0
- package/LICENSE +21 -0
- package/README.md +166 -0
- package/dist/electrum/constants.js +31 -0
- package/dist/electrum/constants.js.map +1 -0
- package/dist/electrum/index.js +552 -0
- package/dist/electrum/index.js.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/shapes/electrum.js +14 -0
- package/dist/shapes/electrum.js.map +1 -0
- package/dist/shapes/index.js +19 -0
- package/dist/shapes/index.js.map +1 -0
- package/dist/shapes/wallet.js +115 -0
- package/dist/shapes/wallet.js.map +1 -0
- package/dist/transaction/index.js +692 -0
- package/dist/transaction/index.js.map +1 -0
- package/dist/types/electrum/constants.d.ts +7 -0
- package/dist/types/electrum/index.d.ts +85 -0
- package/dist/types/electrum.js +9 -0
- package/dist/types/electrum.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/shapes/electrum.d.ts +5 -0
- package/dist/types/shapes/index.d.ts +2 -0
- package/dist/types/shapes/wallet.d.ts +10 -0
- package/dist/types/transaction/index.d.ts +92 -0
- package/dist/types/transaction.js +12 -0
- package/dist/types/transaction.js.map +1 -0
- package/dist/types/types/electrum.d.ts +113 -0
- package/dist/types/types/index.d.ts +3 -0
- package/dist/types/types/transaction.d.ts +51 -0
- package/dist/types/types/wallet.d.ts +400 -0
- package/dist/types/utils/conversion.d.ts +10 -0
- package/dist/types/utils/derivation-path.d.ts +19 -0
- package/dist/types/utils/electrum.d.ts +10 -0
- package/dist/types/utils/exchange-rate.d.ts +30 -0
- package/dist/types/utils/helpers.d.ts +23 -0
- package/dist/types/utils/index.d.ts +7 -0
- package/dist/types/utils/result.d.ts +16 -0
- package/dist/types/utils/transaction.d.ts +21 -0
- package/dist/types/utils/wallet.d.ts +47 -0
- package/dist/types/wallet/constants.d.ts +12 -0
- package/dist/types/wallet/index.d.ts +214 -0
- package/dist/types/wallet.js +36 -0
- package/dist/types/wallet.js.map +1 -0
- package/dist/utils/conversion.js +52 -0
- package/dist/utils/conversion.js.map +1 -0
- package/dist/utils/derivation-path.js +104 -0
- package/dist/utils/derivation-path.js.map +1 -0
- package/dist/utils/electrum.js +149 -0
- package/dist/utils/electrum.js.map +1 -0
- package/dist/utils/exchange-rate.js +49 -0
- package/dist/utils/exchange-rate.js.map +1 -0
- package/dist/utils/helpers.js +137 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/index.js +24 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/result.js +36 -0
- package/dist/utils/result.js.map +1 -0
- package/dist/utils/transaction.js +327 -0
- package/dist/utils/transaction.js.map +1 -0
- package/dist/utils/wallet.js +227 -0
- package/dist/utils/wallet.js.map +1 -0
- package/dist/wallet/constants.js +15 -0
- package/dist/wallet/constants.js.map +1 -0
- package/dist/wallet/index.js +2113 -0
- package/dist/wallet/index.js.map +1 -0
- package/docs/html/.nojekyll +1 -0
- package/docs/html/assets/highlight.css +22 -0
- package/docs/html/assets/main.js +58 -0
- package/docs/html/assets/search.js +1 -0
- package/docs/html/assets/style.css +1367 -0
- package/docs/html/classes/Electrum.html +812 -0
- package/docs/html/classes/Transaction.html +687 -0
- package/docs/html/classes/Wallet.html +2030 -0
- package/docs/html/enums/EAddressType.html +227 -0
- package/docs/html/enums/EAvailableNetworks.html +255 -0
- package/docs/html/enums/EBoostType.html +220 -0
- package/docs/html/enums/EFeeId.html +241 -0
- package/docs/html/enums/EPaymentType.html +220 -0
- package/docs/html/enums/EProtocol.html +220 -0
- package/docs/html/enums/EUnit.html +227 -0
- package/docs/html/functions/availableNetworks.html +200 -0
- package/docs/html/functions/constructByteCountParam.html +210 -0
- package/docs/html/functions/decodeOpReturnMessage.html +202 -0
- package/docs/html/functions/decodeRawTransaction.html +210 -0
- package/docs/html/functions/err.html +214 -0
- package/docs/html/functions/formatKeyDerivationPath.html +219 -0
- package/docs/html/functions/formatPeerData.html +207 -0
- package/docs/html/functions/generateMnemonic.html +223 -0
- package/docs/html/functions/generateWalletId.html +202 -0
- package/docs/html/functions/getAddressFromScriptPubKey.html +209 -0
- package/docs/html/functions/getAddressTypeFromPath.html +206 -0
- package/docs/html/functions/getByteCount.html +206 -0
- package/docs/html/functions/getDataFallback.html +207 -0
- package/docs/html/functions/getDefaultPort.html +209 -0
- package/docs/html/functions/getDefaultWalletData.html +200 -0
- package/docs/html/functions/getDefaultWalletDataKeys.html +200 -0
- package/docs/html/functions/getExchangeRates.html +200 -0
- package/docs/html/functions/getHighestUsedIndexFromTxHashes.html +216 -0
- package/docs/html/functions/getKeyDerivationPath.html +211 -0
- package/docs/html/functions/getKeyDerivationPathObject.html +216 -0
- package/docs/html/functions/getKeyDerivationPathString.html +220 -0
- package/docs/html/functions/getKeyValue.html +206 -0
- package/docs/html/functions/getPeers.html +211 -0
- package/docs/html/functions/getProtocolForPort.html +209 -0
- package/docs/html/functions/getScriptHash.html +210 -0
- package/docs/html/functions/getSeed.html +209 -0
- package/docs/html/functions/getSeedHash.html +206 -0
- package/docs/html/functions/getSha256.html +206 -0
- package/docs/html/functions/getStorageKeyValues.html +209 -0
- package/docs/html/functions/getTxFee.html +210 -0
- package/docs/html/functions/getWalletDataStorageKey.html +206 -0
- package/docs/html/functions/isValidBech32mEncodedString.html +211 -0
- package/docs/html/functions/objectKeys-1.html +211 -0
- package/docs/html/functions/objectsMatch.html +210 -0
- package/docs/html/functions/ok.html +214 -0
- package/docs/html/functions/parseOnChainPaymentRequest.html +204 -0
- package/docs/html/functions/reduceValue.html +215 -0
- package/docs/html/functions/removeDustOutputs.html +206 -0
- package/docs/html/functions/setReplaceByFee.html +210 -0
- package/docs/html/functions/shuffleArray.html +211 -0
- package/docs/html/functions/validateAddress.html +216 -0
- package/docs/html/functions/validateMnemonic.html +206 -0
- package/docs/html/functions/validateTransaction.html +206 -0
- package/docs/html/index.html +360 -0
- package/docs/html/interfaces/IAddInput.html +231 -0
- package/docs/html/interfaces/IAddress.html +247 -0
- package/docs/html/interfaces/IAddressData.html +231 -0
- package/docs/html/interfaces/IAddressType.html +199 -0
- package/docs/html/interfaces/IAddressTypeData.html +252 -0
- package/docs/html/interfaces/IAddresses.html +199 -0
- package/docs/html/interfaces/IBoostedTransaction.html +238 -0
- package/docs/html/interfaces/IBoostedTransactions.html +199 -0
- package/docs/html/interfaces/ICreateTransaction.html +224 -0
- package/docs/html/interfaces/ICustomGetAddress.html +231 -0
- package/docs/html/interfaces/ICustomGetScriptHash.html +224 -0
- package/docs/html/interfaces/IElectrumGetAddressBalanceRes.html +235 -0
- package/docs/html/interfaces/IExchangeRates.html +210 -0
- package/docs/html/interfaces/IFormattedPeerData.html +245 -0
- package/docs/html/interfaces/IFormattedTransaction.html +343 -0
- package/docs/html/interfaces/IFormattedTransactions.html +199 -0
- package/docs/html/interfaces/IGenerateAddresses.html +252 -0
- package/docs/html/interfaces/IGenerateAddressesResponse.html +224 -0
- package/docs/html/interfaces/IGetAddress.html +231 -0
- package/docs/html/interfaces/IGetAddressBalanceRes.html +226 -0
- package/docs/html/interfaces/IGetAddressByPath.html +224 -0
- package/docs/html/interfaces/IGetAddressHistoryResponse.html +269 -0
- package/docs/html/interfaces/IGetAddressResponse.html +231 -0
- package/docs/html/interfaces/IGetAddressScriptHashesHistoryResponse.html +245 -0
- package/docs/html/interfaces/IGetDerivationPath.html +259 -0
- package/docs/html/interfaces/IGetFeeEstimatesResponse.html +238 -0
- package/docs/html/interfaces/IGetHeaderResponse.html +245 -0
- package/docs/html/interfaces/IGetNextAvailableAddressResponse.html +238 -0
- package/docs/html/interfaces/IGetTransactions.html +245 -0
- package/docs/html/interfaces/IGetTransactionsFromInputs.html +245 -0
- package/docs/html/interfaces/IGetUtxosResponse.html +224 -0
- package/docs/html/interfaces/IHeader.html +231 -0
- package/docs/html/interfaces/IIndexes.html +238 -0
- package/docs/html/interfaces/IKeyDerivationPath.html +247 -0
- package/docs/html/interfaces/IKeyDerivationPathData.html +224 -0
- package/docs/html/interfaces/INewBlock.html +224 -0
- package/docs/html/interfaces/IOnchainFees.html +245 -0
- package/docs/html/interfaces/IOutput.html +231 -0
- package/docs/html/interfaces/IPeerData.html +231 -0
- package/docs/html/interfaces/IRbfData.html +252 -0
- package/docs/html/interfaces/ISend.html +224 -0
- package/docs/html/interfaces/ISendTransaction.html +322 -0
- package/docs/html/interfaces/ISendTx.html +231 -0
- package/docs/html/interfaces/ISetupTransaction.html +238 -0
- package/docs/html/interfaces/ISubscribeToAddress.html +247 -0
- package/docs/html/interfaces/ISubscribeToHeader.html +245 -0
- package/docs/html/interfaces/ITargets.html +238 -0
- package/docs/html/interfaces/ITransaction.html +281 -0
- package/docs/html/interfaces/ITxHash.html +217 -0
- package/docs/html/interfaces/ITxHashes.html +235 -0
- package/docs/html/interfaces/IUtxo.html +275 -0
- package/docs/html/interfaces/IVin.html +252 -0
- package/docs/html/interfaces/IVout.html +246 -0
- package/docs/html/interfaces/IWallet.html +350 -0
- package/docs/html/interfaces/IWalletData.html +343 -0
- package/docs/html/types/ElectrumConnectionPubSub.html +233 -0
- package/docs/html/types/ElectrumConnectionSubscription.html +204 -0
- package/docs/html/types/InputData.html +203 -0
- package/docs/html/types/ObjectKeys.html +198 -0
- package/docs/html/types/Result.html +201 -0
- package/docs/html/types/TAddressIndexInfo.html +204 -0
- package/docs/html/types/TAddressLabel.html +193 -0
- package/docs/html/types/TAddressType.html +193 -0
- package/docs/html/types/TAddressTypeContent.html +198 -0
- package/docs/html/types/TAddressTypes.html +193 -0
- package/docs/html/types/TAvailableNetworks.html +193 -0
- package/docs/html/types/TConnectToElectrumRes.html +193 -0
- package/docs/html/types/TDecodeRawTx.html +214 -0
- package/docs/html/types/TElectrumNetworks.html +193 -0
- package/docs/html/types/TGetAddressHistory.html +200 -0
- package/docs/html/types/TGetByteCountInput.html +193 -0
- package/docs/html/types/TGetByteCountInputs.html +193 -0
- package/docs/html/types/TGetByteCountOutput.html +193 -0
- package/docs/html/types/TGetByteCountOutputs.html +193 -0
- package/docs/html/types/TGetData.html +211 -0
- package/docs/html/types/TGetTotalFeeObj.html +204 -0
- package/docs/html/types/TKeyDerivationAccount.html +193 -0
- package/docs/html/types/TKeyDerivationChange.html +193 -0
- package/docs/html/types/TKeyDerivationCoinType.html +193 -0
- package/docs/html/types/TKeyDerivationIndex.html +193 -0
- package/docs/html/types/TKeyDerivationPurpose.html +193 -0
- package/docs/html/types/TMessageDataMap.html +210 -0
- package/docs/html/types/TMessageKeys.html +193 -0
- package/docs/html/types/TOnMessage.html +213 -0
- package/docs/html/types/TProcessUnconfirmedTransactions.html +202 -0
- package/docs/html/types/TProtocol.html +193 -0
- package/docs/html/types/TServer.html +204 -0
- package/docs/html/types/TSetData.html +213 -0
- package/docs/html/types/TSetupTransactionResponse.html +193 -0
- package/docs/html/types/TStorage.html +200 -0
- package/docs/html/types/TSubscribedReceive.html +193 -0
- package/docs/html/types/TTransactionMessage.html +198 -0
- package/docs/html/types/TTxResponse.html +206 -0
- package/docs/html/types/TTxResult.html +200 -0
- package/docs/html/types/TUnspentAddressScriptHashData.html +198 -0
- package/docs/html/types/TWalletDataKeys.html +193 -0
- package/docs/html/variables/defaultElectrumPorts.html +193 -0
- package/docs/html/variables/electrumConnection.html +199 -0
- package/docs/html/variables/mostUsedExchangeTickers.html +241 -0
- package/docs/markdown/.nojekyll +1 -0
- package/docs/markdown/README.md +1875 -0
- package/docs/markdown/classes/Electrum.md +718 -0
- package/docs/markdown/classes/Transaction.md +536 -0
- package/docs/markdown/classes/Wallet.md +2189 -0
- package/docs/markdown/enums/EAddressType.md +41 -0
- package/docs/markdown/enums/EAvailableNetworks.md +85 -0
- package/docs/markdown/enums/EBoostType.md +30 -0
- package/docs/markdown/enums/EFeeId.md +63 -0
- package/docs/markdown/enums/EPaymentType.md +30 -0
- package/docs/markdown/enums/EProtocol.md +30 -0
- package/docs/markdown/enums/EUnit.md +41 -0
- package/docs/markdown/interfaces/IAddInput.md +41 -0
- package/docs/markdown/interfaces/IAddress.md +69 -0
- package/docs/markdown/interfaces/IAddressData.md +41 -0
- package/docs/markdown/interfaces/IAddressType.md +7 -0
- package/docs/markdown/interfaces/IAddressTypeData.md +74 -0
- package/docs/markdown/interfaces/IAddresses.md +7 -0
- package/docs/markdown/interfaces/IBoostedTransaction.md +52 -0
- package/docs/markdown/interfaces/IBoostedTransactions.md +7 -0
- package/docs/markdown/interfaces/ICreateTransaction.md +30 -0
- package/docs/markdown/interfaces/ICustomGetAddress.md +41 -0
- package/docs/markdown/interfaces/ICustomGetScriptHash.md +30 -0
- package/docs/markdown/interfaces/IElectrumGetAddressBalanceRes.md +55 -0
- package/docs/markdown/interfaces/IExchangeRates.md +7 -0
- package/docs/markdown/interfaces/IFormattedPeerData.md +63 -0
- package/docs/markdown/interfaces/IFormattedTransaction.md +217 -0
- package/docs/markdown/interfaces/IFormattedTransactions.md +7 -0
- package/docs/markdown/interfaces/IGenerateAddresses.md +74 -0
- package/docs/markdown/interfaces/IGenerateAddressesResponse.md +30 -0
- package/docs/markdown/interfaces/IGetAddress.md +41 -0
- package/docs/markdown/interfaces/IGetAddressBalanceRes.md +36 -0
- package/docs/markdown/interfaces/IGetAddressByPath.md +30 -0
- package/docs/markdown/interfaces/IGetAddressHistoryResponse.md +121 -0
- package/docs/markdown/interfaces/IGetAddressResponse.md +41 -0
- package/docs/markdown/interfaces/IGetAddressScriptHashesHistoryResponse.md +63 -0
- package/docs/markdown/interfaces/IGetDerivationPath.md +100 -0
- package/docs/markdown/interfaces/IGetFeeEstimatesResponse.md +52 -0
- package/docs/markdown/interfaces/IGetHeaderResponse.md +63 -0
- package/docs/markdown/interfaces/IGetNextAvailableAddressResponse.md +52 -0
- package/docs/markdown/interfaces/IGetTransactions.md +63 -0
- package/docs/markdown/interfaces/IGetTransactionsFromInputs.md +63 -0
- package/docs/markdown/interfaces/IGetUtxosResponse.md +30 -0
- package/docs/markdown/interfaces/IHeader.md +41 -0
- package/docs/markdown/interfaces/IIndexes.md +52 -0
- package/docs/markdown/interfaces/IKeyDerivationPath.md +69 -0
- package/docs/markdown/interfaces/IKeyDerivationPathData.md +30 -0
- package/docs/markdown/interfaces/INewBlock.md +30 -0
- package/docs/markdown/interfaces/IOnchainFees.md +63 -0
- package/docs/markdown/interfaces/IOutput.md +41 -0
- package/docs/markdown/interfaces/IPeerData.md +41 -0
- package/docs/markdown/interfaces/IRbfData.md +74 -0
- package/docs/markdown/interfaces/ISend.md +30 -0
- package/docs/markdown/interfaces/ISendTransaction.md +184 -0
- package/docs/markdown/interfaces/ISendTx.md +41 -0
- package/docs/markdown/interfaces/ISetupTransaction.md +52 -0
- package/docs/markdown/interfaces/ISubscribeToAddress.md +60 -0
- package/docs/markdown/interfaces/ISubscribeToHeader.md +59 -0
- package/docs/markdown/interfaces/ITargets.md +52 -0
- package/docs/markdown/interfaces/ITransaction.md +88 -0
- package/docs/markdown/interfaces/ITxHash.md +19 -0
- package/docs/markdown/interfaces/ITxHashes.md +55 -0
- package/docs/markdown/interfaces/IUtxo.md +112 -0
- package/docs/markdown/interfaces/IVin.md +70 -0
- package/docs/markdown/interfaces/IVout.md +52 -0
- package/docs/markdown/interfaces/IWallet.md +209 -0
- package/docs/markdown/interfaces/IWalletData.md +217 -0
- package/example/helpers.ts +76 -0
- package/example/index.ts +77 -0
- package/package.json +69 -0
- package/src/electrum/constants.ts +28 -0
- package/src/electrum/index.ts +838 -0
- package/src/index.ts +6 -0
- package/src/shapes/electrum.ts +13 -0
- package/src/shapes/index.ts +2 -0
- package/src/shapes/wallet.ts +133 -0
- package/src/transaction/index.ts +1078 -0
- package/src/types/electrum.ts +139 -0
- package/src/types/index.ts +3 -0
- package/src/types/transaction.ts +58 -0
- package/src/types/wallet.ts +503 -0
- package/src/utils/conversion.ts +88 -0
- package/src/utils/derivation-path.ts +171 -0
- package/src/utils/electrum.ts +188 -0
- package/src/utils/exchange-rate.ts +70 -0
- package/src/utils/helpers.ts +191 -0
- package/src/utils/index.ts +7 -0
- package/src/utils/result.ts +79 -0
- package/src/utils/transaction.ts +417 -0
- package/src/utils/wallet.ts +351 -0
- package/src/wallet/constants.ts +24 -0
- package/src/wallet/index.ts +3304 -0
- package/tests/constants.ts +9 -0
- package/tests/derivation.test.ts +146 -0
- package/tests/electrum.test.ts +137 -0
- package/tests/storage.test.ts +222 -0
- package/tests/transaction.test.ts +187 -0
- package/tests/wallet.test.ts +307 -0
- package/tsconfig.json +32 -0
- package/typedoc.json +5 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a result that can be successful (Ok) or contain an error (Err).
|
|
3
|
+
*/
|
|
4
|
+
export type Result<T> = Ok<T> | Err<T>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Represents a successful result containing a value of type T.
|
|
8
|
+
*/
|
|
9
|
+
class Ok<T> {
|
|
10
|
+
/**
|
|
11
|
+
* Constructs an Ok result containing the given value.
|
|
12
|
+
* @param value - The value contained in the result.
|
|
13
|
+
*/
|
|
14
|
+
public constructor(public readonly value: T) {}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Checks if the result is of type Ok.
|
|
18
|
+
* @returns True if the result is of type Ok, otherwise false.
|
|
19
|
+
*/
|
|
20
|
+
public isOk(): this is Ok<T> {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Checks if the result is of type Err.
|
|
26
|
+
* @returns False, as the result is of type Ok.
|
|
27
|
+
*/
|
|
28
|
+
public isErr(): this is Err<T> {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Represents an error result containing an error message.
|
|
35
|
+
*/
|
|
36
|
+
class Err<T> {
|
|
37
|
+
/**
|
|
38
|
+
* Constructs an Err result containing the given error.
|
|
39
|
+
* @param error - The error contained in the result.
|
|
40
|
+
*/
|
|
41
|
+
public constructor(public readonly error: Error) {
|
|
42
|
+
console.log(error);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Checks if the result is of type Ok.
|
|
47
|
+
* @returns False, as the result is of type Err.
|
|
48
|
+
*/
|
|
49
|
+
public isOk(): this is Ok<T> {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Checks if the result is of type Err.
|
|
55
|
+
* @returns True if the result is of type Err, otherwise false.
|
|
56
|
+
*/
|
|
57
|
+
public isErr(): this is Err<T> {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Construct a new Ok result value.
|
|
64
|
+
* @param value - The value to be wrapped in an Ok result.
|
|
65
|
+
* @returns An Ok result containing the given value.
|
|
66
|
+
*/
|
|
67
|
+
export const ok = <T>(value: T): Ok<T> => new Ok(value);
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Construct a new Err result value.
|
|
71
|
+
* @param error - The error message or Error object to be wrapped in an Err result.
|
|
72
|
+
* @returns An Err result containing the given error.
|
|
73
|
+
*/
|
|
74
|
+
export const err = <T>(error: Error | string): Err<T> => {
|
|
75
|
+
if (typeof error === 'string') {
|
|
76
|
+
return new Err(new Error(error));
|
|
77
|
+
}
|
|
78
|
+
return new Err(error);
|
|
79
|
+
};
|
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
import * as bitcoin from 'bitcoinjs-lib';
|
|
2
|
+
import { networks, Psbt } from 'bitcoinjs-lib';
|
|
3
|
+
import { Result, ok, err } from './result';
|
|
4
|
+
import {
|
|
5
|
+
EAddressType,
|
|
6
|
+
EAvailableNetworks,
|
|
7
|
+
IOutput,
|
|
8
|
+
ISendTransaction,
|
|
9
|
+
TDecodeRawTx,
|
|
10
|
+
TGetByteCountInput,
|
|
11
|
+
TGetByteCountInputs,
|
|
12
|
+
TGetByteCountOutput,
|
|
13
|
+
TGetByteCountOutputs
|
|
14
|
+
} from '../types';
|
|
15
|
+
import { objectKeys, reduceValue } from './wallet';
|
|
16
|
+
import validate, { getAddressInfo } from 'bitcoin-address-validation';
|
|
17
|
+
import * as bip21 from 'bip21';
|
|
18
|
+
import { TRANSACTION_DEFAULTS } from '../wallet/constants';
|
|
19
|
+
import { validateAddress } from './helpers';
|
|
20
|
+
import { btcToSats } from './conversion';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Sets RBF for the provided psbt.
|
|
24
|
+
* @param {Psbt} psbt
|
|
25
|
+
* @param {boolean} setRbf
|
|
26
|
+
* @returns {void}
|
|
27
|
+
*/
|
|
28
|
+
export const setReplaceByFee = ({
|
|
29
|
+
psbt,
|
|
30
|
+
setRbf = true
|
|
31
|
+
}: {
|
|
32
|
+
psbt: Psbt;
|
|
33
|
+
setRbf: boolean;
|
|
34
|
+
}): void => {
|
|
35
|
+
try {
|
|
36
|
+
const defaultSequence = bitcoin.Transaction.DEFAULT_SEQUENCE;
|
|
37
|
+
//Cannot set replace-by-fee on transaction without inputs.
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
39
|
+
// @ts-ignore type for Psbt is wrong
|
|
40
|
+
const ins = psbt.data.globalMap.unsignedTx.tx.ins;
|
|
41
|
+
if (ins.length !== 0) {
|
|
42
|
+
ins.forEach((x) => {
|
|
43
|
+
if (setRbf) {
|
|
44
|
+
if (x.sequence >= defaultSequence - 1) {
|
|
45
|
+
x.sequence = 0;
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
if (x.sequence < defaultSequence - 1) {
|
|
49
|
+
x.sequence = defaultSequence;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
} catch {}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/*
|
|
58
|
+
* Attempts to parse any given string as an on-chain payment request.
|
|
59
|
+
* Returns an error if invalid.
|
|
60
|
+
* @param {string} data
|
|
61
|
+
* @param {EAvailableNetworks} [network]
|
|
62
|
+
* @returns {Result<{address: string; network: EAvailableNetworks; sats: number; message: string;}>}
|
|
63
|
+
*/
|
|
64
|
+
export const parseOnChainPaymentRequest = (
|
|
65
|
+
data: string,
|
|
66
|
+
network?: EAvailableNetworks
|
|
67
|
+
): Result<{
|
|
68
|
+
address: string;
|
|
69
|
+
network: EAvailableNetworks;
|
|
70
|
+
sats: number;
|
|
71
|
+
message: string;
|
|
72
|
+
}> => {
|
|
73
|
+
try {
|
|
74
|
+
if (!data) {
|
|
75
|
+
return err('No data provided to parseOnChainPaymentRequest.');
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let validateAddressResult = validateAddress({ address: data, network });
|
|
79
|
+
|
|
80
|
+
if (
|
|
81
|
+
validateAddressResult.isValid &&
|
|
82
|
+
!data.includes(':' || '?' || '&' || '//')
|
|
83
|
+
) {
|
|
84
|
+
return ok({
|
|
85
|
+
address: data,
|
|
86
|
+
network: validateAddressResult.network,
|
|
87
|
+
sats: 0,
|
|
88
|
+
message: ''
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//Determine if we need to parse any invoice data.
|
|
93
|
+
if (data.includes(':' || '?' || '&' || '//')) {
|
|
94
|
+
try {
|
|
95
|
+
//Remove slashes
|
|
96
|
+
if (data.includes('//')) {
|
|
97
|
+
data = data.replace('//', '');
|
|
98
|
+
}
|
|
99
|
+
//bip21.decode will throw if anything other than "bitcoin" is passed to it.
|
|
100
|
+
//Replace any instance of "testnet" or "litecoin" with "bitcoin"
|
|
101
|
+
if (data.includes(':')) {
|
|
102
|
+
data = data.substring(data.indexOf(':') + 1);
|
|
103
|
+
data = `bitcoin:${data}`;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// types are wrong for package 'bip21'
|
|
107
|
+
const result = bip21.decode(data) as {
|
|
108
|
+
address: string;
|
|
109
|
+
options: { [key: string]: string };
|
|
110
|
+
};
|
|
111
|
+
const address = result.address;
|
|
112
|
+
validateAddressResult = validateAddress({ address, network });
|
|
113
|
+
//Ensure address is valid
|
|
114
|
+
if (!validateAddressResult.isValid) {
|
|
115
|
+
return err(`Invalid address: ${data}`);
|
|
116
|
+
}
|
|
117
|
+
let amount = 0;
|
|
118
|
+
let message = '';
|
|
119
|
+
try {
|
|
120
|
+
amount = Number(result.options.amount) || 0;
|
|
121
|
+
} catch (e) {}
|
|
122
|
+
try {
|
|
123
|
+
message = result.options.message || '';
|
|
124
|
+
} catch (e) {}
|
|
125
|
+
return ok({
|
|
126
|
+
address,
|
|
127
|
+
network: validateAddressResult.network,
|
|
128
|
+
sats: btcToSats(amount),
|
|
129
|
+
message
|
|
130
|
+
});
|
|
131
|
+
} catch {
|
|
132
|
+
return err(data);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return err(data);
|
|
136
|
+
} catch {
|
|
137
|
+
return err(data);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Constructs the parameter for getByteCount via an array of addresses.
|
|
143
|
+
* @param {string[]} addresses
|
|
144
|
+
* @param increaseAddressCount
|
|
145
|
+
* @returns {TGetByteCountInputs | TGetByteCountOutputs}y
|
|
146
|
+
*/
|
|
147
|
+
export const constructByteCountParam = (
|
|
148
|
+
addresses: string[],
|
|
149
|
+
increaseAddressCount: { addrType: EAddressType; count: number }[] = []
|
|
150
|
+
): TGetByteCountInputs | TGetByteCountOutputs => {
|
|
151
|
+
try {
|
|
152
|
+
if (addresses.length <= 0) {
|
|
153
|
+
return { P2WPKH: 0 };
|
|
154
|
+
}
|
|
155
|
+
const param: TGetByteCountOutputs = {};
|
|
156
|
+
addresses.map((address) => {
|
|
157
|
+
if (validate(address)) {
|
|
158
|
+
const addressType = getAddressInfo(address).type.toUpperCase();
|
|
159
|
+
param[addressType] = param[addressType] ? param[addressType] + 1 : 1;
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
increaseAddressCount.forEach(({ addrType, count }) => {
|
|
163
|
+
param[addrType] = (param[addrType] ?? 0) + count;
|
|
164
|
+
});
|
|
165
|
+
return param;
|
|
166
|
+
} catch {
|
|
167
|
+
return { P2WPKH: 0 };
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
/*
|
|
172
|
+
Adapted from: https://gist.github.com/junderw/b43af3253ea5865ed52cb51c200ac19c
|
|
173
|
+
Usage:
|
|
174
|
+
getByteCount({'MULTISIG-P2SH:2-4':45},{'P2PKH':1}) Means "45 inputs of P2SH Multisig and 1 output of P2PKH"
|
|
175
|
+
getByteCount({'P2PKH':1,'MULTISIG-P2SH:2-3':2},{'P2PKH':2}) means "1 P2PKH input and 2 Multisig P2SH (2 of 3) inputs along with 2 P2PKH outputs"
|
|
176
|
+
@param {TGetByteCountInputs} inputs
|
|
177
|
+
@param {TGetByteCountOutputs} outputs
|
|
178
|
+
@param {string} [message]
|
|
179
|
+
@returns {number}
|
|
180
|
+
*/
|
|
181
|
+
export const getByteCount = (
|
|
182
|
+
inputs: TGetByteCountInputs,
|
|
183
|
+
outputs: TGetByteCountOutputs,
|
|
184
|
+
message?: string
|
|
185
|
+
): number => {
|
|
186
|
+
try {
|
|
187
|
+
// Base transaction weight
|
|
188
|
+
let totalWeight = 40;
|
|
189
|
+
let hasWitness = false;
|
|
190
|
+
|
|
191
|
+
const types: {
|
|
192
|
+
inputs: {
|
|
193
|
+
[key in TGetByteCountInput]: number;
|
|
194
|
+
};
|
|
195
|
+
multiSigInputs: {
|
|
196
|
+
'MULTISIG-P2SH': number;
|
|
197
|
+
'MULTISIG-P2WSH': number;
|
|
198
|
+
'MULTISIG-P2SH-P2WSH': number;
|
|
199
|
+
};
|
|
200
|
+
outputs: {
|
|
201
|
+
[key in TGetByteCountOutput]: number;
|
|
202
|
+
};
|
|
203
|
+
} = {
|
|
204
|
+
inputs: {
|
|
205
|
+
P2WPKH: 108 + 41 * 4,
|
|
206
|
+
p2wpkh: 108 + 41 * 4 + 1,
|
|
207
|
+
P2PKH: 148 * 4,
|
|
208
|
+
p2pkh: 148 * 4 + 1,
|
|
209
|
+
P2SH: 108 + 64 * 4,
|
|
210
|
+
p2sh: 108 + 64 * 4 + 1,
|
|
211
|
+
'P2SH-P2WPKH': 108 + 64 * 4,
|
|
212
|
+
P2TR: 57.5 * 4,
|
|
213
|
+
p2tr: 57.5 * 4 + 1
|
|
214
|
+
},
|
|
215
|
+
multiSigInputs: {
|
|
216
|
+
'MULTISIG-P2SH': 49 * 4,
|
|
217
|
+
'MULTISIG-P2WSH': 6 + 41 * 4,
|
|
218
|
+
'MULTISIG-P2SH-P2WSH': 6 + 76 * 4
|
|
219
|
+
},
|
|
220
|
+
outputs: {
|
|
221
|
+
P2SH: 32 * 4,
|
|
222
|
+
P2PKH: 34 * 4,
|
|
223
|
+
P2WPKH: 31 * 4,
|
|
224
|
+
P2WSH: 43 * 4,
|
|
225
|
+
p2wpkh: 31 * 4 + 1,
|
|
226
|
+
p2sh: 32 * 4 + 1,
|
|
227
|
+
p2pkh: 34 * 4 + 1,
|
|
228
|
+
P2TR: 43 * 4,
|
|
229
|
+
p2tr: 43 * 4 + 1
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
const checkUInt53 = (n: number): void => {
|
|
234
|
+
if (n < 0 || n > Number.MAX_SAFE_INTEGER || n % 1 !== 0) {
|
|
235
|
+
throw new RangeError('value out of range');
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
const inputKeys = objectKeys(inputs);
|
|
240
|
+
inputKeys.forEach(function (key) {
|
|
241
|
+
const input = inputs[key]!;
|
|
242
|
+
checkUInt53(input);
|
|
243
|
+
const addressTypeCount = input || 1;
|
|
244
|
+
if (key.slice(0, 8) === 'MULTISIG') {
|
|
245
|
+
// ex. "MULTISIG-P2SH:2-3" would mean 2 of 3 P2SH MULTISIG
|
|
246
|
+
const keyParts = key.split(':');
|
|
247
|
+
if (keyParts.length !== 2) {
|
|
248
|
+
throw new Error('invalid input: ' + key);
|
|
249
|
+
}
|
|
250
|
+
const newKey = keyParts[0];
|
|
251
|
+
const mAndN = keyParts[1].split('-').map((item) => parseInt(item, 10));
|
|
252
|
+
|
|
253
|
+
totalWeight += types.multiSigInputs[newKey] * addressTypeCount;
|
|
254
|
+
const multiplyer = newKey === 'MULTISIG-P2SH' ? 4 : 1;
|
|
255
|
+
totalWeight +=
|
|
256
|
+
(73 * mAndN[0] + 34 * mAndN[1]) * multiplyer * addressTypeCount;
|
|
257
|
+
} else {
|
|
258
|
+
totalWeight += types.inputs[key] * addressTypeCount;
|
|
259
|
+
}
|
|
260
|
+
if (['p2sh', 'P2SH', 'P2SH-P2WPKH', 'p2wpkh', 'P2WPKH'].includes(key)) {
|
|
261
|
+
hasWitness = true;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const outputKeys = objectKeys(outputs);
|
|
266
|
+
outputKeys.forEach(function (key) {
|
|
267
|
+
const output = outputs[key]!;
|
|
268
|
+
checkUInt53(output);
|
|
269
|
+
totalWeight += types.outputs[key] * output;
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
if (hasWitness) {
|
|
273
|
+
totalWeight += 2;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (message?.length) {
|
|
277
|
+
// Multiply by 2 to help ensure Electrum servers will broadcast the tx.
|
|
278
|
+
totalWeight += message.length * 2;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Convert from Weight Units to virtual size
|
|
282
|
+
return Math.ceil(totalWeight / 4);
|
|
283
|
+
} catch {
|
|
284
|
+
return TRANSACTION_DEFAULTS.recommendedBaseFee;
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Removes outputs that are below the dust limit.
|
|
290
|
+
* @param {IOutput[]} outputs
|
|
291
|
+
* @returns {IOutput[]}
|
|
292
|
+
*/
|
|
293
|
+
export const removeDustOutputs = (outputs: IOutput[]): IOutput[] => {
|
|
294
|
+
return outputs.filter((output) => {
|
|
295
|
+
return output.value > TRANSACTION_DEFAULTS.dustLimit;
|
|
296
|
+
});
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Used to validate transaction form data.
|
|
301
|
+
* @param {ISendTransaction} transaction
|
|
302
|
+
* @return {Result<string>}
|
|
303
|
+
*/
|
|
304
|
+
export const validateTransaction = (
|
|
305
|
+
transaction: ISendTransaction
|
|
306
|
+
): Result<string> => {
|
|
307
|
+
const baseFee = TRANSACTION_DEFAULTS.recommendedBaseFee;
|
|
308
|
+
|
|
309
|
+
try {
|
|
310
|
+
if (!transaction.fee) {
|
|
311
|
+
return err('No transaction fee provided.');
|
|
312
|
+
}
|
|
313
|
+
if (transaction.outputs.length < 1 || !transaction.outputs[0].address) {
|
|
314
|
+
return err('Please provide an address to send funds to.');
|
|
315
|
+
}
|
|
316
|
+
if (transaction.outputs.length > 0 && !transaction.outputs[0].value) {
|
|
317
|
+
return err('Please provide an amount to send.');
|
|
318
|
+
}
|
|
319
|
+
const inputs = transaction.inputs;
|
|
320
|
+
const outputs = transaction.outputs;
|
|
321
|
+
for (let i = 0; i < outputs.length; i++) {
|
|
322
|
+
const address = outputs[i]?.address ?? '';
|
|
323
|
+
const value = outputs[i]?.value ?? 0;
|
|
324
|
+
const { isValid } = validateAddress({ address });
|
|
325
|
+
if (!isValid) {
|
|
326
|
+
return err(`Invalid Address: ${address}`);
|
|
327
|
+
}
|
|
328
|
+
if (value < baseFee) {
|
|
329
|
+
return err(
|
|
330
|
+
`Output value for ${address} must be greater than or equal to ${baseFee} sats`
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
if (!Number.isInteger(value)) {
|
|
334
|
+
return err(`Output value for ${address} should be an integer`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
const inputsReduce = reduceValue({
|
|
339
|
+
arr: inputs,
|
|
340
|
+
value: 'value'
|
|
341
|
+
});
|
|
342
|
+
if (inputsReduce.isErr()) {
|
|
343
|
+
return err(inputsReduce.error.message);
|
|
344
|
+
}
|
|
345
|
+
//Remove the change address from the outputs array, if any.
|
|
346
|
+
let filteredOutputs = outputs;
|
|
347
|
+
if (transaction.changeAddress) {
|
|
348
|
+
filteredOutputs = outputs.filter((output) => {
|
|
349
|
+
return output.address !== transaction.changeAddress;
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
const outputsReduce = reduceValue({
|
|
353
|
+
arr: filteredOutputs,
|
|
354
|
+
value: 'value'
|
|
355
|
+
});
|
|
356
|
+
if (outputsReduce.isErr()) {
|
|
357
|
+
return err(outputsReduce.error.message);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
return ok('Transaction is valid.');
|
|
361
|
+
} catch (e) {
|
|
362
|
+
return err(e);
|
|
363
|
+
}
|
|
364
|
+
};
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* Attempts to decode a raw tx hex.
|
|
368
|
+
* Source: https://github.com/bitcoinjs/bitcoinjs-lib/issues/1606#issuecomment-664740672
|
|
369
|
+
* @param {string} hex
|
|
370
|
+
* @param {EAvailableNetworks} [_network]
|
|
371
|
+
* @returns {Result<TDecodeRawTx>}
|
|
372
|
+
*/
|
|
373
|
+
export const decodeRawTransaction = (
|
|
374
|
+
hex: string,
|
|
375
|
+
_network: EAvailableNetworks
|
|
376
|
+
): Result<TDecodeRawTx> => {
|
|
377
|
+
try {
|
|
378
|
+
const network = networks[_network];
|
|
379
|
+
const tx = bitcoin.Transaction.fromHex(hex);
|
|
380
|
+
return ok({
|
|
381
|
+
txid: tx.getId(),
|
|
382
|
+
tx_hash: tx.getHash(true).toString('hex'),
|
|
383
|
+
size: tx.byteLength(),
|
|
384
|
+
vsize: tx.virtualSize(),
|
|
385
|
+
weight: tx.weight(),
|
|
386
|
+
version: tx.version,
|
|
387
|
+
locktime: tx.locktime,
|
|
388
|
+
vin: tx.ins.map((input) => ({
|
|
389
|
+
txid: Buffer.from(input.hash).reverse().toString('hex'),
|
|
390
|
+
vout: input.index,
|
|
391
|
+
scriptSig: {
|
|
392
|
+
asm: bitcoin.script.toASM(input.script),
|
|
393
|
+
hex: input.script.toString('hex')
|
|
394
|
+
},
|
|
395
|
+
txinwitness: input.witness.map((b) => b.toString('hex')),
|
|
396
|
+
sequence: input.sequence
|
|
397
|
+
})),
|
|
398
|
+
vout: tx.outs.map((output, i) => {
|
|
399
|
+
let address;
|
|
400
|
+
try {
|
|
401
|
+
address = bitcoin.address.fromOutputScript(output.script, network);
|
|
402
|
+
} catch (e) {}
|
|
403
|
+
return {
|
|
404
|
+
value: output.value,
|
|
405
|
+
n: i,
|
|
406
|
+
scriptPubKey: {
|
|
407
|
+
asm: bitcoin.script.toASM(output.script),
|
|
408
|
+
hex: output.script.toString('hex'),
|
|
409
|
+
address
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
})
|
|
413
|
+
});
|
|
414
|
+
} catch (e) {
|
|
415
|
+
return err(e);
|
|
416
|
+
}
|
|
417
|
+
};
|