beignet 0.0.1 → 0.0.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/electrum/index.js +31 -17
- package/dist/electrum/index.js.map +1 -1
- package/dist/transaction/index.js +18 -6
- package/dist/transaction/index.js.map +1 -1
- package/dist/types/electrum/index.d.ts +2 -2
- package/dist/types/types/electrum.d.ts +16 -0
- package/dist/types/types/wallet.d.ts +1 -0
- package/dist/types/utils/transaction.d.ts +1 -1
- package/dist/types/wallet/index.d.ts +8 -1
- package/dist/types/wallet.js.map +1 -1
- package/dist/utils/transaction.js +4 -3
- package/dist/utils/transaction.js.map +1 -1
- package/dist/wallet/index.js +109 -40
- package/dist/wallet/index.js.map +1 -1
- package/package.json +1 -1
- package/src/electrum/index.ts +52 -31
- package/src/transaction/index.ts +30 -7
- package/src/types/electrum.ts +19 -0
- package/src/types/wallet.ts +3 -2
- package/src/utils/transaction.ts +7 -4
- package/src/wallet/index.ts +240 -133
- package/tests/electrum.test.ts +5 -1
- package/tests/transaction.test.ts +21 -15
package/dist/wallet/index.js
CHANGED
|
@@ -45,6 +45,7 @@ class Wallet {
|
|
|
45
45
|
constructor({ mnemonic, passphrase, name, network = types_1.EAvailableNetworks.mainnet, addressType = types_1.EAddressType.p2wpkh, storage, electrumOptions, onMessage = () => null, customGetAddress, customGetScriptHash, rbf = false, selectedFeeId = types_1.EFeeId.normal }) {
|
|
46
46
|
var _a;
|
|
47
47
|
this._pendingRefreshPromises = [];
|
|
48
|
+
this.savingOperations = {};
|
|
48
49
|
this.getReceiveAddress = async ({ addressType = this.data.addressType }) => {
|
|
49
50
|
try {
|
|
50
51
|
const wallet = this.data;
|
|
@@ -90,10 +91,15 @@ class Wallet {
|
|
|
90
91
|
return this.data.boostedTransactions;
|
|
91
92
|
};
|
|
92
93
|
this.getBip32Interface = async () => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
try {
|
|
95
|
+
const network = bitcoinjs_lib_1.networks[this._network];
|
|
96
|
+
const seed = await bip39.mnemonicToSeed(this._mnemonic, this._passphrase);
|
|
97
|
+
const root = bip32.fromSeed(seed, network);
|
|
98
|
+
return (0, utils_1.ok)(root);
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
return (0, utils_1.err)(e);
|
|
102
|
+
}
|
|
97
103
|
};
|
|
98
104
|
if (!mnemonic)
|
|
99
105
|
throw new Error('No mnemonic specified.');
|
|
@@ -267,7 +273,7 @@ class Wallet {
|
|
|
267
273
|
try {
|
|
268
274
|
const walletDataKeys = (0, utils_1.getDefaultWalletDataKeys)();
|
|
269
275
|
const walletData = (0, utils_1.getDefaultWalletData)();
|
|
270
|
-
|
|
276
|
+
await Promise.all(walletDataKeys.map(async (key) => {
|
|
271
277
|
let dataResult;
|
|
272
278
|
try {
|
|
273
279
|
const walletDataKey = this.getWalletDataKey(key);
|
|
@@ -334,7 +340,7 @@ class Wallet {
|
|
|
334
340
|
default:
|
|
335
341
|
return (0, utils_1.err)(`Unhandled key in getWalletData: ${key}`);
|
|
336
342
|
}
|
|
337
|
-
}
|
|
343
|
+
}));
|
|
338
344
|
return (0, utils_1.ok)(walletData);
|
|
339
345
|
}
|
|
340
346
|
catch (e) {
|
|
@@ -478,8 +484,8 @@ class Wallet {
|
|
|
478
484
|
return await this.getScriptHash({ address, network });
|
|
479
485
|
}));
|
|
480
486
|
const res = await this.electrum.getAddressScriptHashBalances(scriptHashes);
|
|
481
|
-
if (res.error) {
|
|
482
|
-
return (0, utils_1.err)(res.data);
|
|
487
|
+
if (res.error || typeof res.data === 'string') {
|
|
488
|
+
return (0, utils_1.err)(JSON.stringify(res.data));
|
|
483
489
|
}
|
|
484
490
|
return (0, utils_1.ok)(res.data.reduce((acc, cur) => {
|
|
485
491
|
var _a, _b, _c, _d;
|
|
@@ -663,7 +669,8 @@ class Wallet {
|
|
|
663
669
|
addressIndex: addressIndex.index,
|
|
664
670
|
changeAddressIndex: 0,
|
|
665
671
|
keyDerivationPath,
|
|
666
|
-
addressType
|
|
672
|
+
addressType,
|
|
673
|
+
saveAddresses: false
|
|
667
674
|
});
|
|
668
675
|
if (newAddresses.isOk()) {
|
|
669
676
|
addresses = newAddresses.value.addresses;
|
|
@@ -677,7 +684,8 @@ class Wallet {
|
|
|
677
684
|
addressIndex: 0,
|
|
678
685
|
changeAddressIndex: changeAddressIndex.index,
|
|
679
686
|
keyDerivationPath,
|
|
680
|
-
addressType
|
|
687
|
+
addressType,
|
|
688
|
+
saveAddresses: false
|
|
681
689
|
});
|
|
682
690
|
if (newChangeAddresses.isOk()) {
|
|
683
691
|
changeAddresses = newChangeAddresses.value.changeAddresses;
|
|
@@ -783,7 +791,8 @@ class Wallet {
|
|
|
783
791
|
addressIndex: highestStoredIndex.value.addressIndex.index,
|
|
784
792
|
changeAddressIndex: 0,
|
|
785
793
|
keyDerivationPath,
|
|
786
|
-
addressType
|
|
794
|
+
addressType,
|
|
795
|
+
saveAddresses: false
|
|
787
796
|
});
|
|
788
797
|
if (newAddresses.isOk()) {
|
|
789
798
|
addresses = newAddresses.value.addresses || {};
|
|
@@ -796,7 +805,8 @@ class Wallet {
|
|
|
796
805
|
addressIndex: 0,
|
|
797
806
|
changeAddressIndex: highestStoredIndex.value.changeAddressIndex.index,
|
|
798
807
|
keyDerivationPath,
|
|
799
|
-
addressType
|
|
808
|
+
addressType,
|
|
809
|
+
saveAddresses: false
|
|
800
810
|
});
|
|
801
811
|
if (newChangeAddresses.isOk()) {
|
|
802
812
|
changeAddresses = newChangeAddresses.value.changeAddresses || {};
|
|
@@ -811,6 +821,10 @@ class Wallet {
|
|
|
811
821
|
allAddresses = [...allAddresses, ...addressesToScan];
|
|
812
822
|
allChangeAddresses = [...allChangeAddresses, ...changeAddressesToScan];
|
|
813
823
|
}
|
|
824
|
+
await Promise.all([
|
|
825
|
+
this.saveWalletData('addresses', this._data.addresses),
|
|
826
|
+
this.saveWalletData('changeAddresses', this._data.changeAddresses)
|
|
827
|
+
]);
|
|
814
828
|
return lastKnownIndexes;
|
|
815
829
|
}
|
|
816
830
|
catch (e) {
|
|
@@ -832,7 +846,7 @@ class Wallet {
|
|
|
832
846
|
return (0, utils_1.err)(e);
|
|
833
847
|
}
|
|
834
848
|
}
|
|
835
|
-
async addAddresses({ addressAmount = 5, changeAddressAmount = 5, addressIndex = 0, changeAddressIndex = 0, addressType, keyDerivationPath }) {
|
|
849
|
+
async addAddresses({ addressAmount = 5, changeAddressAmount = 5, addressIndex = 0, changeAddressIndex = 0, addressType, keyDerivationPath, saveAddresses = true }) {
|
|
836
850
|
if (!addressType) {
|
|
837
851
|
addressType = this.data.addressType;
|
|
838
852
|
}
|
|
@@ -870,11 +884,13 @@ class Wallet {
|
|
|
870
884
|
const changeAddresses = removeDuplicateResponse.value.changeAddresses;
|
|
871
885
|
if (Object.keys(addresses).length) {
|
|
872
886
|
this._data.addresses[addressType] = Object.assign(Object.assign({}, this.data.addresses[addressType]), addresses);
|
|
873
|
-
|
|
887
|
+
if (saveAddresses)
|
|
888
|
+
await this.saveWalletData('addresses', this._data.addresses);
|
|
874
889
|
}
|
|
875
890
|
if (Object.keys(changeAddresses).length) {
|
|
876
891
|
this._data.changeAddresses[addressType] = Object.assign(Object.assign({}, this.data.changeAddresses[addressType]), changeAddresses);
|
|
877
|
-
|
|
892
|
+
if (saveAddresses)
|
|
893
|
+
await this.saveWalletData('changeAddresses', this._data.changeAddresses);
|
|
878
894
|
}
|
|
879
895
|
return (0, utils_1.ok)(Object.assign(Object.assign({}, generatedAddresses.value), { addressType: type }));
|
|
880
896
|
}
|
|
@@ -983,17 +999,19 @@ class Wallet {
|
|
|
983
999
|
this._data.lastUsedAddressIndex[addressTypeKey] = lastUsedAddressIndex;
|
|
984
1000
|
this._data.lastUsedChangeAddressIndex[addressTypeKey] =
|
|
985
1001
|
lastUsedChangeAddressIndex;
|
|
1002
|
+
updated = true;
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
try {
|
|
1006
|
+
await Promise.all(promises);
|
|
1007
|
+
if (updated) {
|
|
986
1008
|
await Promise.all([
|
|
987
1009
|
this.saveWalletData('addressIndex', this._data.addressIndex),
|
|
988
1010
|
this.saveWalletData('changeAddressIndex', this._data.changeAddressIndex),
|
|
989
1011
|
this.saveWalletData('lastUsedAddressIndex', this._data.lastUsedAddressIndex),
|
|
990
1012
|
this.saveWalletData('lastUsedChangeAddressIndex', this._data.lastUsedChangeAddressIndex)
|
|
991
1013
|
]);
|
|
992
|
-
updated = true;
|
|
993
1014
|
}
|
|
994
|
-
});
|
|
995
|
-
try {
|
|
996
|
-
await Promise.all(promises);
|
|
997
1015
|
return (0, utils_1.ok)(updated ? 'Successfully updated indexes.' : 'No update needed.');
|
|
998
1016
|
}
|
|
999
1017
|
catch (e) {
|
|
@@ -1048,9 +1066,7 @@ class Wallet {
|
|
|
1048
1066
|
});
|
|
1049
1067
|
if (nextAddressIndex) {
|
|
1050
1068
|
this._data.addressIndex[addressType] = nextAddressIndex;
|
|
1051
|
-
await
|
|
1052
|
-
this.saveWalletData('addressIndex', this._data.addressIndex)
|
|
1053
|
-
]);
|
|
1069
|
+
await this.saveWalletData('addressIndex', this._data.addressIndex);
|
|
1054
1070
|
return (0, utils_1.ok)(nextAddressIndex);
|
|
1055
1071
|
}
|
|
1056
1072
|
const addAddressesRes = await this.addAddresses({
|
|
@@ -1064,14 +1080,13 @@ class Wallet {
|
|
|
1064
1080
|
if (addAddressesRes.isErr()) {
|
|
1065
1081
|
return (0, utils_1.err)(addAddressesRes.error.message);
|
|
1066
1082
|
}
|
|
1067
|
-
const
|
|
1068
|
-
if (!
|
|
1083
|
+
const addressIndex = Object.values(this.data.addresses[addressType]).find((addr) => addr.index === currentAddressIndex + 1);
|
|
1084
|
+
if (!addressIndex) {
|
|
1069
1085
|
return (0, utils_1.err)('Unable to generate addresses at this time.');
|
|
1070
1086
|
}
|
|
1071
|
-
|
|
1072
|
-
this._data.addressIndex[addressType] = newAddressIndex;
|
|
1087
|
+
this._data.addressIndex[addressType] = addressIndex;
|
|
1073
1088
|
await this.saveWalletData('addressIndex', this._data.addressIndex);
|
|
1074
|
-
return (0, utils_1.ok)(
|
|
1089
|
+
return (0, utils_1.ok)(addressIndex);
|
|
1075
1090
|
}
|
|
1076
1091
|
catch (e) {
|
|
1077
1092
|
return (0, utils_1.err)(e);
|
|
@@ -1120,9 +1135,22 @@ class Wallet {
|
|
|
1120
1135
|
}
|
|
1121
1136
|
async saveWalletData(key, data) {
|
|
1122
1137
|
if (!this._setData)
|
|
1123
|
-
return;
|
|
1138
|
+
return 'No setData method has been provided';
|
|
1139
|
+
if (key in this.savingOperations) {
|
|
1140
|
+
await this.savingOperations[key];
|
|
1141
|
+
}
|
|
1124
1142
|
const walletDataKey = this.getWalletDataKey(key);
|
|
1125
|
-
|
|
1143
|
+
this.savingOperations[key] = this._setData(walletDataKey, data)
|
|
1144
|
+
.then(() => {
|
|
1145
|
+
return `${walletDataKey} data saved successfully`;
|
|
1146
|
+
})
|
|
1147
|
+
.catch((error) => {
|
|
1148
|
+
return `Error saving wallet data for ${walletDataKey}: ${error}`;
|
|
1149
|
+
})
|
|
1150
|
+
.finally(() => {
|
|
1151
|
+
delete this.savingOperations[key];
|
|
1152
|
+
});
|
|
1153
|
+
return await this.savingOperations[key];
|
|
1126
1154
|
}
|
|
1127
1155
|
async updateAndSaveWalletData(key, data, addressType) {
|
|
1128
1156
|
if (addressType) {
|
|
@@ -1198,15 +1226,15 @@ class Wallet {
|
|
|
1198
1226
|
this._data.transactions = Object.assign(Object.assign({}, this._data.transactions), formattedTransactions);
|
|
1199
1227
|
await this.saveWalletData('transactions', this._data.transactions);
|
|
1200
1228
|
if (this.onMessage) {
|
|
1201
|
-
confirmedTxs.forEach((tx) => {
|
|
1202
|
-
this.onMessage('transactionConfirmed', tx);
|
|
1203
|
-
});
|
|
1204
1229
|
sentTxs.forEach((tx) => {
|
|
1205
1230
|
this.onMessage('transactionSent', tx);
|
|
1206
1231
|
});
|
|
1207
1232
|
receivedTxs.forEach((tx) => {
|
|
1208
1233
|
this.onMessage('transactionReceived', tx);
|
|
1209
1234
|
});
|
|
1235
|
+
confirmedTxs.forEach((tx) => {
|
|
1236
|
+
this.onMessage('transactionConfirmed', tx);
|
|
1237
|
+
});
|
|
1210
1238
|
}
|
|
1211
1239
|
return (0, utils_1.ok)(notificationTxid);
|
|
1212
1240
|
}
|
|
@@ -1231,9 +1259,7 @@ class Wallet {
|
|
|
1231
1259
|
}
|
|
1232
1260
|
else {
|
|
1233
1261
|
this._data.unconfirmedTransactions = unconfirmedTxs;
|
|
1234
|
-
await
|
|
1235
|
-
this.saveWalletData('unconfirmedTransactions', this._data.unconfirmedTransactions)
|
|
1236
|
-
]);
|
|
1262
|
+
await this.saveWalletData('unconfirmedTransactions', this._data.unconfirmedTransactions);
|
|
1237
1263
|
}
|
|
1238
1264
|
return (0, utils_1.ok)('Successfully updated unconfirmed transactions.');
|
|
1239
1265
|
}
|
|
@@ -1644,6 +1670,9 @@ class Wallet {
|
|
|
1644
1670
|
});
|
|
1645
1671
|
}
|
|
1646
1672
|
async sendMany({ txs = [], satsPerByte = this.feeEstimates.normal, rbf, broadcast = true, shuffleOutputs = true }) {
|
|
1673
|
+
if (!this.data.utxos.length) {
|
|
1674
|
+
return (0, utils_1.err)('No UTXOs available.');
|
|
1675
|
+
}
|
|
1647
1676
|
const setupTransactionRes = await this.transaction.setupTransaction({
|
|
1648
1677
|
rbf
|
|
1649
1678
|
});
|
|
@@ -1693,6 +1722,39 @@ class Wallet {
|
|
|
1693
1722
|
return (0, utils_1.err)(broadcastRes.error.message);
|
|
1694
1723
|
return (0, utils_1.ok)(broadcastRes.value);
|
|
1695
1724
|
}
|
|
1725
|
+
async sendMax({ address, satsPerByte, rbf = false, broadcast = true } = {}) {
|
|
1726
|
+
if (!this.data.utxos.length) {
|
|
1727
|
+
return (0, utils_1.err)('No UTXOs available.');
|
|
1728
|
+
}
|
|
1729
|
+
await this.resetSendTransaction();
|
|
1730
|
+
const setupTransactionRes = await this.transaction.setupTransaction();
|
|
1731
|
+
if (setupTransactionRes.isErr()) {
|
|
1732
|
+
return (0, utils_1.err)(setupTransactionRes.error.message);
|
|
1733
|
+
}
|
|
1734
|
+
const sendMaxRes = await this.transaction.sendMax({
|
|
1735
|
+
address,
|
|
1736
|
+
satsPerByte,
|
|
1737
|
+
rbf
|
|
1738
|
+
});
|
|
1739
|
+
if (sendMaxRes.isErr()) {
|
|
1740
|
+
return (0, utils_1.err)(sendMaxRes.error.message);
|
|
1741
|
+
}
|
|
1742
|
+
const createRes = await this.transaction.createTransaction({
|
|
1743
|
+
shuffleOutputs: true
|
|
1744
|
+
});
|
|
1745
|
+
if (createRes.isErr())
|
|
1746
|
+
return (0, utils_1.err)(createRes.error.message);
|
|
1747
|
+
const { hex } = createRes.value;
|
|
1748
|
+
if (!broadcast) {
|
|
1749
|
+
return (0, utils_1.ok)(hex);
|
|
1750
|
+
}
|
|
1751
|
+
const broadcastRes = await this.electrum.broadcastTransaction({
|
|
1752
|
+
rawTx: hex
|
|
1753
|
+
});
|
|
1754
|
+
if (broadcastRes.isErr())
|
|
1755
|
+
return (0, utils_1.err)(broadcastRes.error.message);
|
|
1756
|
+
return (0, utils_1.ok)(broadcastRes.value);
|
|
1757
|
+
}
|
|
1696
1758
|
async send({ address, amount, message = '', satsPerByte = this.feeEstimates.normal, rbf, broadcast = true, shuffleOutputs = true }) {
|
|
1697
1759
|
return await this.sendMany({
|
|
1698
1760
|
txs: [{ address, amount, message }],
|
|
@@ -1716,7 +1778,7 @@ class Wallet {
|
|
|
1716
1778
|
const currentWallet = this.data;
|
|
1717
1779
|
let saveAddressIndexes = false;
|
|
1718
1780
|
let saveChangeAddressIndexes = false;
|
|
1719
|
-
|
|
1781
|
+
await Promise.all(types.map(async (addressType) => {
|
|
1720
1782
|
const addressIndex = currentWallet.addressIndex[addressType];
|
|
1721
1783
|
const changeAddressIndex = currentWallet.changeAddressIndex[addressType];
|
|
1722
1784
|
if ((addressIndex === null || addressIndex === void 0 ? void 0 : addressIndex.index) < 0) {
|
|
@@ -1727,12 +1789,18 @@ class Wallet {
|
|
|
1727
1789
|
await this.updateAddressIndex(addressType, true);
|
|
1728
1790
|
saveChangeAddressIndexes = true;
|
|
1729
1791
|
}
|
|
1730
|
-
}
|
|
1792
|
+
}));
|
|
1731
1793
|
if (saveAddressIndexes) {
|
|
1732
|
-
await
|
|
1794
|
+
await Promise.all([
|
|
1795
|
+
this.saveWalletData('addressIndex', this._data.addressIndex),
|
|
1796
|
+
this.saveWalletData('addresses', this._data.addresses)
|
|
1797
|
+
]);
|
|
1733
1798
|
}
|
|
1734
1799
|
if (saveChangeAddressIndexes) {
|
|
1735
|
-
await
|
|
1800
|
+
await Promise.all([
|
|
1801
|
+
this.saveWalletData('changeAddressIndex', this._data.changeAddressIndex),
|
|
1802
|
+
this.saveWalletData('changeAddresses', this._data.changeAddresses)
|
|
1803
|
+
]);
|
|
1736
1804
|
}
|
|
1737
1805
|
return (0, utils_1.ok)('Set Zero Index Addresses.');
|
|
1738
1806
|
}
|
|
@@ -1765,7 +1833,8 @@ class Wallet {
|
|
|
1765
1833
|
addressIndex: index,
|
|
1766
1834
|
changeAddressAmount: indexToUpdate === 'changeAddressIndex' ? constants_1.GENERATE_ADDRESS_AMOUNT : 0,
|
|
1767
1835
|
changeAddressIndex: index,
|
|
1768
|
-
addressType
|
|
1836
|
+
addressType,
|
|
1837
|
+
saveAddresses: false
|
|
1769
1838
|
});
|
|
1770
1839
|
}
|
|
1771
1840
|
}
|