@ledgerhq/coin-kaspa 1.4.1-nightly.20251120023735 → 1.4.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/.turbo/turbo-build.log +1 -1
- package/.unimportedrc.json +1 -2
- package/CHANGELOG.md +17 -8
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +1 -11
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/logic/scanAddresses.d.ts.map +1 -1
- package/lib/logic/scanAddresses.js +10 -2
- package/lib/logic/scanAddresses.js.map +1 -1
- package/lib/logic/utxos/lib.d.ts +0 -1
- package/lib/logic/utxos/lib.d.ts.map +1 -1
- package/lib/logic/utxos/lib.js +6 -16
- package/lib/logic/utxos/lib.js.map +1 -1
- package/lib/logic/utxos/selection.d.ts.map +1 -1
- package/lib/logic/utxos/selection.js +26 -11
- package/lib/logic/utxos/selection.js.map +1 -1
- package/lib/types/errors.d.ts +0 -6
- package/lib/types/errors.d.ts.map +1 -1
- package/lib/types/errors.js +1 -3
- package/lib/types/errors.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +1 -11
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/logic/scanAddresses.d.ts.map +1 -1
- package/lib-es/logic/scanAddresses.js +10 -2
- package/lib-es/logic/scanAddresses.js.map +1 -1
- package/lib-es/logic/utxos/lib.d.ts +0 -1
- package/lib-es/logic/utxos/lib.d.ts.map +1 -1
- package/lib-es/logic/utxos/lib.js +5 -14
- package/lib-es/logic/utxos/lib.js.map +1 -1
- package/lib-es/logic/utxos/selection.d.ts.map +1 -1
- package/lib-es/logic/utxos/selection.js +23 -8
- package/lib-es/logic/utxos/selection.js.map +1 -1
- package/lib-es/types/errors.d.ts +0 -6
- package/lib-es/types/errors.d.ts.map +1 -1
- package/lib-es/types/errors.js +0 -2
- package/lib-es/types/errors.js.map +1 -1
- package/package.json +8 -7
- package/src/bridge/getTransactionStatus.ts +1 -10
- package/src/logic/scanAddresses.ts +12 -2
- package/src/logic/tests/utxoSelection.test.ts +3 -30
- package/src/logic/utxos/lib.ts +12 -17
- package/src/logic/utxos/selection.ts +27 -14
- package/src/types/errors.ts +2 -2
- package/lib/logic/constants.d.ts +0 -7
- package/lib/logic/constants.d.ts.map +0 -1
- package/lib/logic/constants.js +0 -10
- package/lib/logic/constants.js.map +0 -1
- package/lib-es/logic/constants.d.ts +0 -7
- package/lib-es/logic/constants.d.ts.map +0 -1
- package/lib-es/logic/constants.js +0 -7
- package/lib-es/logic/constants.js.map +0 -1
- package/src/logic/constants.ts +0 -8
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
> @ledgerhq/coin-kaspa@1.4.
|
|
2
|
+
> @ledgerhq/coin-kaspa@1.4.1 build /home/runner/work/ledger-live/ledger-live/libs/coin-modules/coin-kaspa
|
|
3
3
|
> tsc && tsc -m esnext --moduleResolution bundler --outDir lib-es
|
|
4
4
|
|
package/.unimportedrc.json
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
# @ledgerhq/coin-framework
|
|
2
2
|
|
|
3
|
-
## 1.4.1
|
|
3
|
+
## 1.4.1
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
- [
|
|
7
|
+
- Updated dependencies [[`74a340b`](https://github.com/LedgerHQ/ledger-live/commit/74a340b258589c9c37476103029eb036b930616c), [`a6bc24e`](https://github.com/LedgerHQ/ledger-live/commit/a6bc24ee988b98bf82f807ac5ce731ba79813901), [`b69c97d`](https://github.com/LedgerHQ/ledger-live/commit/b69c97d979ba97154c9abfda6abfc2a36becee4f), [`544721d`](https://github.com/LedgerHQ/ledger-live/commit/544721d198454526ef83516619d59c881ba34eb9), [`1c6f5f5`](https://github.com/LedgerHQ/ledger-live/commit/1c6f5f5843349b1955f7ca466f98cbe4ffcdaddf), [`d5d838a`](https://github.com/LedgerHQ/ledger-live/commit/d5d838a23e00edd53293843781c559c41db4e854), [`9f61dcf`](https://github.com/LedgerHQ/ledger-live/commit/9f61dcf6163fd66657e5be732c28bea623a40515), [`938b970`](https://github.com/LedgerHQ/ledger-live/commit/938b970e15118dc706c759a3bec27dc01c3dd268), [`c40e9da`](https://github.com/LedgerHQ/ledger-live/commit/c40e9da68452fe9827b9435ff2d162291186be73), [`c0b5b9f`](https://github.com/LedgerHQ/ledger-live/commit/c0b5b9f4cdcb2ea3e15419cbf3d1a14f725c3e6a), [`70049be`](https://github.com/LedgerHQ/ledger-live/commit/70049bed0cd0a8c7a9e4947a63af82061dad46c0), [`5b41dd5`](https://github.com/LedgerHQ/ledger-live/commit/5b41dd56e024a5d03ba0e49084113c04887395db), [`eb5a17e`](https://github.com/LedgerHQ/ledger-live/commit/eb5a17e4db336eaa871eaeb52ffa5248e0f78bec), [`c70f6a8`](https://github.com/LedgerHQ/ledger-live/commit/c70f6a8370056b6fd8f236205471359d6f9b846f)]:
|
|
8
|
+
- @ledgerhq/types-live@6.89.0
|
|
9
|
+
- @ledgerhq/cryptoassets@13.33.0
|
|
10
|
+
- @ledgerhq/coin-framework@6.9.0
|
|
11
|
+
- @ledgerhq/live-env@2.21.0
|
|
12
|
+
- @ledgerhq/live-network@2.1.1
|
|
8
13
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- @ledgerhq/live
|
|
14
|
+
## 1.4.1-next.0
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [[`74a340b`](https://github.com/LedgerHQ/ledger-live/commit/74a340b258589c9c37476103029eb036b930616c), [`a6bc24e`](https://github.com/LedgerHQ/ledger-live/commit/a6bc24ee988b98bf82f807ac5ce731ba79813901), [`b69c97d`](https://github.com/LedgerHQ/ledger-live/commit/b69c97d979ba97154c9abfda6abfc2a36becee4f), [`544721d`](https://github.com/LedgerHQ/ledger-live/commit/544721d198454526ef83516619d59c881ba34eb9), [`1c6f5f5`](https://github.com/LedgerHQ/ledger-live/commit/1c6f5f5843349b1955f7ca466f98cbe4ffcdaddf), [`d5d838a`](https://github.com/LedgerHQ/ledger-live/commit/d5d838a23e00edd53293843781c559c41db4e854), [`9f61dcf`](https://github.com/LedgerHQ/ledger-live/commit/9f61dcf6163fd66657e5be732c28bea623a40515), [`938b970`](https://github.com/LedgerHQ/ledger-live/commit/938b970e15118dc706c759a3bec27dc01c3dd268), [`c40e9da`](https://github.com/LedgerHQ/ledger-live/commit/c40e9da68452fe9827b9435ff2d162291186be73), [`c0b5b9f`](https://github.com/LedgerHQ/ledger-live/commit/c0b5b9f4cdcb2ea3e15419cbf3d1a14f725c3e6a), [`70049be`](https://github.com/LedgerHQ/ledger-live/commit/70049bed0cd0a8c7a9e4947a63af82061dad46c0), [`5b41dd5`](https://github.com/LedgerHQ/ledger-live/commit/5b41dd56e024a5d03ba0e49084113c04887395db), [`eb5a17e`](https://github.com/LedgerHQ/ledger-live/commit/eb5a17e4db336eaa871eaeb52ffa5248e0f78bec), [`c70f6a8`](https://github.com/LedgerHQ/ledger-live/commit/c70f6a8370056b6fd8f236205471359d6f9b846f)]:
|
|
19
|
+
- @ledgerhq/types-live@6.89.0-next.0
|
|
20
|
+
- @ledgerhq/cryptoassets@13.33.0-next.0
|
|
21
|
+
- @ledgerhq/coin-framework@6.9.0-next.0
|
|
22
|
+
- @ledgerhq/live-env@2.21.0-next.0
|
|
23
|
+
- @ledgerhq/live-network@2.1.1-next.0
|
|
15
24
|
|
|
16
25
|
## 1.4.0
|
|
17
26
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTransactionStatus.d.ts","sourceRoot":"","sources":["../../src/bridge/getTransactionStatus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getTransactionStatus.d.ts","sourceRoot":"","sources":["../../src/bridge/getTransactionStatus.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAgBxE,QAAA,MAAM,oBAAoB,YACf,YAAY,eACR,WAAW,KACvB,QAAQ,iBAAiB,CA2E3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const errors_1 = require("@ledgerhq/errors");
|
|
4
|
-
const errors_2 = require("../types/errors");
|
|
5
4
|
const bignumber_js_1 = require("bignumber.js");
|
|
6
5
|
const logic_1 = require("../logic");
|
|
7
6
|
const cache_1 = require("@ledgerhq/live-network/cache");
|
|
8
|
-
const constants_1 = require("../logic/constants");
|
|
9
7
|
const getCachedUtxos = (0, cache_1.makeLRUCache)(async (account) => {
|
|
10
8
|
const { compressedPublicKey, chainCode } = (0, logic_1.parseExtendedPublicKey)(Buffer.from(account.xpub, "hex"));
|
|
11
9
|
return await (0, logic_1.scanUtxos)(compressedPublicKey, chainCode);
|
|
@@ -46,17 +44,9 @@ const getTransactionStatus = async (account, transaction) => {
|
|
|
46
44
|
if (transaction.amount.lt(20000000)) {
|
|
47
45
|
errors.dustLimit = new errors_1.DustLimit("");
|
|
48
46
|
}
|
|
49
|
-
if (utxos.length > constants_1.MAX_UTXOS_PER_TX) {
|
|
50
|
-
warnings.amount = new errors_2.ReducedAmountUtxoWarning();
|
|
51
|
-
}
|
|
52
47
|
}
|
|
53
48
|
if (transaction.amount.gt(maxSpendableAmount) || maxSpendableAmount.eq(0)) {
|
|
54
|
-
|
|
55
|
-
errors.amount = new errors_2.UtxoLimitReachedError();
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
errors.amount = new errors_1.NotEnoughBalance();
|
|
59
|
-
}
|
|
49
|
+
errors.amount = new errors_1.NotEnoughBalance();
|
|
60
50
|
}
|
|
61
51
|
if (Object.keys(errors).length === 0) {
|
|
62
52
|
const result = (0, logic_1.selectUtxos)(utxos, transaction.recipient.length > 67, transaction.amount, (0, logic_1.getFeeRate)(transaction).toNumber() || 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTransactionStatus.js","sourceRoot":"","sources":["../../src/bridge/getTransactionStatus.ts"],"names":[],"mappings":";;AAAA,6CAS0B;AAC1B
|
|
1
|
+
{"version":3,"file":"getTransactionStatus.js","sourceRoot":"","sources":["../../src/bridge/getTransactionStatus.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanAddresses.d.ts","sourceRoot":"","sources":["../../src/logic/scanAddresses.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,gBAAgB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"scanAddresses.d.ts","sourceRoot":"","sources":["../../src/logic/scanAddresses.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAa5D;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,mBAAmB,EAAE,MAAM,EAC3B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,CA2E3B"}
|
|
@@ -13,6 +13,7 @@ const CHANGE_ADDRESS_TYPE = 1;
|
|
|
13
13
|
const INITIAL_BALANCE = (0, bignumber_js_1.BigNumber)(0);
|
|
14
14
|
const GAP_LIMIT = 20;
|
|
15
15
|
const SCAN_BATCH_SIZE = 200;
|
|
16
|
+
const MAX_TX_INPUTS = 88; // floor (( 100_000 - 918 (def_size with 2 outputs) ) / 1_118 (per_input))
|
|
16
17
|
/**
|
|
17
18
|
* Scans the addresses for an account and retrieves information such as used addresses and the total balance.
|
|
18
19
|
*
|
|
@@ -75,8 +76,15 @@ async function scanAddresses(compressedPublicKey, chainCode, startIndex) {
|
|
|
75
76
|
updateAddressesData(addresses, accountAddresses, type, keepScanning);
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
const spendableBalance = [
|
|
80
|
+
...accountAddresses.usedChangeAddresses,
|
|
81
|
+
...accountAddresses.usedReceiveAddresses,
|
|
82
|
+
]
|
|
83
|
+
.sort((a, b) => b.balance.minus(a.balance).toNumber())
|
|
84
|
+
.slice(0, MAX_TX_INPUTS)
|
|
85
|
+
.map(utxo => utxo.balance)
|
|
86
|
+
.reduce((acc, v) => acc.plus(v), (0, bignumber_js_1.BigNumber)(0));
|
|
87
|
+
accountAddresses.spendableBalance = spendableBalance;
|
|
80
88
|
return accountAddresses;
|
|
81
89
|
}
|
|
82
90
|
exports.scanAddresses = scanAddresses;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanAddresses.js","sourceRoot":"","sources":["../../src/logic/scanAddresses.ts"],"names":[],"mappings":";;;;;;AAAA,+CAAyC;AAEzC,oDAAiC;AACjC,wCAAyE;AAEzE,+BAA+B;AAC/B,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,eAAe,GAAG,IAAA,wBAAS,EAAC,CAAC,CAAC,CAAC;AACrC,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B;;;;;;;GAOG;AACI,KAAK,UAAU,aAAa,CACjC,mBAA2B,EAC3B,SAAiB,EACjB,UAAkB;IAElB,MAAM,UAAU,GAAe,IAAI,eAAU,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;IAE9E,MAAM,gBAAgB,GAAqB;QACzC,oBAAoB,EAAE,EAAE;QACxB,mBAAmB,EAAE,EAAE;QACvB,iBAAiB,EAAE;YACjB,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,IAAI;SAChB;QACD,kBAAkB,EAAE;YAClB,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,IAAI;SAChB;QACD,YAAY,EAAE,IAAA,wBAAS,EAAC,CAAC,CAAC;QAC1B,gBAAgB,EAAE,IAAA,wBAAS,EAAC,CAAC,CAAC;KAC/B,CAAC;IAEF,qEAAqE;IAErE,gDAAgD;IAChD,KAAK,MAAM,IAAI,IAAI,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,EAAE,CAAC;QAC/D,IAAI,YAAY,GAAY,IAAI,CAAC;QAEjC,OAAO,YAAY,EAAE,CAAC;YACpB,MAAM,SAAS,GAAqB,EAAE,CAAC;YACvC,KAAK,IAAI,KAAK,GAAG,UAAU,EAAE,KAAK,GAAG,UAAU,GAAG,eAAe,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC3E,MAAM,cAAc,GAAW,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAClE,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,IAAI;oBACV,KAAK;oBACL,OAAO,EAAE,cAAc;oBACvB,OAAO,EAAE,IAAA,wBAAS,EAAC,CAAC,CAAC;oBACrB,MAAM,EAAE,KAAK;iBACI,CAAC,CAAC;YACvB,CAAC;YAED,sDAAsD;YACtD,MAAM,qBAAqB,CAAC,SAAS,CAAC,CAAC;YAEvC,iBAAiB;YACjB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,gBAAgB,CAAC,YAAY,GAAG,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnF,CAAC;YAED,uEAAuE;YACvE,MAAM,oBAAoB,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;YAEzD,YAAY,GAAG,CAAC,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjE,IAAI,YAAY;gBAAE,UAAU,IAAI,eAAe,CAAC;YAEhD,mBAAmB,CAAC,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"scanAddresses.js","sourceRoot":"","sources":["../../src/logic/scanAddresses.ts"],"names":[],"mappings":"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"}
|
package/lib/logic/utxos/lib.d.ts
CHANGED
|
@@ -3,5 +3,4 @@ import { KaspaUtxo } from "../../types";
|
|
|
3
3
|
export declare const calcMaxSpendableAmount: (utxos: KaspaUtxo[], isEcdsaRecipient: boolean, feerate?: number) => BigNumber;
|
|
4
4
|
export declare const sumBigNumber: (values: BigNumber[]) => BigNumber;
|
|
5
5
|
export declare const sumUtxoAmounts: (utxos: KaspaUtxo[]) => BigNumber;
|
|
6
|
-
export declare const sortUtxos: (utxos: KaspaUtxo[]) => void;
|
|
7
6
|
//# sourceMappingURL=lib.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../../src/logic/utxos/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../../src/logic/utxos/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAOxC,eAAO,MAAM,sBAAsB,UAC1B,SAAS,EAAE,oBACA,OAAO,YAChB,MAAM,KACd,SAmBF,CAAC;AAEF,eAAO,MAAM,YAAY,WAAY,SAAS,EAAE,KAAG,SAElD,CAAC;AAEF,eAAO,MAAM,cAAc,UAAW,SAAS,EAAE,KAAG,SAEnD,CAAC"}
|
package/lib/logic/utxos/lib.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.sumUtxoAmounts = exports.sumBigNumber = exports.calcMaxSpendableAmount = void 0;
|
|
4
4
|
const bignumber_js_1 = require("bignumber.js");
|
|
5
|
-
const
|
|
5
|
+
const ADDITIONAL_MASS_PER_INPUT = 1118;
|
|
6
|
+
const DEFAULT_MASS_1_OUTPUT = 506;
|
|
7
|
+
const MAX_UTXOS_PER_TX = 88;
|
|
6
8
|
const calcMaxSpendableAmount = (utxos, isEcdsaRecipient, feerate = 1) => {
|
|
7
|
-
(
|
|
8
|
-
const utxoSubset = utxos.slice(0, constants_1.MAX_UTXOS_PER_TX);
|
|
9
|
-
const maxInputAmount = (0, exports.sumUtxoAmounts)(utxoSubset);
|
|
9
|
+
const maxInputAmount = utxos.reduce((sum, utxo) => sum.plus(new bignumber_js_1.BigNumber(utxo.utxoEntry.amount)), new bignumber_js_1.BigNumber(0));
|
|
10
10
|
// storage mass can be neglected here
|
|
11
11
|
// max compute mass for one output and 88 inputs is 98901
|
|
12
|
-
let maxSpendableAmount = maxInputAmount.minus((0, bignumber_js_1.BigNumber)(
|
|
12
|
+
let maxSpendableAmount = maxInputAmount.minus((0, bignumber_js_1.BigNumber)(DEFAULT_MASS_1_OUTPUT + Math.min(MAX_UTXOS_PER_TX, utxos.length) * ADDITIONAL_MASS_PER_INPUT).times(feerate));
|
|
13
13
|
if (isEcdsaRecipient) {
|
|
14
14
|
maxSpendableAmount = maxSpendableAmount.minus((0, bignumber_js_1.BigNumber)(11));
|
|
15
15
|
}
|
|
@@ -24,14 +24,4 @@ const sumUtxoAmounts = (utxos) => {
|
|
|
24
24
|
return utxos.reduce((acc, v) => acc.plus(v.utxoEntry.amount), (0, bignumber_js_1.BigNumber)(0));
|
|
25
25
|
};
|
|
26
26
|
exports.sumUtxoAmounts = sumUtxoAmounts;
|
|
27
|
-
const sortUtxos = (utxos) => {
|
|
28
|
-
utxos.sort((a, b) => {
|
|
29
|
-
const transactionComparison = a.utxoEntry.blockDaaScore.localeCompare(b.utxoEntry.blockDaaScore);
|
|
30
|
-
if (transactionComparison !== 0) {
|
|
31
|
-
return transactionComparison;
|
|
32
|
-
}
|
|
33
|
-
return a.utxoEntry.amount.minus(b.utxoEntry.amount).toNumber();
|
|
34
|
-
});
|
|
35
|
-
};
|
|
36
|
-
exports.sortUtxos = sortUtxos;
|
|
37
27
|
//# sourceMappingURL=lib.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../../../src/logic/utxos/lib.ts"],"names":[],"mappings":";;;AAAA,+CAAyC;
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../../../src/logic/utxos/lib.ts"],"names":[],"mappings":";;;AAAA,+CAAyC;AAGzC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAEvC,MAAM,qBAAqB,GAAW,GAAG,CAAC;AAC1C,MAAM,gBAAgB,GAAW,EAAE,CAAC;AAE7B,MAAM,sBAAsB,GAAG,CACpC,KAAkB,EAClB,gBAAyB,EACzB,UAAkB,CAAC,EACR,EAAE;IACb,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CACjC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,wBAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAC7D,IAAI,wBAAS,CAAC,CAAC,CAAC,CACjB,CAAC;IAEF,qCAAqC;IACrC,yDAAyD;IACzD,IAAI,kBAAkB,GAAG,cAAc,CAAC,KAAK,CAC3C,IAAA,wBAAS,EACP,qBAAqB,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,yBAAyB,CAC7F,CAAC,KAAK,CAAC,OAAO,CAAC,CACjB,CAAC;IAEF,IAAI,gBAAgB,EAAE,CAAC;QACrB,kBAAkB,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAA,wBAAS,EAAC,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAA,wBAAS,EAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;AACtE,CAAC,CAAC;AAvBW,QAAA,sBAAsB,0BAuBjC;AAEK,MAAM,YAAY,GAAG,CAAC,MAAmB,EAAa,EAAE;IAC7D,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAA,wBAAS,EAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,CAAC;AAFW,QAAA,YAAY,gBAEvB;AAEK,MAAM,cAAc,GAAG,CAAC,KAAkB,EAAa,EAAE;IAC9D,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,IAAA,wBAAS,EAAC,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC,CAAC;AAFW,QAAA,cAAc,kBAEzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/logic/utxos/selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/logic/utxos/selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAUxC,eAAO,MAAM,WAAW,UACf,SAAS,EAAE,oBACA,OAAO,UACjB,SAAS,YACR,MAAM;kBACE,SAAS;SAAO,SAAS;WAAS,SAAS,EAAE;CAuE/D,CAAC"}
|
|
@@ -4,19 +4,25 @@ exports.selectUtxos = void 0;
|
|
|
4
4
|
const bignumber_js_1 = require("bignumber.js");
|
|
5
5
|
const massCalcluation_1 = require("../massCalcluation");
|
|
6
6
|
const lib_1 = require("./lib");
|
|
7
|
-
const
|
|
7
|
+
const MASS_LIMIT_PER_TX = 100_000; // TX mass must not exceed 100k gram.
|
|
8
|
+
const MASS_PER_INPUT = 1118; // Per selected utxo as input, mass increases by this value.
|
|
9
|
+
const MASS_PER_OUTPUT = 412; // Per selected utxo as input, mass increases by this value.
|
|
10
|
+
const MAX_UTXOS_PER_TX = 88; // 88 is the maximum of utxo inputs in one TX.
|
|
11
|
+
const MAX_DISCARD = 2000_0000; // Throw error, if discarded value is higher than this.
|
|
8
12
|
const selectUtxos = (utxos, isEcdsaRecipient, amount, feerate = 1) => {
|
|
9
13
|
// always sort utxos
|
|
10
|
-
|
|
11
|
-
//
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
sortUtxos(utxos);
|
|
15
|
+
// Max UTXO count is 88. More don't fit into a regular TX
|
|
16
|
+
if (utxos.length > MAX_UTXOS_PER_TX) {
|
|
17
|
+
throw new Error(`UTXO count exceeds the limit of ${MAX_UTXOS_PER_TX} for a TX.`);
|
|
18
|
+
}
|
|
19
|
+
// First check in general, if there is enough amount in the UTXOs.
|
|
20
|
+
if ((0, lib_1.calcMaxSpendableAmount)(utxos, isEcdsaRecipient, feerate).isLessThan(amount)) {
|
|
15
21
|
throw new Error(`UTXO total amount is not sufficient for sending amount ${amount}`);
|
|
16
22
|
}
|
|
17
23
|
// Find a sufficient slice.
|
|
18
|
-
for (let i = 0; i <
|
|
19
|
-
const selectedUtxos =
|
|
24
|
+
for (let i = 0; i < utxos.length; i++) {
|
|
25
|
+
const selectedUtxos = utxos.slice(0, i + 1);
|
|
20
26
|
const selectedUtxoAmount = (0, lib_1.sumUtxoAmounts)(selectedUtxos);
|
|
21
27
|
// calculate absolute min fee for regular TX with 1 outputs and the given feerate.
|
|
22
28
|
const minMass = (0, massCalcluation_1.calcComputeMass)(i + 1, false, isEcdsaRecipient);
|
|
@@ -36,17 +42,17 @@ const selectUtxos = (utxos, isEcdsaRecipient, amount, feerate = 1) => {
|
|
|
36
42
|
: 0;
|
|
37
43
|
// If storage mass exceeds the limit or the change amount is negative ( 2 outputs not possible )
|
|
38
44
|
// Need to pick another UTXO or discard the change.
|
|
39
|
-
if (changeAmount.isLessThan(0) || storageMass >
|
|
45
|
+
if (changeAmount.isLessThan(0) || storageMass > MASS_LIMIT_PER_TX) {
|
|
40
46
|
// Picking a further UTXO means a higher mass (one input and output) and thus a higher fee.
|
|
41
47
|
// Check if the fee is not higher, than just discarding the change.
|
|
42
|
-
const isWorthPickingAnotherUtxo = changeAmount.isGreaterThan((0, bignumber_js_1.BigNumber)((
|
|
48
|
+
const isWorthPickingAnotherUtxo = changeAmount.isGreaterThan((0, bignumber_js_1.BigNumber)((MASS_PER_INPUT + MASS_PER_OUTPUT) * feerate));
|
|
43
49
|
if (i + 1 < utxos.length && isWorthPickingAnotherUtxo) {
|
|
44
50
|
// There is one more UTXO and it is cheaper to pick than discard the change.
|
|
45
51
|
continue;
|
|
46
52
|
}
|
|
47
53
|
else {
|
|
48
54
|
// Change needs to be discarded as fee to keep mass low enough.
|
|
49
|
-
if (changeAmount.isGreaterThan(
|
|
55
|
+
if (changeAmount.isGreaterThan(MAX_DISCARD)) {
|
|
50
56
|
throw new Error(`Unable to select UTXOs. Change ${changeAmount} Sompis is too high to be discarded.`);
|
|
51
57
|
}
|
|
52
58
|
changeAmount = (0, bignumber_js_1.BigNumber)(0);
|
|
@@ -62,4 +68,13 @@ const selectUtxos = (utxos, isEcdsaRecipient, amount, feerate = 1) => {
|
|
|
62
68
|
throw new Error("UTXOs can't be determined to fulfill the specified amount");
|
|
63
69
|
};
|
|
64
70
|
exports.selectUtxos = selectUtxos;
|
|
71
|
+
const sortUtxos = (utxos) => {
|
|
72
|
+
utxos.sort((a, b) => {
|
|
73
|
+
const transactionComparison = a.utxoEntry.blockDaaScore.localeCompare(b.utxoEntry.blockDaaScore);
|
|
74
|
+
if (transactionComparison !== 0) {
|
|
75
|
+
return transactionComparison;
|
|
76
|
+
}
|
|
77
|
+
return a.utxoEntry.amount.minus(b.utxoEntry.amount).toNumber();
|
|
78
|
+
});
|
|
79
|
+
};
|
|
65
80
|
//# sourceMappingURL=selection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/logic/utxos/selection.ts"],"names":[],"mappings":";;;AAAA,+CAAyC;AAEzC,wDAAsE;AACtE,+
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/logic/utxos/selection.ts"],"names":[],"mappings":"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"}
|
package/lib/types/errors.d.ts
CHANGED
|
@@ -7,10 +7,4 @@ export declare const TransactionMassExceededError: import("@ledgerhq/errors/lib/
|
|
|
7
7
|
export declare const EmptyRecipientError: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{
|
|
8
8
|
[key: string]: unknown;
|
|
9
9
|
}>;
|
|
10
|
-
export declare const ReducedAmountUtxoWarning: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{
|
|
11
|
-
[key: string]: unknown;
|
|
12
|
-
}>;
|
|
13
|
-
export declare const UtxoLimitReachedError: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{
|
|
14
|
-
[key: string]: unknown;
|
|
15
|
-
}>;
|
|
16
10
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB;;EAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB;;EAA8C,CAAC;AAE7E,eAAO,MAAM,4BAA4B;;EAAyD,CAAC;AAEnG,eAAO,MAAM,mBAAmB;;EAAgD,CAAC"}
|
package/lib/types/errors.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.EmptyRecipientError = exports.TransactionMassExceededError = exports.NotEnoughFeeError = void 0;
|
|
4
4
|
const errors_1 = require("@ledgerhq/errors");
|
|
5
5
|
exports.NotEnoughFeeError = (0, errors_1.createCustomErrorClass)("NotEnoughFeeError");
|
|
6
6
|
exports.TransactionMassExceededError = (0, errors_1.createCustomErrorClass)("TransactionMassExceededError");
|
|
7
7
|
exports.EmptyRecipientError = (0, errors_1.createCustomErrorClass)("EmptyRecipientError");
|
|
8
|
-
exports.ReducedAmountUtxoWarning = (0, errors_1.createCustomErrorClass)("ReducedAmountUtxoWarning");
|
|
9
|
-
exports.UtxoLimitReachedError = (0, errors_1.createCustomErrorClass)("UtxoLimitReachedError");
|
|
10
8
|
//# sourceMappingURL=errors.js.map
|
package/lib/types/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":";;;AAAA,6CAA0D;AAE7C,QAAA,iBAAiB,GAAG,IAAA,+BAAsB,EAAC,mBAAmB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":";;;AAAA,6CAA0D;AAE7C,QAAA,iBAAiB,GAAG,IAAA,+BAAsB,EAAC,mBAAmB,CAAC,CAAC;AAEhE,QAAA,4BAA4B,GAAG,IAAA,+BAAsB,EAAC,8BAA8B,CAAC,CAAC;AAEtF,QAAA,mBAAmB,GAAG,IAAA,+BAAsB,EAAC,qBAAqB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTransactionStatus.d.ts","sourceRoot":"","sources":["../../src/bridge/getTransactionStatus.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getTransactionStatus.d.ts","sourceRoot":"","sources":["../../src/bridge/getTransactionStatus.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAgBxE,QAAA,MAAM,oBAAoB,YACf,YAAY,eACR,WAAW,KACvB,QAAQ,iBAAiB,CA2E3B,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { AmountRequired, DustLimit, FeeNotLoaded, FeeRequired, FeeTooHigh, InvalidAddress, NotEnoughBalance, RecipientRequired, } from "@ledgerhq/errors";
|
|
2
|
-
import { ReducedAmountUtxoWarning, UtxoLimitReachedError } from "../types/errors";
|
|
3
2
|
import { BigNumber } from "bignumber.js";
|
|
4
3
|
import { calcMaxSpendableAmount, getFeeRate, isValidKaspaAddress, parseExtendedPublicKey, scanUtxos, selectUtxos, } from "../logic";
|
|
5
4
|
import { makeLRUCache, minutes } from "@ledgerhq/live-network/cache";
|
|
6
|
-
import { MAX_UTXOS_PER_TX } from "../logic/constants";
|
|
7
5
|
const getCachedUtxos = makeLRUCache(async (account) => {
|
|
8
6
|
const { compressedPublicKey, chainCode } = parseExtendedPublicKey(Buffer.from(account.xpub, "hex"));
|
|
9
7
|
return await scanUtxos(compressedPublicKey, chainCode);
|
|
@@ -44,17 +42,9 @@ const getTransactionStatus = async (account, transaction) => {
|
|
|
44
42
|
if (transaction.amount.lt(20000000)) {
|
|
45
43
|
errors.dustLimit = new DustLimit("");
|
|
46
44
|
}
|
|
47
|
-
if (utxos.length > MAX_UTXOS_PER_TX) {
|
|
48
|
-
warnings.amount = new ReducedAmountUtxoWarning();
|
|
49
|
-
}
|
|
50
45
|
}
|
|
51
46
|
if (transaction.amount.gt(maxSpendableAmount) || maxSpendableAmount.eq(0)) {
|
|
52
|
-
|
|
53
|
-
errors.amount = new UtxoLimitReachedError();
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
errors.amount = new NotEnoughBalance();
|
|
57
|
-
}
|
|
47
|
+
errors.amount = new NotEnoughBalance();
|
|
58
48
|
}
|
|
59
49
|
if (Object.keys(errors).length === 0) {
|
|
60
50
|
const result = selectUtxos(utxos, transaction.recipient.length > 67, transaction.amount, getFeeRate(transaction).toNumber() || 1);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTransactionStatus.js","sourceRoot":"","sources":["../../src/bridge/getTransactionStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"getTransactionStatus.js","sourceRoot":"","sources":["../../src/bridge/getTransactionStatus.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanAddresses.d.ts","sourceRoot":"","sources":["../../src/logic/scanAddresses.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,gBAAgB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"scanAddresses.d.ts","sourceRoot":"","sources":["../../src/logic/scanAddresses.ts"],"names":[],"mappings":"AACA,OAAO,EAAkB,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAa5D;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,mBAAmB,EAAE,MAAM,EAC3B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,gBAAgB,CAAC,CA2E3B"}
|
|
@@ -7,6 +7,7 @@ const CHANGE_ADDRESS_TYPE = 1;
|
|
|
7
7
|
const INITIAL_BALANCE = BigNumber(0);
|
|
8
8
|
const GAP_LIMIT = 20;
|
|
9
9
|
const SCAN_BATCH_SIZE = 200;
|
|
10
|
+
const MAX_TX_INPUTS = 88; // floor (( 100_000 - 918 (def_size with 2 outputs) ) / 1_118 (per_input))
|
|
10
11
|
/**
|
|
11
12
|
* Scans the addresses for an account and retrieves information such as used addresses and the total balance.
|
|
12
13
|
*
|
|
@@ -69,8 +70,15 @@ export async function scanAddresses(compressedPublicKey, chainCode, startIndex)
|
|
|
69
70
|
updateAddressesData(addresses, accountAddresses, type, keepScanning);
|
|
70
71
|
}
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
const spendableBalance = [
|
|
74
|
+
...accountAddresses.usedChangeAddresses,
|
|
75
|
+
...accountAddresses.usedReceiveAddresses,
|
|
76
|
+
]
|
|
77
|
+
.sort((a, b) => b.balance.minus(a.balance).toNumber())
|
|
78
|
+
.slice(0, MAX_TX_INPUTS)
|
|
79
|
+
.map(utxo => utxo.balance)
|
|
80
|
+
.reduce((acc, v) => acc.plus(v), BigNumber(0));
|
|
81
|
+
accountAddresses.spendableBalance = spendableBalance;
|
|
74
82
|
return accountAddresses;
|
|
75
83
|
}
|
|
76
84
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanAddresses.js","sourceRoot":"","sources":["../../src/logic/scanAddresses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,UAAU,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAEzE,+BAA+B;AAC/B,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAC/B,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAC9B,MAAM,eAAe,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;AACrC,MAAM,SAAS,GAAG,EAAE,CAAC;AACrB,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,mBAA2B,EAC3B,SAAiB,EACjB,UAAkB;IAElB,MAAM,UAAU,GAAe,IAAI,UAAU,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;IAE9E,MAAM,gBAAgB,GAAqB;QACzC,oBAAoB,EAAE,EAAE;QACxB,mBAAmB,EAAE,EAAE;QACvB,iBAAiB,EAAE;YACjB,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,IAAI;SAChB;QACD,kBAAkB,EAAE;YAClB,IAAI,EAAE,CAAC;YACP,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,EAAE;YACX,OAAO,EAAE,eAAe;YACxB,MAAM,EAAE,KAAK;YACb,SAAS,EAAE,IAAI;SAChB;QACD,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;QAC1B,gBAAgB,EAAE,SAAS,CAAC,CAAC,CAAC;KAC/B,CAAC;IAEF,qEAAqE;IAErE,gDAAgD;IAChD,KAAK,MAAM,IAAI,IAAI,CAAC,oBAAoB,EAAE,mBAAmB,CAAC,EAAE,CAAC;QAC/D,IAAI,YAAY,GAAY,IAAI,CAAC;QAEjC,OAAO,YAAY,EAAE,CAAC;YACpB,MAAM,SAAS,GAAqB,EAAE,CAAC;YACvC,KAAK,IAAI,KAAK,GAAG,UAAU,EAAE,KAAK,GAAG,UAAU,GAAG,eAAe,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC3E,MAAM,cAAc,GAAW,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAClE,SAAS,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,IAAI;oBACV,KAAK;oBACL,OAAO,EAAE,cAAc;oBACvB,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;oBACrB,MAAM,EAAE,KAAK;iBACI,CAAC,CAAC;YACvB,CAAC;YAED,sDAAsD;YACtD,MAAM,qBAAqB,CAAC,SAAS,CAAC,CAAC;YAEvC,iBAAiB;YACjB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,gBAAgB,CAAC,YAAY,GAAG,gBAAgB,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACnF,CAAC;YAED,uEAAuE;YACvE,MAAM,oBAAoB,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC;YAEzD,YAAY,GAAG,CAAC,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACjE,IAAI,YAAY;gBAAE,UAAU,IAAI,eAAe,CAAC;YAEhD,mBAAmB,CAAC,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,
|
|
1
|
+
{"version":3,"file":"scanAddresses.js","sourceRoot":"","sources":["../../src/logic/scanAddresses.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,5 +3,4 @@ import { KaspaUtxo } from "../../types";
|
|
|
3
3
|
export declare const calcMaxSpendableAmount: (utxos: KaspaUtxo[], isEcdsaRecipient: boolean, feerate?: number) => BigNumber;
|
|
4
4
|
export declare const sumBigNumber: (values: BigNumber[]) => BigNumber;
|
|
5
5
|
export declare const sumUtxoAmounts: (utxos: KaspaUtxo[]) => BigNumber;
|
|
6
|
-
export declare const sortUtxos: (utxos: KaspaUtxo[]) => void;
|
|
7
6
|
//# sourceMappingURL=lib.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../../src/logic/utxos/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../../src/logic/utxos/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAOxC,eAAO,MAAM,sBAAsB,UAC1B,SAAS,EAAE,oBACA,OAAO,YAChB,MAAM,KACd,SAmBF,CAAC;AAEF,eAAO,MAAM,YAAY,WAAY,SAAS,EAAE,KAAG,SAElD,CAAC;AAEF,eAAO,MAAM,cAAc,UAAW,SAAS,EAAE,KAAG,SAEnD,CAAC"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { BigNumber } from "bignumber.js";
|
|
2
|
-
|
|
2
|
+
const ADDITIONAL_MASS_PER_INPUT = 1118;
|
|
3
|
+
const DEFAULT_MASS_1_OUTPUT = 506;
|
|
4
|
+
const MAX_UTXOS_PER_TX = 88;
|
|
3
5
|
export const calcMaxSpendableAmount = (utxos, isEcdsaRecipient, feerate = 1) => {
|
|
4
|
-
|
|
5
|
-
const utxoSubset = utxos.slice(0, MAX_UTXOS_PER_TX);
|
|
6
|
-
const maxInputAmount = sumUtxoAmounts(utxoSubset);
|
|
6
|
+
const maxInputAmount = utxos.reduce((sum, utxo) => sum.plus(new BigNumber(utxo.utxoEntry.amount)), new BigNumber(0));
|
|
7
7
|
// storage mass can be neglected here
|
|
8
8
|
// max compute mass for one output and 88 inputs is 98901
|
|
9
|
-
let maxSpendableAmount = maxInputAmount.minus(BigNumber(DEFAULT_MASS_1_OUTPUT +
|
|
9
|
+
let maxSpendableAmount = maxInputAmount.minus(BigNumber(DEFAULT_MASS_1_OUTPUT + Math.min(MAX_UTXOS_PER_TX, utxos.length) * ADDITIONAL_MASS_PER_INPUT).times(feerate));
|
|
10
10
|
if (isEcdsaRecipient) {
|
|
11
11
|
maxSpendableAmount = maxSpendableAmount.minus(BigNumber(11));
|
|
12
12
|
}
|
|
@@ -18,13 +18,4 @@ export const sumBigNumber = (values) => {
|
|
|
18
18
|
export const sumUtxoAmounts = (utxos) => {
|
|
19
19
|
return utxos.reduce((acc, v) => acc.plus(v.utxoEntry.amount), BigNumber(0));
|
|
20
20
|
};
|
|
21
|
-
export const sortUtxos = (utxos) => {
|
|
22
|
-
utxos.sort((a, b) => {
|
|
23
|
-
const transactionComparison = a.utxoEntry.blockDaaScore.localeCompare(b.utxoEntry.blockDaaScore);
|
|
24
|
-
if (transactionComparison !== 0) {
|
|
25
|
-
return transactionComparison;
|
|
26
|
-
}
|
|
27
|
-
return a.utxoEntry.amount.minus(b.utxoEntry.amount).toNumber();
|
|
28
|
-
});
|
|
29
|
-
};
|
|
30
21
|
//# sourceMappingURL=lib.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../../../src/logic/utxos/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../../../src/logic/utxos/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAEvC,MAAM,qBAAqB,GAAW,GAAG,CAAC;AAC1C,MAAM,gBAAgB,GAAW,EAAE,CAAC;AAEpC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CACpC,KAAkB,EAClB,gBAAyB,EACzB,UAAkB,CAAC,EACR,EAAE;IACb,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CACjC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAC7D,IAAI,SAAS,CAAC,CAAC,CAAC,CACjB,CAAC;IAEF,qCAAqC;IACrC,yDAAyD;IACzD,IAAI,kBAAkB,GAAG,cAAc,CAAC,KAAK,CAC3C,SAAS,CACP,qBAAqB,GAAG,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,yBAAyB,CAC7F,CAAC,KAAK,CAAC,OAAO,CAAC,CACjB,CAAC;IAEF,IAAI,gBAAgB,EAAE,CAAC;QACrB,kBAAkB,GAAG,kBAAkB,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,OAAO,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;AACtE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAmB,EAAa,EAAE;IAC7D,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAkB,EAAa,EAAE;IAC9D,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9E,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/logic/utxos/selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../../../src/logic/utxos/selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAUxC,eAAO,MAAM,WAAW,UACf,SAAS,EAAE,oBACA,OAAO,UACjB,SAAS,YACR,MAAM;kBACE,SAAS;SAAO,SAAS;WAAS,SAAS,EAAE;CAuE/D,CAAC"}
|
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
import { BigNumber } from "bignumber.js";
|
|
2
2
|
import { calcComputeMass, calcStorageMass } from "../massCalcluation";
|
|
3
|
-
import { calcMaxSpendableAmount,
|
|
4
|
-
|
|
3
|
+
import { calcMaxSpendableAmount, sumUtxoAmounts } from "./lib";
|
|
4
|
+
const MASS_LIMIT_PER_TX = 100_000; // TX mass must not exceed 100k gram.
|
|
5
|
+
const MASS_PER_INPUT = 1118; // Per selected utxo as input, mass increases by this value.
|
|
6
|
+
const MASS_PER_OUTPUT = 412; // Per selected utxo as input, mass increases by this value.
|
|
7
|
+
const MAX_UTXOS_PER_TX = 88; // 88 is the maximum of utxo inputs in one TX.
|
|
8
|
+
const MAX_DISCARD = 2000_0000; // Throw error, if discarded value is higher than this.
|
|
5
9
|
export const selectUtxos = (utxos, isEcdsaRecipient, amount, feerate = 1) => {
|
|
6
10
|
// always sort utxos
|
|
7
11
|
sortUtxos(utxos);
|
|
8
|
-
//
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
+
// Max UTXO count is 88. More don't fit into a regular TX
|
|
13
|
+
if (utxos.length > MAX_UTXOS_PER_TX) {
|
|
14
|
+
throw new Error(`UTXO count exceeds the limit of ${MAX_UTXOS_PER_TX} for a TX.`);
|
|
15
|
+
}
|
|
16
|
+
// First check in general, if there is enough amount in the UTXOs.
|
|
17
|
+
if (calcMaxSpendableAmount(utxos, isEcdsaRecipient, feerate).isLessThan(amount)) {
|
|
12
18
|
throw new Error(`UTXO total amount is not sufficient for sending amount ${amount}`);
|
|
13
19
|
}
|
|
14
20
|
// Find a sufficient slice.
|
|
15
|
-
for (let i = 0; i <
|
|
16
|
-
const selectedUtxos =
|
|
21
|
+
for (let i = 0; i < utxos.length; i++) {
|
|
22
|
+
const selectedUtxos = utxos.slice(0, i + 1);
|
|
17
23
|
const selectedUtxoAmount = sumUtxoAmounts(selectedUtxos);
|
|
18
24
|
// calculate absolute min fee for regular TX with 1 outputs and the given feerate.
|
|
19
25
|
const minMass = calcComputeMass(i + 1, false, isEcdsaRecipient);
|
|
@@ -58,4 +64,13 @@ export const selectUtxos = (utxos, isEcdsaRecipient, amount, feerate = 1) => {
|
|
|
58
64
|
// Throw an error, if UTXOs can't be determined to fulfill the requirement.
|
|
59
65
|
throw new Error("UTXOs can't be determined to fulfill the specified amount");
|
|
60
66
|
};
|
|
67
|
+
const sortUtxos = (utxos) => {
|
|
68
|
+
utxos.sort((a, b) => {
|
|
69
|
+
const transactionComparison = a.utxoEntry.blockDaaScore.localeCompare(b.utxoEntry.blockDaaScore);
|
|
70
|
+
if (transactionComparison !== 0) {
|
|
71
|
+
return transactionComparison;
|
|
72
|
+
}
|
|
73
|
+
return a.utxoEntry.amount.minus(b.utxoEntry.amount).toNumber();
|
|
74
|
+
});
|
|
75
|
+
};
|
|
61
76
|
//# sourceMappingURL=selection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/logic/utxos/selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,
|
|
1
|
+
{"version":3,"file":"selection.js","sourceRoot":"","sources":["../../../src/logic/utxos/selection.ts"],"names":[],"mappings":"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"}
|
package/lib-es/types/errors.d.ts
CHANGED
|
@@ -7,10 +7,4 @@ export declare const TransactionMassExceededError: import("@ledgerhq/errors/lib/
|
|
|
7
7
|
export declare const EmptyRecipientError: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{
|
|
8
8
|
[key: string]: unknown;
|
|
9
9
|
}>;
|
|
10
|
-
export declare const ReducedAmountUtxoWarning: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{
|
|
11
|
-
[key: string]: unknown;
|
|
12
|
-
}>;
|
|
13
|
-
export declare const UtxoLimitReachedError: import("@ledgerhq/errors/lib/helpers").LedgerErrorConstructor<{
|
|
14
|
-
[key: string]: unknown;
|
|
15
|
-
}>;
|
|
16
10
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB;;EAA8C,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,iBAAiB;;EAA8C,CAAC;AAE7E,eAAO,MAAM,4BAA4B;;EAAyD,CAAC;AAEnG,eAAO,MAAM,mBAAmB;;EAAgD,CAAC"}
|
package/lib-es/types/errors.js
CHANGED
|
@@ -2,6 +2,4 @@ import { createCustomErrorClass } from "@ledgerhq/errors";
|
|
|
2
2
|
export const NotEnoughFeeError = createCustomErrorClass("NotEnoughFeeError");
|
|
3
3
|
export const TransactionMassExceededError = createCustomErrorClass("TransactionMassExceededError");
|
|
4
4
|
export const EmptyRecipientError = createCustomErrorClass("EmptyRecipientError");
|
|
5
|
-
export const ReducedAmountUtxoWarning = createCustomErrorClass("ReducedAmountUtxoWarning");
|
|
6
|
-
export const UtxoLimitReachedError = createCustomErrorClass("UtxoLimitReachedError");
|
|
7
5
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,mBAAmB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/types/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,CAAC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,mBAAmB,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,4BAA4B,GAAG,sBAAsB,CAAC,8BAA8B,CAAC,CAAC;AAEnG,MAAM,CAAC,MAAM,mBAAmB,GAAG,sBAAsB,CAAC,qBAAqB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/coin-kaspa",
|
|
3
|
-
"version": "1.4.1
|
|
3
|
+
"version": "1.4.1",
|
|
4
4
|
"description": "Ledger framework for Kaspa integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger",
|
|
@@ -97,15 +97,15 @@
|
|
|
97
97
|
"lru-cache": "^7.14.1",
|
|
98
98
|
"prando": "^6.0.1",
|
|
99
99
|
"rxjs": "^7.8.1",
|
|
100
|
-
"@ledgerhq/coin-framework": "^6.9.0
|
|
101
|
-
"@ledgerhq/cryptoassets": "^13.33.0
|
|
100
|
+
"@ledgerhq/coin-framework": "^6.9.0",
|
|
101
|
+
"@ledgerhq/cryptoassets": "^13.33.0",
|
|
102
102
|
"@ledgerhq/devices": "8.7.0",
|
|
103
103
|
"@ledgerhq/errors": "^6.27.0",
|
|
104
|
-
"@ledgerhq/live-env": "^2.21.0
|
|
105
|
-
"@ledgerhq/live-network": "^2.1.1
|
|
104
|
+
"@ledgerhq/live-env": "^2.21.0",
|
|
105
|
+
"@ledgerhq/live-network": "^2.1.1",
|
|
106
106
|
"@ledgerhq/logs": "^6.13.0",
|
|
107
107
|
"@ledgerhq/types-cryptoassets": "^7.30.0",
|
|
108
|
-
"@ledgerhq/types-live": "^6.89.0
|
|
108
|
+
"@ledgerhq/types-live": "^6.89.0"
|
|
109
109
|
},
|
|
110
110
|
"devDependencies": {
|
|
111
111
|
"@types/invariant": "^2.2.2",
|
|
@@ -118,7 +118,8 @@
|
|
|
118
118
|
"timemachine": "^0.3.2",
|
|
119
119
|
"ts-jest": "^29.1.1",
|
|
120
120
|
"@ledgerhq/disable-network-setup": "^0.1.0",
|
|
121
|
-
"@ledgerhq/hw-transport-node-speculos": "^6.29.13"
|
|
121
|
+
"@ledgerhq/hw-transport-node-speculos": "^6.29.13",
|
|
122
|
+
"@ledgerhq/hw-transport-node-speculos-http": "^6.31.0"
|
|
122
123
|
},
|
|
123
124
|
"scripts": {
|
|
124
125
|
"clean": "rimraf lib lib-es",
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
NotEnoughBalance,
|
|
9
9
|
RecipientRequired,
|
|
10
10
|
} from "@ledgerhq/errors";
|
|
11
|
-
import { ReducedAmountUtxoWarning, UtxoLimitReachedError } from "../types/errors";
|
|
12
11
|
import { BigNumber } from "bignumber.js";
|
|
13
12
|
import {
|
|
14
13
|
calcMaxSpendableAmount,
|
|
@@ -20,7 +19,6 @@ import {
|
|
|
20
19
|
} from "../logic";
|
|
21
20
|
import { KaspaAccount, Transaction, TransactionStatus } from "../types";
|
|
22
21
|
import { makeLRUCache, minutes } from "@ledgerhq/live-network/cache";
|
|
23
|
-
import { MAX_UTXOS_PER_TX } from "../logic/constants";
|
|
24
22
|
|
|
25
23
|
const getCachedUtxos = makeLRUCache(
|
|
26
24
|
async (account: KaspaAccount) => {
|
|
@@ -85,17 +83,10 @@ const getTransactionStatus = async (
|
|
|
85
83
|
if (transaction.amount.lt(20000000)) {
|
|
86
84
|
errors.dustLimit = new DustLimit("");
|
|
87
85
|
}
|
|
88
|
-
if (utxos.length > MAX_UTXOS_PER_TX) {
|
|
89
|
-
warnings.amount = new ReducedAmountUtxoWarning();
|
|
90
|
-
}
|
|
91
86
|
}
|
|
92
87
|
|
|
93
88
|
if (transaction.amount.gt(maxSpendableAmount) || maxSpendableAmount.eq(0)) {
|
|
94
|
-
|
|
95
|
-
errors.amount = new UtxoLimitReachedError();
|
|
96
|
-
} else {
|
|
97
|
-
errors.amount = new NotEnoughBalance();
|
|
98
|
-
}
|
|
89
|
+
errors.amount = new NotEnoughBalance();
|
|
99
90
|
}
|
|
100
91
|
|
|
101
92
|
if (Object.keys(errors).length === 0) {
|
|
@@ -10,6 +10,8 @@ const INITIAL_BALANCE = BigNumber(0);
|
|
|
10
10
|
const GAP_LIMIT = 20;
|
|
11
11
|
const SCAN_BATCH_SIZE = 200;
|
|
12
12
|
|
|
13
|
+
const MAX_TX_INPUTS = 88; // floor (( 100_000 - 918 (def_size with 2 outputs) ) / 1_118 (per_input))
|
|
14
|
+
|
|
13
15
|
/**
|
|
14
16
|
* Scans the addresses for an account and retrieves information such as used addresses and the total balance.
|
|
15
17
|
*
|
|
@@ -85,8 +87,16 @@ export async function scanAddresses(
|
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
const spendableBalance = [
|
|
91
|
+
...accountAddresses.usedChangeAddresses,
|
|
92
|
+
...accountAddresses.usedReceiveAddresses,
|
|
93
|
+
]
|
|
94
|
+
.sort((a, b) => b.balance.minus(a.balance).toNumber())
|
|
95
|
+
.slice(0, MAX_TX_INPUTS)
|
|
96
|
+
.map(utxo => utxo.balance)
|
|
97
|
+
.reduce((acc, v) => acc.plus(v), BigNumber(0));
|
|
98
|
+
|
|
99
|
+
accountAddresses.spendableBalance = spendableBalance;
|
|
90
100
|
|
|
91
101
|
return accountAddresses;
|
|
92
102
|
}
|
|
@@ -244,26 +244,14 @@ describe("1 output without discard", () => {
|
|
|
244
244
|
expect(selectedUtxos.changeAmount.toNumber()).toBe(0);
|
|
245
245
|
});
|
|
246
246
|
|
|
247
|
-
test("should throw an error if
|
|
247
|
+
test("should throw an error if UTXO count exceeds maximum limit", () => {
|
|
248
248
|
const utxos = KaspaUtxoGenerator.generateUtxoSet(100, BigNumber(1_0000_0000), "0");
|
|
249
249
|
const feeRate = 1;
|
|
250
250
|
const isEcdsaRecipient = false;
|
|
251
251
|
|
|
252
252
|
expect(() => {
|
|
253
|
-
selectUtxos(utxos, isEcdsaRecipient, BigNumber(
|
|
254
|
-
}).toThrow("UTXO
|
|
255
|
-
});
|
|
256
|
-
|
|
257
|
-
test("should be fine, if less than 88 UTXOs needed for a set of 100 UTXO", () => {
|
|
258
|
-
const utxos = KaspaUtxoGenerator.generateUtxoSet(100, BigNumber(1_0000_0000), "0");
|
|
259
|
-
const feeRate = 1;
|
|
260
|
-
const isEcdsaRecipient = false;
|
|
261
|
-
|
|
262
|
-
const selectedUtxos = selectUtxos(utxos, isEcdsaRecipient, BigNumber(80_0000_0000), feeRate);
|
|
263
|
-
|
|
264
|
-
expect(selectedUtxos.utxos.length).toBe(81);
|
|
265
|
-
expect(selectedUtxos.fee.toNumber()).toBe(81 * 1118 + 918);
|
|
266
|
-
expect(selectedUtxos.changeAmount.toNumber()).toBe(1_0000_0000 - (81 * 1118 + 918));
|
|
253
|
+
selectUtxos(utxos, isEcdsaRecipient, BigNumber(1_0000_0000), feeRate);
|
|
254
|
+
}).toThrow("UTXO count exceeds the limit of 88 for a TX.");
|
|
267
255
|
});
|
|
268
256
|
|
|
269
257
|
test("should throw an error if discarded change exceeds maximum allowable discard value", () => {
|
|
@@ -276,21 +264,6 @@ describe("1 output without discard", () => {
|
|
|
276
264
|
}).toThrow(/Change \d+ Sompis is too high to be discarded./);
|
|
277
265
|
});
|
|
278
266
|
|
|
279
|
-
test("Send maximum amount for 88/100 UTXOs", () => {
|
|
280
|
-
const utxos = KaspaUtxoGenerator.generateUtxoSet(100, BigNumber(1_0000_0000), "0");
|
|
281
|
-
const feeRate = 1;
|
|
282
|
-
const isEcdsaRecipient = false;
|
|
283
|
-
|
|
284
|
-
const expectedFee = 88 * 1118 + 506;
|
|
285
|
-
|
|
286
|
-
const maxAmount = BigNumber(88_0000_0000).minus(expectedFee);
|
|
287
|
-
const selectedUtxos = selectUtxos(utxos, isEcdsaRecipient, maxAmount, feeRate);
|
|
288
|
-
|
|
289
|
-
expect(selectedUtxos.utxos.length).toBe(88);
|
|
290
|
-
expect(selectedUtxos.fee.toNumber()).toBe(expectedFee);
|
|
291
|
-
expect(selectedUtxos.changeAmount.toNumber()).toBe(0);
|
|
292
|
-
});
|
|
293
|
-
|
|
294
267
|
test("should throw - UTXOs can't be determined to fulfill the specified amount", () => {
|
|
295
268
|
jest.spyOn(lib, "calcMaxSpendableAmount").mockReturnValue(BigNumber(1_2345_0000));
|
|
296
269
|
const feeRate = 1;
|
package/src/logic/utxos/lib.ts
CHANGED
|
@@ -1,20 +1,27 @@
|
|
|
1
1
|
import { BigNumber } from "bignumber.js";
|
|
2
2
|
import { KaspaUtxo } from "../../types";
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
const ADDITIONAL_MASS_PER_INPUT = 1118;
|
|
5
|
+
|
|
6
|
+
const DEFAULT_MASS_1_OUTPUT: number = 506;
|
|
7
|
+
const MAX_UTXOS_PER_TX: number = 88;
|
|
4
8
|
|
|
5
9
|
export const calcMaxSpendableAmount = (
|
|
6
10
|
utxos: KaspaUtxo[],
|
|
7
11
|
isEcdsaRecipient: boolean,
|
|
8
12
|
feerate: number = 1,
|
|
9
13
|
): BigNumber => {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
const maxInputAmount = utxos.reduce(
|
|
15
|
+
(sum, utxo) => sum.plus(new BigNumber(utxo.utxoEntry.amount)),
|
|
16
|
+
new BigNumber(0),
|
|
17
|
+
);
|
|
13
18
|
|
|
14
19
|
// storage mass can be neglected here
|
|
15
20
|
// max compute mass for one output and 88 inputs is 98901
|
|
16
21
|
let maxSpendableAmount = maxInputAmount.minus(
|
|
17
|
-
BigNumber(
|
|
22
|
+
BigNumber(
|
|
23
|
+
DEFAULT_MASS_1_OUTPUT + Math.min(MAX_UTXOS_PER_TX, utxos.length) * ADDITIONAL_MASS_PER_INPUT,
|
|
24
|
+
).times(feerate),
|
|
18
25
|
);
|
|
19
26
|
|
|
20
27
|
if (isEcdsaRecipient) {
|
|
@@ -31,15 +38,3 @@ export const sumBigNumber = (values: BigNumber[]): BigNumber => {
|
|
|
31
38
|
export const sumUtxoAmounts = (utxos: KaspaUtxo[]): BigNumber => {
|
|
32
39
|
return utxos.reduce((acc, v) => acc.plus(v.utxoEntry.amount), BigNumber(0));
|
|
33
40
|
};
|
|
34
|
-
|
|
35
|
-
export const sortUtxos = (utxos: KaspaUtxo[]) => {
|
|
36
|
-
utxos.sort((a, b) => {
|
|
37
|
-
const transactionComparison = a.utxoEntry.blockDaaScore.localeCompare(
|
|
38
|
-
b.utxoEntry.blockDaaScore,
|
|
39
|
-
);
|
|
40
|
-
if (transactionComparison !== 0) {
|
|
41
|
-
return transactionComparison;
|
|
42
|
-
}
|
|
43
|
-
return a.utxoEntry.amount.minus(b.utxoEntry.amount).toNumber();
|
|
44
|
-
});
|
|
45
|
-
};
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { BigNumber } from "bignumber.js";
|
|
2
2
|
import { KaspaUtxo } from "../../types";
|
|
3
3
|
import { calcComputeMass, calcStorageMass } from "../massCalcluation";
|
|
4
|
-
import { calcMaxSpendableAmount,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from "../constants";
|
|
4
|
+
import { calcMaxSpendableAmount, sumUtxoAmounts } from "./lib";
|
|
5
|
+
|
|
6
|
+
const MASS_LIMIT_PER_TX = 100_000; // TX mass must not exceed 100k gram.
|
|
7
|
+
const MASS_PER_INPUT: number = 1118; // Per selected utxo as input, mass increases by this value.
|
|
8
|
+
const MASS_PER_OUTPUT: number = 412; // Per selected utxo as input, mass increases by this value.
|
|
9
|
+
const MAX_UTXOS_PER_TX: number = 88; // 88 is the maximum of utxo inputs in one TX.
|
|
10
|
+
const MAX_DISCARD: number = 2000_0000; // Throw error, if discarded value is higher than this.
|
|
12
11
|
|
|
13
12
|
export const selectUtxos = (
|
|
14
13
|
utxos: KaspaUtxo[],
|
|
@@ -18,17 +17,19 @@ export const selectUtxos = (
|
|
|
18
17
|
): { changeAmount: BigNumber; fee: BigNumber; utxos: KaspaUtxo[] } => {
|
|
19
18
|
// always sort utxos
|
|
20
19
|
sortUtxos(utxos);
|
|
21
|
-
//
|
|
22
|
-
|
|
20
|
+
// Max UTXO count is 88. More don't fit into a regular TX
|
|
21
|
+
if (utxos.length > MAX_UTXOS_PER_TX) {
|
|
22
|
+
throw new Error(`UTXO count exceeds the limit of ${MAX_UTXOS_PER_TX} for a TX.`);
|
|
23
|
+
}
|
|
23
24
|
|
|
24
|
-
//
|
|
25
|
-
if (calcMaxSpendableAmount(
|
|
25
|
+
// First check in general, if there is enough amount in the UTXOs.
|
|
26
|
+
if (calcMaxSpendableAmount(utxos, isEcdsaRecipient, feerate).isLessThan(amount)) {
|
|
26
27
|
throw new Error(`UTXO total amount is not sufficient for sending amount ${amount}`);
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
// Find a sufficient slice.
|
|
30
|
-
for (let i = 0; i <
|
|
31
|
-
const selectedUtxos =
|
|
31
|
+
for (let i = 0; i < utxos.length; i++) {
|
|
32
|
+
const selectedUtxos = utxos.slice(0, i + 1);
|
|
32
33
|
const selectedUtxoAmount = sumUtxoAmounts(selectedUtxos);
|
|
33
34
|
// calculate absolute min fee for regular TX with 1 outputs and the given feerate.
|
|
34
35
|
const minMass = calcComputeMass(i + 1, false, isEcdsaRecipient);
|
|
@@ -85,3 +86,15 @@ export const selectUtxos = (
|
|
|
85
86
|
// Throw an error, if UTXOs can't be determined to fulfill the requirement.
|
|
86
87
|
throw new Error("UTXOs can't be determined to fulfill the specified amount");
|
|
87
88
|
};
|
|
89
|
+
|
|
90
|
+
const sortUtxos = (utxos: KaspaUtxo[]) => {
|
|
91
|
+
utxos.sort((a, b) => {
|
|
92
|
+
const transactionComparison = a.utxoEntry.blockDaaScore.localeCompare(
|
|
93
|
+
b.utxoEntry.blockDaaScore,
|
|
94
|
+
);
|
|
95
|
+
if (transactionComparison !== 0) {
|
|
96
|
+
return transactionComparison;
|
|
97
|
+
}
|
|
98
|
+
return a.utxoEntry.amount.minus(b.utxoEntry.amount).toNumber();
|
|
99
|
+
});
|
|
100
|
+
};
|
package/src/types/errors.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createCustomErrorClass } from "@ledgerhq/errors";
|
|
2
2
|
|
|
3
3
|
export const NotEnoughFeeError = createCustomErrorClass("NotEnoughFeeError");
|
|
4
|
+
|
|
4
5
|
export const TransactionMassExceededError = createCustomErrorClass("TransactionMassExceededError");
|
|
6
|
+
|
|
5
7
|
export const EmptyRecipientError = createCustomErrorClass("EmptyRecipientError");
|
|
6
|
-
export const ReducedAmountUtxoWarning = createCustomErrorClass("ReducedAmountUtxoWarning");
|
|
7
|
-
export const UtxoLimitReachedError = createCustomErrorClass("UtxoLimitReachedError");
|
package/lib/logic/constants.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export declare const MAX_UTXOS_PER_TX: number;
|
|
2
|
-
export declare const DEFAULT_MASS_1_OUTPUT: number;
|
|
3
|
-
export declare const MASS_PER_INPUT: number;
|
|
4
|
-
export declare const MASS_PER_OUTPUT: number;
|
|
5
|
-
export declare const MASS_LIMIT_PER_TX = 100000;
|
|
6
|
-
export declare const MAX_DISCARD: number;
|
|
7
|
-
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/logic/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAE,MAAW,CAAC;AAC3C,eAAO,MAAM,qBAAqB,EAAE,MAAY,CAAC;AAEjD,eAAO,MAAM,cAAc,EAAE,MAAa,CAAC;AAC3C,eAAO,MAAM,eAAe,EAAE,MAAY,CAAC;AAE3C,eAAO,MAAM,iBAAiB,SAAU,CAAC;AACzC,eAAO,MAAM,WAAW,EAAE,MAAkB,CAAC"}
|
package/lib/logic/constants.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MAX_DISCARD = exports.MASS_LIMIT_PER_TX = exports.MASS_PER_OUTPUT = exports.MASS_PER_INPUT = exports.DEFAULT_MASS_1_OUTPUT = exports.MAX_UTXOS_PER_TX = void 0;
|
|
4
|
-
exports.MAX_UTXOS_PER_TX = 88;
|
|
5
|
-
exports.DEFAULT_MASS_1_OUTPUT = 506;
|
|
6
|
-
exports.MASS_PER_INPUT = 1118; // Per selected utxo as input, mass increases by this value.
|
|
7
|
-
exports.MASS_PER_OUTPUT = 412; // Per selected utxo as input, mass increases by this value.
|
|
8
|
-
exports.MASS_LIMIT_PER_TX = 100_000; // TX mass must not exceed 100k gram.
|
|
9
|
-
exports.MAX_DISCARD = 2000_0000; // Throw error, if discarded value is higher than this.
|
|
10
|
-
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/logic/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAW,EAAE,CAAC;AAC9B,QAAA,qBAAqB,GAAW,GAAG,CAAC;AAEpC,QAAA,cAAc,GAAW,IAAI,CAAC,CAAC,4DAA4D;AAC3F,QAAA,eAAe,GAAW,GAAG,CAAC,CAAC,4DAA4D;AAE3F,QAAA,iBAAiB,GAAG,OAAO,CAAC,CAAC,qCAAqC;AAClE,QAAA,WAAW,GAAW,SAAS,CAAC,CAAC,uDAAuD"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export declare const MAX_UTXOS_PER_TX: number;
|
|
2
|
-
export declare const DEFAULT_MASS_1_OUTPUT: number;
|
|
3
|
-
export declare const MASS_PER_INPUT: number;
|
|
4
|
-
export declare const MASS_PER_OUTPUT: number;
|
|
5
|
-
export declare const MASS_LIMIT_PER_TX = 100000;
|
|
6
|
-
export declare const MAX_DISCARD: number;
|
|
7
|
-
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/logic/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,EAAE,MAAW,CAAC;AAC3C,eAAO,MAAM,qBAAqB,EAAE,MAAY,CAAC;AAEjD,eAAO,MAAM,cAAc,EAAE,MAAa,CAAC;AAC3C,eAAO,MAAM,eAAe,EAAE,MAAY,CAAC;AAE3C,eAAO,MAAM,iBAAiB,SAAU,CAAC;AACzC,eAAO,MAAM,WAAW,EAAE,MAAkB,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
export const MAX_UTXOS_PER_TX = 88;
|
|
2
|
-
export const DEFAULT_MASS_1_OUTPUT = 506;
|
|
3
|
-
export const MASS_PER_INPUT = 1118; // Per selected utxo as input, mass increases by this value.
|
|
4
|
-
export const MASS_PER_OUTPUT = 412; // Per selected utxo as input, mass increases by this value.
|
|
5
|
-
export const MASS_LIMIT_PER_TX = 100_000; // TX mass must not exceed 100k gram.
|
|
6
|
-
export const MAX_DISCARD = 2000_0000; // Throw error, if discarded value is higher than this.
|
|
7
|
-
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/logic/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAW,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,qBAAqB,GAAW,GAAG,CAAC;AAEjD,MAAM,CAAC,MAAM,cAAc,GAAW,IAAI,CAAC,CAAC,4DAA4D;AACxG,MAAM,CAAC,MAAM,eAAe,GAAW,GAAG,CAAC,CAAC,4DAA4D;AAExG,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,CAAC,qCAAqC;AAC/E,MAAM,CAAC,MAAM,WAAW,GAAW,SAAS,CAAC,CAAC,uDAAuD"}
|
package/src/logic/constants.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export const MAX_UTXOS_PER_TX: number = 88;
|
|
2
|
-
export const DEFAULT_MASS_1_OUTPUT: number = 506;
|
|
3
|
-
|
|
4
|
-
export const MASS_PER_INPUT: number = 1118; // Per selected utxo as input, mass increases by this value.
|
|
5
|
-
export const MASS_PER_OUTPUT: number = 412; // Per selected utxo as input, mass increases by this value.
|
|
6
|
-
|
|
7
|
-
export const MASS_LIMIT_PER_TX = 100_000; // TX mass must not exceed 100k gram.
|
|
8
|
-
export const MAX_DISCARD: number = 2000_0000; // Throw error, if discarded value is higher than this.
|