@arkade-os/sdk 0.4.15 → 0.4.16
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/README.md +102 -96
- package/dist/cjs/arkfee/estimator.js +1 -1
- package/dist/cjs/arkfee/types.js +2 -1
- package/dist/cjs/arknote/index.js +43 -4
- package/dist/cjs/bip322/index.js +1 -1
- package/dist/cjs/contracts/arkcontract.js +1 -1
- package/dist/cjs/contracts/contractManager.js +40 -24
- package/dist/cjs/contracts/contractWatcher.js +29 -22
- package/dist/cjs/contracts/handlers/default.js +1 -1
- package/dist/cjs/contracts/handlers/delegate.js +1 -1
- package/dist/cjs/contracts/handlers/helpers.js +1 -1
- package/dist/cjs/extension/asset/assetGroup.js +92 -5
- package/dist/cjs/extension/asset/assetId.js +67 -3
- package/dist/cjs/extension/asset/assetInput.js +18 -0
- package/dist/cjs/extension/asset/assetOutput.js +15 -0
- package/dist/cjs/extension/asset/assetRef.js +66 -0
- package/dist/cjs/extension/asset/metadata.js +15 -0
- package/dist/cjs/extension/asset/packet.js +4 -1
- package/dist/cjs/extension/index.js +1 -1
- package/dist/cjs/forfeit.js +14 -0
- package/dist/cjs/identity/seedIdentity.js +2 -2
- package/dist/cjs/identity/singleKey.js +4 -0
- package/dist/cjs/intent/index.js +28 -12
- package/dist/cjs/providers/ark.js +3 -2
- package/dist/cjs/providers/delegator.js +20 -1
- package/dist/cjs/providers/expoArk.js +2 -2
- package/dist/cjs/providers/indexer.js +2 -2
- package/dist/cjs/providers/onchain.js +2 -1
- package/dist/cjs/repositories/realm/schemas.js +2 -2
- package/dist/cjs/repositories/realm/types.js +1 -1
- package/dist/cjs/script/address.js +37 -6
- package/dist/cjs/script/base.js +70 -1
- package/dist/cjs/script/default.js +3 -0
- package/dist/cjs/script/delegate.js +4 -0
- package/dist/cjs/script/tapscript.js +17 -2
- package/dist/cjs/script/vhtlc.js +35 -27
- package/dist/cjs/storage/fileSystem.js +1 -1
- package/dist/cjs/storage/inMemory.js +1 -1
- package/dist/cjs/storage/indexedDB.js +1 -1
- package/dist/cjs/storage/localStorage.js +1 -1
- package/dist/cjs/tree/validation.js +1 -1
- package/dist/cjs/utils/arkTransaction.js +5 -5
- package/dist/cjs/utils/bip21.js +16 -3
- package/dist/cjs/utils/syncCursors.js +4 -4
- package/dist/cjs/utils/transaction.js +1 -1
- package/dist/cjs/utils/transactionHistory.js +11 -11
- package/dist/cjs/utils/unknownFields.js +3 -3
- package/dist/cjs/wallet/asset-manager.js +4 -4
- package/dist/cjs/wallet/batch.js +5 -5
- package/dist/cjs/wallet/delegator.js +9 -8
- package/dist/cjs/wallet/expo/background.js +3 -3
- package/dist/cjs/wallet/expo/wallet.js +7 -7
- package/dist/cjs/wallet/index.js +43 -0
- package/dist/cjs/wallet/onchain.js +43 -5
- package/dist/cjs/wallet/ramps.js +44 -14
- package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +22 -22
- package/dist/cjs/wallet/serviceWorker/wallet.js +28 -24
- package/dist/cjs/wallet/unroll.js +12 -8
- package/dist/cjs/wallet/utils.js +1 -1
- package/dist/cjs/wallet/vtxo-manager.js +122 -82
- package/dist/cjs/wallet/wallet.js +125 -67
- package/dist/cjs/worker/expo/asyncStorageTaskQueue.js +1 -1
- package/dist/cjs/worker/expo/processors/contractPollProcessor.js +2 -2
- package/dist/cjs/worker/expo/taskRunner.js +3 -3
- package/dist/cjs/worker/messageBus.js +3 -0
- package/dist/esm/arkfee/estimator.js +1 -1
- package/dist/esm/arkfee/types.js +2 -1
- package/dist/esm/arknote/index.js +43 -4
- package/dist/esm/bip322/index.js +1 -1
- package/dist/esm/contracts/arkcontract.js +1 -1
- package/dist/esm/contracts/contractManager.js +40 -24
- package/dist/esm/contracts/contractWatcher.js +29 -22
- package/dist/esm/contracts/handlers/default.js +1 -1
- package/dist/esm/contracts/handlers/delegate.js +1 -1
- package/dist/esm/contracts/handlers/helpers.js +1 -1
- package/dist/esm/extension/asset/assetGroup.js +92 -5
- package/dist/esm/extension/asset/assetId.js +67 -3
- package/dist/esm/extension/asset/assetInput.js +18 -0
- package/dist/esm/extension/asset/assetOutput.js +15 -0
- package/dist/esm/extension/asset/assetRef.js +66 -0
- package/dist/esm/extension/asset/metadata.js +15 -0
- package/dist/esm/extension/asset/packet.js +4 -1
- package/dist/esm/extension/index.js +1 -1
- package/dist/esm/forfeit.js +14 -0
- package/dist/esm/identity/seedIdentity.js +2 -2
- package/dist/esm/identity/singleKey.js +4 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/intent/index.js +28 -12
- package/dist/esm/providers/ark.js +3 -2
- package/dist/esm/providers/delegator.js +20 -1
- package/dist/esm/providers/expoArk.js +2 -2
- package/dist/esm/providers/indexer.js +2 -2
- package/dist/esm/providers/onchain.js +2 -1
- package/dist/esm/repositories/realm/schemas.js +2 -2
- package/dist/esm/repositories/realm/types.js +1 -1
- package/dist/esm/script/address.js +37 -6
- package/dist/esm/script/base.js +70 -1
- package/dist/esm/script/default.js +3 -0
- package/dist/esm/script/delegate.js +4 -0
- package/dist/esm/script/tapscript.js +17 -2
- package/dist/esm/script/vhtlc.js +35 -27
- package/dist/esm/storage/fileSystem.js +1 -1
- package/dist/esm/storage/inMemory.js +1 -1
- package/dist/esm/storage/indexedDB.js +1 -1
- package/dist/esm/storage/localStorage.js +1 -1
- package/dist/esm/tree/validation.js +1 -1
- package/dist/esm/utils/arkTransaction.js +5 -5
- package/dist/esm/utils/bip21.js +16 -3
- package/dist/esm/utils/syncCursors.js +4 -4
- package/dist/esm/utils/transaction.js +1 -1
- package/dist/esm/utils/transactionHistory.js +11 -11
- package/dist/esm/utils/unknownFields.js +3 -3
- package/dist/esm/wallet/asset-manager.js +4 -4
- package/dist/esm/wallet/batch.js +5 -5
- package/dist/esm/wallet/delegator.js +9 -8
- package/dist/esm/wallet/expo/background.js +3 -3
- package/dist/esm/wallet/expo/wallet.js +7 -7
- package/dist/esm/wallet/index.js +43 -0
- package/dist/esm/wallet/onchain.js +43 -5
- package/dist/esm/wallet/ramps.js +44 -14
- package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +22 -22
- package/dist/esm/wallet/serviceWorker/wallet.js +28 -24
- package/dist/esm/wallet/unroll.js +12 -8
- package/dist/esm/wallet/utils.js +1 -1
- package/dist/esm/wallet/vtxo-manager.js +121 -81
- package/dist/esm/wallet/wallet.js +125 -67
- package/dist/esm/worker/expo/asyncStorageTaskQueue.js +1 -1
- package/dist/esm/worker/expo/processors/contractPollProcessor.js +2 -2
- package/dist/esm/worker/expo/taskRunner.js +3 -3
- package/dist/esm/worker/messageBus.js +3 -0
- package/dist/types/arkfee/estimator.d.ts +1 -1
- package/dist/types/arkfee/types.d.ts +2 -1
- package/dist/types/arknote/index.d.ts +44 -4
- package/dist/types/bip322/index.d.ts +1 -1
- package/dist/types/contracts/arkcontract.d.ts +1 -1
- package/dist/types/contracts/contractManager.d.ts +40 -63
- package/dist/types/contracts/contractWatcher.d.ts +39 -18
- package/dist/types/contracts/handlers/default.d.ts +1 -1
- package/dist/types/contracts/handlers/delegate.d.ts +1 -1
- package/dist/types/contracts/handlers/helpers.d.ts +1 -1
- package/dist/types/contracts/types.d.ts +36 -26
- package/dist/types/extension/asset/assetGroup.d.ts +92 -1
- package/dist/types/extension/asset/assetId.d.ts +67 -3
- package/dist/types/extension/asset/assetInput.d.ts +18 -0
- package/dist/types/extension/asset/assetOutput.d.ts +15 -0
- package/dist/types/extension/asset/assetRef.d.ts +66 -0
- package/dist/types/extension/asset/metadata.d.ts +15 -0
- package/dist/types/extension/asset/packet.d.ts +4 -1
- package/dist/types/extension/index.d.ts +1 -1
- package/dist/types/forfeit.d.ts +14 -0
- package/dist/types/identity/index.d.ts +16 -0
- package/dist/types/identity/seedIdentity.d.ts +8 -6
- package/dist/types/identity/singleKey.d.ts +4 -0
- package/dist/types/intent/index.d.ts +19 -6
- package/dist/types/providers/ark.d.ts +40 -2
- package/dist/types/providers/delegator.d.ts +54 -1
- package/dist/types/providers/expoArk.d.ts +2 -2
- package/dist/types/providers/indexer.d.ts +105 -2
- package/dist/types/providers/onchain.d.ts +62 -1
- package/dist/types/repositories/realm/schemas.d.ts +2 -2
- package/dist/types/repositories/realm/types.d.ts +2 -2
- package/dist/types/repositories/walletRepository.d.ts +16 -0
- package/dist/types/script/address.d.ts +35 -2
- package/dist/types/script/base.d.ts +66 -1
- package/dist/types/script/default.d.ts +3 -0
- package/dist/types/script/delegate.d.ts +4 -0
- package/dist/types/script/tapscript.d.ts +17 -2
- package/dist/types/script/vhtlc.d.ts +35 -27
- package/dist/types/storage/fileSystem.d.ts +1 -1
- package/dist/types/storage/inMemory.d.ts +1 -1
- package/dist/types/storage/index.d.ts +1 -1
- package/dist/types/storage/indexedDB.d.ts +1 -1
- package/dist/types/storage/localStorage.d.ts +1 -1
- package/dist/types/utils/arkTransaction.d.ts +3 -3
- package/dist/types/utils/bip21.d.ts +17 -0
- package/dist/types/utils/syncCursors.d.ts +4 -4
- package/dist/types/utils/transaction.d.ts +1 -1
- package/dist/types/utils/transactionHistory.d.ts +3 -3
- package/dist/types/utils/unknownFields.d.ts +5 -5
- package/dist/types/wallet/asset-manager.d.ts +3 -3
- package/dist/types/wallet/batch.d.ts +27 -7
- package/dist/types/wallet/delegator.d.ts +10 -0
- package/dist/types/wallet/expo/background.d.ts +4 -4
- package/dist/types/wallet/expo/wallet.d.ts +10 -10
- package/dist/types/wallet/index.d.ts +457 -25
- package/dist/types/wallet/onchain.d.ts +42 -4
- package/dist/types/wallet/ramps.d.ts +40 -10
- package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +4 -4
- package/dist/types/wallet/serviceWorker/wallet.d.ts +71 -33
- package/dist/types/wallet/unroll.d.ts +8 -6
- package/dist/types/wallet/vtxo-manager.d.ts +146 -93
- package/dist/types/wallet/wallet.d.ts +91 -33
- package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +1 -1
- package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +1 -1
- package/dist/types/worker/expo/taskRunner.d.ts +6 -6
- package/dist/types/worker/messageBus.d.ts +5 -3
- package/package.json +1 -1
package/dist/esm/script/vhtlc.js
CHANGED
|
@@ -2,36 +2,38 @@ import { Script } from "@scure/btc-signer";
|
|
|
2
2
|
import { CLTVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CSVMultisigTapscript, MultisigTapscript, } from './tapscript.js';
|
|
3
3
|
import { hex } from "@scure/base";
|
|
4
4
|
import { VtxoScript } from './base.js';
|
|
5
|
-
/**
|
|
6
|
-
* Virtual Hash Time Lock Contract (VHTLC) implementation.
|
|
7
|
-
*
|
|
8
|
-
* VHTLC is a contract that enables atomic swaps and conditional payments
|
|
9
|
-
* in the Ark protocol. It provides multiple spending paths:
|
|
10
|
-
*
|
|
11
|
-
* - **claim**: Receiver can claim funds by revealing the preimage
|
|
12
|
-
* - **refund**: Sender and receiver can collaboratively refund
|
|
13
|
-
* - **refundWithoutReceiver**: Sender can refund after locktime expires
|
|
14
|
-
* - **unilateralClaim**: Receiver can claim unilaterally after delay
|
|
15
|
-
* - **unilateralRefund**: Sender and receiver can refund unilaterally after delay
|
|
16
|
-
* - **unilateralRefundWithoutReceiver**: Sender can refund unilaterally after delay
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```typescript
|
|
20
|
-
* const vhtlc = new VHTLC.Script({
|
|
21
|
-
* sender: alicePubKey,
|
|
22
|
-
* receiver: bobPubKey,
|
|
23
|
-
* server: serverPubKey,
|
|
24
|
-
* preimageHash: hash160(secret),
|
|
25
|
-
* refundLocktime: BigInt(chainTip + 10),
|
|
26
|
-
* unilateralClaimDelay: { type: 'blocks', value: 100n },
|
|
27
|
-
* unilateralRefundDelay: { type: 'blocks', value: 102n },
|
|
28
|
-
* unilateralRefundWithoutReceiverDelay: { type: 'blocks', value: 103n }
|
|
29
|
-
* });
|
|
30
|
-
* ```
|
|
31
|
-
*/
|
|
5
|
+
/** Virtual Hash Time Lock Contract (VHTLC) namespace. */
|
|
32
6
|
export var VHTLC;
|
|
33
7
|
(function (VHTLC) {
|
|
8
|
+
/**
|
|
9
|
+
* Virtual Hash Time Lock Contract (VHTLC) script implementation.
|
|
10
|
+
*
|
|
11
|
+
* VHTLC enables atomic swaps and conditional payments in the Arkade protocol.
|
|
12
|
+
* It provides multiple spending paths:
|
|
13
|
+
*
|
|
14
|
+
* - **claim**: Receiver can claim funds by revealing the preimage
|
|
15
|
+
* - **refund**: Sender and receiver can collaboratively refund
|
|
16
|
+
* - **refundWithoutReceiver**: Sender can refund after locktime expires
|
|
17
|
+
* - **unilateralClaim**: Receiver can claim unilaterally after delay
|
|
18
|
+
* - **unilateralRefund**: Sender and receiver can refund unilaterally after delay
|
|
19
|
+
* - **unilateralRefundWithoutReceiver**: Sender can refund unilaterally after delay
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const vhtlc = new VHTLC.Script({
|
|
24
|
+
* sender: alicePubKey,
|
|
25
|
+
* receiver: bobPubKey,
|
|
26
|
+
* server: serverPubKey,
|
|
27
|
+
* preimageHash: hash160(secret),
|
|
28
|
+
* refundLocktime: BigInt(chainTip + 10),
|
|
29
|
+
* unilateralClaimDelay: { type: 'blocks', value: 100n },
|
|
30
|
+
* unilateralRefundDelay: { type: 'blocks', value: 102n },
|
|
31
|
+
* unilateralRefundWithoutReceiverDelay: { type: 'blocks', value: 103n }
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
34
35
|
class Script extends VtxoScript {
|
|
36
|
+
/** Create a VHTLC script from the supplied participant keys, hash, and timelocks. */
|
|
35
37
|
constructor(options) {
|
|
36
38
|
validateOptions(options);
|
|
37
39
|
const { sender, receiver, server, preimageHash, refundLocktime, unilateralClaimDelay, unilateralRefundDelay, unilateralRefundWithoutReceiverDelay, } = options;
|
|
@@ -76,21 +78,27 @@ export var VHTLC;
|
|
|
76
78
|
this.unilateralRefundScript = hex.encode(unilateralRefundScript);
|
|
77
79
|
this.unilateralRefundWithoutReceiverScript = hex.encode(unilateralRefundWithoutReceiverScript);
|
|
78
80
|
}
|
|
81
|
+
/** Return the collaborative claim tapleaf script. */
|
|
79
82
|
claim() {
|
|
80
83
|
return this.findLeaf(this.claimScript);
|
|
81
84
|
}
|
|
85
|
+
/** Return the collaborative refund tapleaf script. */
|
|
82
86
|
refund() {
|
|
83
87
|
return this.findLeaf(this.refundScript);
|
|
84
88
|
}
|
|
89
|
+
/** Return the refund-without-receiver tapleaf script. */
|
|
85
90
|
refundWithoutReceiver() {
|
|
86
91
|
return this.findLeaf(this.refundWithoutReceiverScript);
|
|
87
92
|
}
|
|
93
|
+
/** Return the unilateral claim tapleaf script. */
|
|
88
94
|
unilateralClaim() {
|
|
89
95
|
return this.findLeaf(this.unilateralClaimScript);
|
|
90
96
|
}
|
|
97
|
+
/** Return the unilateral refund tapleaf script. */
|
|
91
98
|
unilateralRefund() {
|
|
92
99
|
return this.findLeaf(this.unilateralRefundScript);
|
|
93
100
|
}
|
|
101
|
+
/** Return the unilateral refund-without-receiver tapleaf script. */
|
|
94
102
|
unilateralRefundWithoutReceiver() {
|
|
95
103
|
return this.findLeaf(this.unilateralRefundWithoutReceiverScript);
|
|
96
104
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DB_VERSION } from '../repositories/indexedDB/db.js';
|
|
2
2
|
/**
|
|
3
|
-
* @deprecated Use
|
|
3
|
+
* @deprecated Use repository implementations via `StorageConfig` instead.
|
|
4
4
|
*/
|
|
5
5
|
export class IndexedDBStorageAdapter {
|
|
6
6
|
constructor(dbName, version = DB_VERSION) {
|
|
@@ -32,7 +32,7 @@ export function validateConnectorsTxGraph(settlementTxB64, connectorsGraph) {
|
|
|
32
32
|
if (rootInput.index !== BATCH_OUTPUT_CONNECTORS_INDEX)
|
|
33
33
|
throw ErrWrongSettlementTxid;
|
|
34
34
|
}
|
|
35
|
-
// ValidateVtxoTxGraph checks if the given
|
|
35
|
+
// ValidateVtxoTxGraph checks if the given virtual output tx graph is valid.
|
|
36
36
|
// The function validates:
|
|
37
37
|
// - the number of nodes
|
|
38
38
|
// - the number of leaves
|
|
@@ -14,7 +14,7 @@ import { Extension } from '../extension/index.js';
|
|
|
14
14
|
*
|
|
15
15
|
* Creates one checkpoint transaction per input and a virtual transaction that
|
|
16
16
|
* combines all the checkpoints, sending to the specified outputs. This is the
|
|
17
|
-
* core function for creating
|
|
17
|
+
* core function for creating Arkade transactions.
|
|
18
18
|
*
|
|
19
19
|
* @param inputs - Array of virtual transaction inputs
|
|
20
20
|
* @param outputs - Array of transaction outputs
|
|
@@ -92,9 +92,9 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
92
92
|
return tx;
|
|
93
93
|
}
|
|
94
94
|
function buildCheckpointTx(vtxo, serverUnrollScript) {
|
|
95
|
-
// create the checkpoint
|
|
95
|
+
// create the checkpoint virtual output script from collaborative closure
|
|
96
96
|
const collaborativeClosure = decodeTapscript(scriptFromTapLeafScript(vtxo.tapLeafScript));
|
|
97
|
-
// create the checkpoint
|
|
97
|
+
// create the checkpoint virtual output script combining collaborative closure and server unroll script
|
|
98
98
|
const checkpointVtxoScript = new VtxoScript([
|
|
99
99
|
serverUnrollScript.script,
|
|
100
100
|
collaborativeClosure.script,
|
|
@@ -249,8 +249,8 @@ export function combineTapscriptSigs(signedTx, originalTx) {
|
|
|
249
249
|
return originalTx;
|
|
250
250
|
}
|
|
251
251
|
/**
|
|
252
|
-
* Validates if a given string is a valid
|
|
253
|
-
* @param address The
|
|
252
|
+
* Validates if a given string is a valid Arkade address by attempting to decode it.
|
|
253
|
+
* @param address The Arkade address to validate.
|
|
254
254
|
* @returns True if the address is valid, false otherwise.
|
|
255
255
|
*/
|
|
256
256
|
export function isValidArkAddress(address) {
|
package/dist/esm/utils/bip21.js
CHANGED
|
@@ -4,6 +4,12 @@ export var BIP21Error;
|
|
|
4
4
|
BIP21Error["INVALID_ADDRESS"] = "Invalid address";
|
|
5
5
|
})(BIP21Error || (BIP21Error = {}));
|
|
6
6
|
export class BIP21 {
|
|
7
|
+
/**
|
|
8
|
+
* Create a BIP21 URI from the provided parameters.
|
|
9
|
+
*
|
|
10
|
+
* @param params - BIP21 parameters to encode
|
|
11
|
+
* @returns Encoded BIP21 URI
|
|
12
|
+
*/
|
|
7
13
|
static create(params) {
|
|
8
14
|
const { address, ...options } = params;
|
|
9
15
|
// Build query string
|
|
@@ -22,7 +28,7 @@ export class BIP21 {
|
|
|
22
28
|
queryParams[key] = value;
|
|
23
29
|
}
|
|
24
30
|
else if (key === "ark") {
|
|
25
|
-
// Validate
|
|
31
|
+
// Validate Arkade address format
|
|
26
32
|
if (typeof value === "string" &&
|
|
27
33
|
(value.startsWith("ark") || value.startsWith("tark"))) {
|
|
28
34
|
queryParams[key] = value;
|
|
@@ -53,11 +59,18 @@ export class BIP21 {
|
|
|
53
59
|
: "";
|
|
54
60
|
return `bitcoin:${address ? address.toLowerCase() : ""}${query}`;
|
|
55
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Parse a BIP21 URI and return its decoded parameters.
|
|
64
|
+
*
|
|
65
|
+
* @param uri - BIP21 URI to parse
|
|
66
|
+
* @returns Parsed BIP21 URI data
|
|
67
|
+
* @throws Error if the URI does not start with the `bitcoin:` scheme
|
|
68
|
+
*/
|
|
56
69
|
static parse(uri) {
|
|
57
70
|
if (!uri.toLowerCase().startsWith("bitcoin:")) {
|
|
58
71
|
throw new Error(BIP21Error.INVALID_URI);
|
|
59
72
|
}
|
|
60
|
-
// Remove bitcoin
|
|
73
|
+
// Remove the `bitcoin:` prefix while preserving the case of the rest.
|
|
61
74
|
const withoutPrefix = uri.slice(uri.toLowerCase().indexOf("bitcoin:") + 8);
|
|
62
75
|
const [address, query] = withoutPrefix.split("?");
|
|
63
76
|
const params = {};
|
|
@@ -80,7 +93,7 @@ export class BIP21 {
|
|
|
80
93
|
params[key] = amount;
|
|
81
94
|
}
|
|
82
95
|
else if (key === "ark") {
|
|
83
|
-
// Validate
|
|
96
|
+
// Validate Arkade address format
|
|
84
97
|
if (value.startsWith("ark") || value.startsWith("tark")) {
|
|
85
98
|
params[key] = value;
|
|
86
99
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Lag behind real-time to avoid racing with indexer writes. */
|
|
2
2
|
export const SAFETY_LAG_MS = 30000;
|
|
3
|
-
/** Overlap window so boundary
|
|
3
|
+
/** Overlap window so boundary virtual outputs are never missed. */
|
|
4
4
|
export const OVERLAP_MS = 60000;
|
|
5
5
|
/**
|
|
6
6
|
* Per-repository mutex that serializes wallet-state mutations so that
|
|
@@ -101,8 +101,8 @@ export async function clearSyncCursors(repo, scripts) {
|
|
|
101
101
|
* Returns `undefined` when the script has no cursor (bootstrap needed).
|
|
102
102
|
*
|
|
103
103
|
* No upper bound (`before`) is applied to the query so that freshly
|
|
104
|
-
* created
|
|
105
|
-
* when advancing the cursor (see
|
|
104
|
+
* created virtual outputs are never excluded. The safety lag is applied only
|
|
105
|
+
* when advancing the cursor (see @see cursorCutoff).
|
|
106
106
|
*/
|
|
107
107
|
export function computeSyncWindow(cursor) {
|
|
108
108
|
if (cursor === undefined)
|
|
@@ -112,7 +112,7 @@ export function computeSyncWindow(cursor) {
|
|
|
112
112
|
}
|
|
113
113
|
/**
|
|
114
114
|
* The safe high-water mark for cursor advancement.
|
|
115
|
-
* Lags behind real-time by
|
|
115
|
+
* Lags behind real-time by @see SAFETY_LAG_MS so that virtual outputs still
|
|
116
116
|
* being indexed are re-queried on the next sync.
|
|
117
117
|
*
|
|
118
118
|
* When `requestStartedAt` is provided the cutoff is frozen to the
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Transaction as BtcSignerTransaction } from "@scure/btc-signer";
|
|
2
2
|
/**
|
|
3
3
|
* Transaction is a wrapper around the @scure/btc-signer Transaction class.
|
|
4
|
-
* It adds the
|
|
4
|
+
* It adds the Arkade protocol specific options to the transaction.
|
|
5
5
|
*/
|
|
6
6
|
export class Transaction extends BtcSignerTransaction {
|
|
7
7
|
constructor(opts) {
|
|
@@ -45,13 +45,13 @@ function subtractAssets(spent, change) {
|
|
|
45
45
|
return Array.from(map, ([assetId, amount]) => ({ assetId, amount }));
|
|
46
46
|
}
|
|
47
47
|
/**
|
|
48
|
-
* Builds the transaction history by analyzing virtual
|
|
48
|
+
* Builds the transaction history by analyzing virtual outputs, boarding transactions, and ignored commitments.
|
|
49
49
|
* History is sorted from newest to oldest and is composed only of SENT and RECEIVED transactions.
|
|
50
50
|
*
|
|
51
|
-
* @param {VirtualCoin[]} vtxos - An array of virtual
|
|
51
|
+
* @param {VirtualCoin[]} vtxos - An array of virtual outputs representing the user's transactions and balances.
|
|
52
52
|
* @param {ArkTransaction[]} allBoardingTxs - An array of boarding transactions to include in the history.
|
|
53
53
|
* @param {Set<string>} commitmentsToIgnore - A set of commitment IDs that should be excluded from processing.
|
|
54
|
-
* @return {ExtendedArkTransaction[]} A sorted array of extended
|
|
54
|
+
* @return {ExtendedArkTransaction[]} A sorted array of extended Arkade transactions, representing the transaction history.
|
|
55
55
|
*/
|
|
56
56
|
export async function buildTransactionHistory(vtxos, allBoardingTxs, commitmentsToIgnore, getTxCreatedAt) {
|
|
57
57
|
const fromOldestVtxo = [...vtxos].sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
@@ -59,7 +59,7 @@ export async function buildTransactionHistory(vtxos, allBoardingTxs, commitments
|
|
|
59
59
|
let received = [];
|
|
60
60
|
for (const vtxo of fromOldestVtxo) {
|
|
61
61
|
if (vtxo.status.isLeaf) {
|
|
62
|
-
// If this
|
|
62
|
+
// If this virtual output is a leaf and it's not the settlement of a boarding or there's no virtual output refreshed by it,
|
|
63
63
|
// it's translated into a received batch transaction
|
|
64
64
|
if (!commitmentsToIgnore.has(vtxo.virtualStatus.commitmentTxIds[0]) &&
|
|
65
65
|
fromOldestVtxo.filter((v) => v.settledBy === vtxo.virtualStatus.commitmentTxIds[0]).length === 0) {
|
|
@@ -79,7 +79,7 @@ export async function buildTransactionHistory(vtxos, allBoardingTxs, commitments
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
else if (fromOldestVtxo.filter((v) => v.arkTxId === vtxo.txid).length === 0) {
|
|
82
|
-
// If this
|
|
82
|
+
// If this virtual output is preconfirmed and does not spend any other virtual outputs,
|
|
83
83
|
// it's translated into a received offchain transaction
|
|
84
84
|
const assets = collectAssets([vtxo]);
|
|
85
85
|
received.push({
|
|
@@ -92,15 +92,15 @@ export async function buildTransactionHistory(vtxos, allBoardingTxs, commitments
|
|
|
92
92
|
...(assets && { assets }),
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
|
-
// If the
|
|
95
|
+
// If the virtual output is spent, it's translated into a sent transaction unless:
|
|
96
96
|
// - it's been refreshed (we don't want to add any record in this case)
|
|
97
|
-
// - a sent transaction has been already added to avoid duplicates (can happen if many
|
|
97
|
+
// - a sent transaction has been already added to avoid duplicates (can happen if many virtual outputs have been spent in the same tx or forfeited in the same batch)
|
|
98
98
|
if (vtxo.isSpent) {
|
|
99
|
-
// If the
|
|
99
|
+
// If the virtual output is spent offchain, it's translated into an offchain sent tx
|
|
100
100
|
if (vtxo.arkTxId &&
|
|
101
101
|
!sent.some((s) => s.key.arkTxid === vtxo.arkTxId)) {
|
|
102
102
|
const changes = fromOldestVtxo.filter((_) => _.txid === vtxo.arkTxId);
|
|
103
|
-
// We want to find all the other
|
|
103
|
+
// We want to find all the other virtual outputs spent by the same transaction to
|
|
104
104
|
// calculate the full amount of the change.
|
|
105
105
|
const allSpent = fromOldestVtxo.filter((v) => v.arkTxId === vtxo.arkTxId);
|
|
106
106
|
const spentAmount = allSpent.reduce((acc, v) => acc + v.value, 0);
|
|
@@ -113,7 +113,7 @@ export async function buildTransactionHistory(vtxos, allBoardingTxs, commitments
|
|
|
113
113
|
}
|
|
114
114
|
else {
|
|
115
115
|
txAmount = spentAmount;
|
|
116
|
-
// TODO: fetch the
|
|
116
|
+
// TODO: fetch the virtual output with /v1/indexer/vtxos?outpoints=<vtxo.arkTxid:0> to know when the tx was made
|
|
117
117
|
txTime = getTxCreatedAt
|
|
118
118
|
? ((await getTxCreatedAt(vtxo.arkTxId)) ??
|
|
119
119
|
vtxo.createdAt.getTime() + 1)
|
|
@@ -130,7 +130,7 @@ export async function buildTransactionHistory(vtxos, allBoardingTxs, commitments
|
|
|
130
130
|
...(assets && { assets }),
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
|
-
// If the
|
|
133
|
+
// If the virtual output is forfeited in a batch and the total sum of forfeited virtual outputs is bigger than the sum of new virtual outputs,
|
|
134
134
|
// it's translated into an exit sent tx
|
|
135
135
|
if (vtxo.settledBy &&
|
|
136
136
|
!commitmentsToIgnore.has(vtxo.settledBy) &&
|
|
@@ -2,7 +2,7 @@ import * as bip68 from "bip68";
|
|
|
2
2
|
import { RawWitness, ScriptNum } from "@scure/btc-signer";
|
|
3
3
|
import { hex } from "@scure/base";
|
|
4
4
|
/**
|
|
5
|
-
* ArkPsbtFieldKey
|
|
5
|
+
* ArkPsbtFieldKey are the available key names for the Arkade PSBT custom fields.
|
|
6
6
|
*/
|
|
7
7
|
export var ArkPsbtFieldKey;
|
|
8
8
|
(function (ArkPsbtFieldKey) {
|
|
@@ -12,8 +12,8 @@ export var ArkPsbtFieldKey;
|
|
|
12
12
|
ArkPsbtFieldKey["ConditionWitness"] = "condition";
|
|
13
13
|
})(ArkPsbtFieldKey || (ArkPsbtFieldKey = {}));
|
|
14
14
|
/**
|
|
15
|
-
* ArkPsbtFieldKeyType is the type of the
|
|
16
|
-
* Every
|
|
15
|
+
* ArkPsbtFieldKeyType is the key type of the Arkade PSBT custom field.
|
|
16
|
+
* Every Arkade PSBT field has key type 222.
|
|
17
17
|
*/
|
|
18
18
|
export const ArkPsbtFieldKeyType = 222;
|
|
19
19
|
/**
|
|
@@ -23,7 +23,7 @@ export class AssetManager extends ReadonlyAssetManager {
|
|
|
23
23
|
* @param params.amount - Amount of asset units to issue
|
|
24
24
|
* @param params.controlAssetId - Optional control asset ID (for reissuable assets)
|
|
25
25
|
* @param params.metadata - Optional metadata to attach to the asset
|
|
26
|
-
* @returns Promise resolving to the
|
|
26
|
+
* @returns Promise resolving to the Arkade transaction ID and asset ID
|
|
27
27
|
*
|
|
28
28
|
* @example
|
|
29
29
|
* ```typescript
|
|
@@ -108,7 +108,7 @@ export class AssetManager extends ReadonlyAssetManager {
|
|
|
108
108
|
* @param params - Parameters for asset reissuance
|
|
109
109
|
* @param params.assetId - The asset ID to reissue (control asset ID is resolved via getAssetDetails)
|
|
110
110
|
* @param params.amount - Amount of additional units to issue
|
|
111
|
-
* @returns Promise resolving to the
|
|
111
|
+
* @returns Promise resolving to the Arkade transaction ID
|
|
112
112
|
*
|
|
113
113
|
* @example
|
|
114
114
|
* ```typescript
|
|
@@ -215,7 +215,7 @@ export class AssetManager extends ReadonlyAssetManager {
|
|
|
215
215
|
* @param params - Parameters for burning
|
|
216
216
|
* @param params.assetId - The asset ID to burn
|
|
217
217
|
* @param params.amount - Amount of units to burn
|
|
218
|
-
* @returns Promise resolving to the
|
|
218
|
+
* @returns Promise resolving to the Arkade transaction ID
|
|
219
219
|
*
|
|
220
220
|
* @example
|
|
221
221
|
* ```typescript
|
|
@@ -233,7 +233,7 @@ export class AssetManager extends ReadonlyAssetManager {
|
|
|
233
233
|
withRecoverable: false,
|
|
234
234
|
});
|
|
235
235
|
const assetChanges = new Map();
|
|
236
|
-
// select
|
|
236
|
+
// select virtual outputs with the asset to burn
|
|
237
237
|
const { selected: assetCoins } = selectCoinsWithAsset(virtualCoins, params.assetId, BigInt(params.amount));
|
|
238
238
|
const selectedCoins = [...assetCoins];
|
|
239
239
|
let totalBtcSelected = 0;
|
package/dist/esm/wallet/batch.js
CHANGED
|
@@ -11,7 +11,7 @@ import { hex } from "@scure/base";
|
|
|
11
11
|
* const handler = wallet.createBatchHandler(intentId, inputs, expectedRecipients, musig2session);
|
|
12
12
|
*
|
|
13
13
|
* const abortController = new AbortController();
|
|
14
|
-
* // Get event stream from
|
|
14
|
+
* // Get event stream from the Arkade provider
|
|
15
15
|
* const eventStream = arkProvider.getEventStream(
|
|
16
16
|
* abortController.signal,
|
|
17
17
|
* ['your-topic-1', 'your-topic-2']
|
|
@@ -96,7 +96,7 @@ export var Batch;
|
|
|
96
96
|
step !== Step.TreeNoncesAggregated) {
|
|
97
97
|
continue;
|
|
98
98
|
}
|
|
99
|
-
// batchIndex 0 =
|
|
99
|
+
// batchIndex 0 = virtual output tree, batchIndex 1 = connector tree
|
|
100
100
|
if (event.batchIndex === 0) {
|
|
101
101
|
flatVtxoTree.push(event.chunk);
|
|
102
102
|
}
|
|
@@ -115,7 +115,7 @@ export var Batch;
|
|
|
115
115
|
if (!vtxoTree) {
|
|
116
116
|
throw new Error("vtxo tree not initialized");
|
|
117
117
|
}
|
|
118
|
-
// push signature to the
|
|
118
|
+
// push signature to the virtual output tree
|
|
119
119
|
const tapKeySig = hex.decode(event.signature);
|
|
120
120
|
vtxoTree.update(event.txid, (tx) => {
|
|
121
121
|
tx.updateInput(0, {
|
|
@@ -131,7 +131,7 @@ export var Batch;
|
|
|
131
131
|
if (step !== Step.BatchStarted) {
|
|
132
132
|
continue;
|
|
133
133
|
}
|
|
134
|
-
// create
|
|
134
|
+
// create virtual output tree from collected chunks
|
|
135
135
|
vtxoTree = TxTree.create(flatVtxoTree);
|
|
136
136
|
const { skip } = await handler.onTreeSigningStarted(event, vtxoTree);
|
|
137
137
|
if (!skip) {
|
|
@@ -153,7 +153,7 @@ export var Batch;
|
|
|
153
153
|
if (step !== Step.TreeNoncesAggregated) {
|
|
154
154
|
continue;
|
|
155
155
|
}
|
|
156
|
-
// Build
|
|
156
|
+
// Build virtual output tree if it hasn't been built yet
|
|
157
157
|
if (!vtxoTree && flatVtxoTree.length > 0) {
|
|
158
158
|
vtxoTree = TxTree.create(flatVtxoTree);
|
|
159
159
|
}
|
|
@@ -8,6 +8,7 @@ import { getNetwork } from '../networks.js';
|
|
|
8
8
|
import { createAssetPacket } from './asset.js';
|
|
9
9
|
import { Extension } from '../extension/index.js';
|
|
10
10
|
export class DelegatorManagerImpl {
|
|
11
|
+
/** Create a delegator manager from the configured provider, Arkade info source, and wallet identity. */
|
|
11
12
|
constructor(delegatorProvider, arkInfoProvider, identity) {
|
|
12
13
|
this.delegatorProvider = delegatorProvider;
|
|
13
14
|
this.arkInfoProvider = arkInfoProvider;
|
|
@@ -24,7 +25,7 @@ export class DelegatorManagerImpl {
|
|
|
24
25
|
// fetch server and delegator info once, shared across all groups
|
|
25
26
|
const arkInfo = await this.arkInfoProvider.getInfo();
|
|
26
27
|
const delegateInfo = await this.delegatorProvider.getDelegateInfo();
|
|
27
|
-
// if explicit delegateAt is provided, delegate all
|
|
28
|
+
// if explicit delegateAt is provided, delegate all virtual outputs at once without sorting
|
|
28
29
|
if (delegateAt) {
|
|
29
30
|
try {
|
|
30
31
|
await delegate(this.identity, this.delegatorProvider, arkInfo, delegateInfo, vtxos, destinationScript, delegateAt);
|
|
@@ -34,7 +35,7 @@ export class DelegatorManagerImpl {
|
|
|
34
35
|
}
|
|
35
36
|
return { delegated: vtxos, failed: [] };
|
|
36
37
|
}
|
|
37
|
-
// if no explicit delegateAt is provided, sort
|
|
38
|
+
// if no explicit delegateAt is provided, sort virtual outputs by expiry and delegate in groups of the same expiry day
|
|
38
39
|
const groupByExpiry = new Map();
|
|
39
40
|
let recoverableVtxos = [];
|
|
40
41
|
for (const vtxo of vtxos) {
|
|
@@ -51,7 +52,7 @@ export class DelegatorManagerImpl {
|
|
|
51
52
|
vtxo,
|
|
52
53
|
]);
|
|
53
54
|
}
|
|
54
|
-
// if no groups, it means we only need to delegate the recoverable
|
|
55
|
+
// if no groups, it means we only need to delegate the recoverable virtual outputs
|
|
55
56
|
if (groupByExpiry.size === 0) {
|
|
56
57
|
try {
|
|
57
58
|
await delegate(this.identity, this.delegatorProvider, arkInfo, delegateInfo, recoverableVtxos, destinationScript, delegateAt);
|
|
@@ -64,7 +65,7 @@ export class DelegatorManagerImpl {
|
|
|
64
65
|
}
|
|
65
66
|
return { delegated: recoverableVtxos, failed: [] };
|
|
66
67
|
}
|
|
67
|
-
// search for the earliest group, include recoverable
|
|
68
|
+
// search for the earliest group, include recoverable virtual outputs into it
|
|
68
69
|
const earliestGroup = Math.min(...groupByExpiry.keys());
|
|
69
70
|
groupByExpiry.set(earliestGroup, [
|
|
70
71
|
...(groupByExpiry.get(earliestGroup) ?? []),
|
|
@@ -86,9 +87,9 @@ export class DelegatorManagerImpl {
|
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
/**
|
|
89
|
-
* Delegates virtual
|
|
90
|
-
* on behalf of the wallet.
|
|
91
|
-
* @param vtxos - Array of extended virtual
|
|
90
|
+
* Delegates virtual outputs to a delegation service, allowing them to manage their renewal
|
|
91
|
+
* on behalf of the wallet owner.
|
|
92
|
+
* @param vtxos - Array of extended virtual outputs to delegate. Must not be empty.
|
|
92
93
|
* @param delegateAt - Optional Date specifying when the delegation
|
|
93
94
|
* should occur. If not provided, defaults to 12 hours before the earliest
|
|
94
95
|
* expiry time of the provided vtxos.
|
|
@@ -105,7 +106,7 @@ async function delegate(identity, delegatorProvider, arkInfo, delegateInfo, vtxo
|
|
|
105
106
|
.filter((coin) => !isRecoverable(coin) && coin.virtualStatus.batchExpiry)
|
|
106
107
|
.reduce((min, coin) => Math.min(min, coin.virtualStatus.batchExpiry), Number.MAX_SAFE_INTEGER);
|
|
107
108
|
if (!expiryTimestamp || expiryTimestamp === Number.MAX_SAFE_INTEGER) {
|
|
108
|
-
// if no expiry (recoverable
|
|
109
|
+
// if no expiry (recoverable virtual outputs), delegate 1 minute from now
|
|
109
110
|
delegateAt = new Date(Date.now() + 1 * 60 * 1000);
|
|
110
111
|
}
|
|
111
112
|
else {
|
|
@@ -60,7 +60,7 @@ export function defineExpoBackgroundTask(taskName, options) {
|
|
|
60
60
|
const indexerProvider = new ExpoIndexerProvider(config.arkServerUrl);
|
|
61
61
|
const arkProvider = new ExpoArkProvider(config.arkServerUrl);
|
|
62
62
|
// Reconstruct default offchainTapscript as fallback
|
|
63
|
-
// for
|
|
63
|
+
// for virtual outputs not associated with a contract.
|
|
64
64
|
const offchainTapscript = new DefaultVtxo.Script({
|
|
65
65
|
pubKey: hex.decode(config.pubkeyHex),
|
|
66
66
|
serverPubKey: hex.decode(config.serverPubKeyHex),
|
|
@@ -104,8 +104,8 @@ export function defineExpoBackgroundTask(taskName, options) {
|
|
|
104
104
|
/**
|
|
105
105
|
* Activate the OS-level background task scheduler.
|
|
106
106
|
*
|
|
107
|
-
* Call this after
|
|
108
|
-
*
|
|
107
|
+
* Call this after @see defineExpoBackgroundTask (typically inside
|
|
108
|
+
* @see ExpoWallet.setup or in a React component after wallet init).
|
|
109
109
|
*
|
|
110
110
|
* @param minimumInterval - Minimum interval in minutes (default 15).
|
|
111
111
|
*/
|
|
@@ -8,7 +8,7 @@ import { DefaultVtxo } from '../../script/default.js';
|
|
|
8
8
|
/**
|
|
9
9
|
* Expo/React Native wallet with built-in background task processing.
|
|
10
10
|
*
|
|
11
|
-
* Wraps a standard
|
|
11
|
+
* Wraps a standard @see Wallet and adds a lightweight task queue
|
|
12
12
|
* for keeping contract/VTXO state fresh while the app is active and
|
|
13
13
|
* across Expo BackgroundTask wakes.
|
|
14
14
|
*
|
|
@@ -18,10 +18,10 @@ import { DefaultVtxo } from '../../script/default.js';
|
|
|
18
18
|
* import { AsyncStorageTaskQueue } from "@arkade-os/sdk/worker/expo";
|
|
19
19
|
*
|
|
20
20
|
* const wallet = await ExpoWallet.setup({
|
|
21
|
-
* identity:
|
|
22
|
-
* arkServerUrl,
|
|
23
|
-
* esploraUrl,
|
|
24
|
-
* storage: {
|
|
21
|
+
* identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
22
|
+
* arkServerUrl: 'https://arkade.computer',
|
|
23
|
+
* esploraUrl: 'https://mempool.space/api',
|
|
24
|
+
* storage: { ... },
|
|
25
25
|
* background: {
|
|
26
26
|
* taskName: "ark-background-poll",
|
|
27
27
|
* taskQueue: new AsyncStorageTaskQueue(AsyncStorage),
|
|
@@ -50,8 +50,8 @@ export class ExpoWallet {
|
|
|
50
50
|
/**
|
|
51
51
|
* Create an ExpoWallet with background task support.
|
|
52
52
|
*
|
|
53
|
-
* 1. Creates the inner
|
|
54
|
-
* 2. Wires up processors (defaults to
|
|
53
|
+
* 1. Creates the inner @see Wallet via `Wallet.create()`.
|
|
54
|
+
* 2. Wires up processors (defaults to @see contractPollProcessor).
|
|
55
55
|
* 3. Persists background config for the background handler (if the queue supports it).
|
|
56
56
|
* 4. Seeds the task queue with a `contract-poll` task.
|
|
57
57
|
* 5. Registers the background task with the OS scheduler (if `minimumBackgroundInterval` is set).
|
package/dist/esm/wallet/index.js
CHANGED
|
@@ -1,14 +1,48 @@
|
|
|
1
|
+
/** Wallet transaction direction. */
|
|
1
2
|
export var TxType;
|
|
2
3
|
(function (TxType) {
|
|
3
4
|
TxType["TxSent"] = "SENT";
|
|
4
5
|
TxType["TxReceived"] = "RECEIVED";
|
|
5
6
|
})(TxType || (TxType = {}));
|
|
7
|
+
/**
|
|
8
|
+
* Return whether a virtual output is still spendable.
|
|
9
|
+
*
|
|
10
|
+
* @param vtxo - virtual output to inspect
|
|
11
|
+
* @returns `true` when the virtual output is not marked as spent
|
|
12
|
+
*
|
|
13
|
+
* @see isRecoverable
|
|
14
|
+
* @see isExpired
|
|
15
|
+
*/
|
|
6
16
|
export function isSpendable(vtxo) {
|
|
7
17
|
return !vtxo.isSpent;
|
|
8
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Return whether a virtual output is recoverable.
|
|
21
|
+
*
|
|
22
|
+
* @param vtxo - virtual output to inspect
|
|
23
|
+
* @returns `true` when the virtual output is swept but still spendable
|
|
24
|
+
*
|
|
25
|
+
* @remarks
|
|
26
|
+
* Recoverable virtual outputs are typically re-settled into fresh virtual outputs by the virtual output manager.
|
|
27
|
+
*
|
|
28
|
+
* @see isSpendable
|
|
29
|
+
* @see isExpired
|
|
30
|
+
*/
|
|
9
31
|
export function isRecoverable(vtxo) {
|
|
10
32
|
return vtxo.virtualStatus.state === "swept" && isSpendable(vtxo);
|
|
11
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Return whether a virtual output should be treated as expired.
|
|
36
|
+
*
|
|
37
|
+
* @param vtxo - virtual output to inspect
|
|
38
|
+
* @returns `true` when the virtual output is swept or its batch expiry has passed
|
|
39
|
+
* @remarks
|
|
40
|
+
* On regtest-like environments the upstream expiry value may be expressed as a block
|
|
41
|
+
* height instead of a timestamp. This helper intentionally ignores obviously non-time
|
|
42
|
+
* values to avoid false positives.
|
|
43
|
+
*
|
|
44
|
+
* @see VirtualStatus.batchExpiry
|
|
45
|
+
*/
|
|
12
46
|
export function isExpired(vtxo) {
|
|
13
47
|
if (vtxo.virtualStatus.state === "swept")
|
|
14
48
|
return true; // swept by server = expired
|
|
@@ -23,6 +57,15 @@ export function isExpired(vtxo) {
|
|
|
23
57
|
return false;
|
|
24
58
|
return expiry <= Date.now();
|
|
25
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Return whether a virtual output is below the dust threshold.
|
|
62
|
+
*
|
|
63
|
+
* @param vtxo - virtual output to inspect
|
|
64
|
+
* @param dust - dust threshold in satoshis
|
|
65
|
+
* @returns `true` when the virtual output value is below `dust`
|
|
66
|
+
*
|
|
67
|
+
* @see isRecoverable
|
|
68
|
+
*/
|
|
26
69
|
export function isSubdust(vtxo, dust) {
|
|
27
70
|
return vtxo.value < dust;
|
|
28
71
|
}
|