@gvnrdao/dh-sdk 0.0.307 → 0.0.308
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/browser/dist/browser.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +468 -129
- package/dist/index.mjs +393 -51
- package/dist/modules/diamond-hands-sdk.d.ts +62 -17
- package/dist/utils/stale-spend-invalidate-message.d.ts +46 -0
- package/dist/utils/withdrawal-reconciliation.utils.d.ts +3 -2
- package/package.json +3 -3
|
@@ -546,7 +546,7 @@ export declare class DiamondHandsSDK {
|
|
|
546
546
|
* been broadcast to the Bitcoin network. An empty array means no pending withdrawals.
|
|
547
547
|
*
|
|
548
548
|
* @param positionId - Position identifier
|
|
549
|
-
* @returns Array of pending withdrawals, each including a pre-computed utxoKey
|
|
549
|
+
* @returns Array of pending withdrawals, each including a pre-computed utxoKey (the key recoverStaleSpend and the admin clearing path operate on)
|
|
550
550
|
*/
|
|
551
551
|
getPendingWithdrawals(positionId: string): Promise<Array<{
|
|
552
552
|
txid: string;
|
|
@@ -564,11 +564,15 @@ export declare class DiamondHandsSDK {
|
|
|
564
564
|
* broadcast happened. Callers MUST use the returned `status` to decide what
|
|
565
565
|
* to offer:
|
|
566
566
|
* - EXECUTABLE → offer Execute (the only status that may).
|
|
567
|
-
* - EXECUTED → auto-clear; `spendingTxid` is the completion proof
|
|
568
|
-
*
|
|
567
|
+
* - EXECUTED → auto-clear; `spendingTxid` is the completion proof —
|
|
568
|
+
* feed it to recoverStaleSpend to clear the reservation.
|
|
569
|
+
* - SPENT_MISMATCH → unexecutable; recoverStaleSpend with the spending txid
|
|
570
|
+
* as invalidator clears the reservation.
|
|
569
571
|
* - CORRUPT → authorization contradicts the chain (e.g. declared
|
|
570
|
-
* satoshis ≠ real output value);
|
|
571
|
-
*
|
|
572
|
+
* satoshis ≠ real output value); Execute can only die at
|
|
573
|
+
* the signer guard, and no borrower-side cancel exists
|
|
574
|
+
* (audit #62210) — clearing needs the AdminModule
|
|
575
|
+
* cancelStaleSpendByAdmin operator override.
|
|
572
576
|
* - UNFUNDED → funding tx unknown/unconfirmed; wait.
|
|
573
577
|
*
|
|
574
578
|
* @param opts.esploraBaseUrl Esplora API base (e.g. the api proxy
|
|
@@ -578,18 +582,6 @@ export declare class DiamondHandsSDK {
|
|
|
578
582
|
reconcilePendingWithdrawals(positionId: string, opts?: {
|
|
579
583
|
esploraBaseUrl?: string;
|
|
580
584
|
}): Promise<Array<ReconciledWithdrawal<Awaited<ReturnType<DiamondHandsSDK["getPendingWithdrawals"]>>[number]>>>;
|
|
581
|
-
/**
|
|
582
|
-
* Cancel a pending BTC withdrawal
|
|
583
|
-
*
|
|
584
|
-
* Removes a stale authorized spend from BTCSpendAuthorizer, unlocking the UTXO
|
|
585
|
-
* and allowing the borrower to retry the withdrawal from scratch.
|
|
586
|
-
* Only the position's borrower may call this — requires a connected signer.
|
|
587
|
-
*
|
|
588
|
-
* @param positionId - Position identifier
|
|
589
|
-
* @param txid - Bitcoin UTXO transaction ID (from getPendingWithdrawals)
|
|
590
|
-
* @param vout - Output index (from getPendingWithdrawals)
|
|
591
|
-
* @returns Transaction hash of the cancellation EVM transaction
|
|
592
|
-
*/
|
|
593
585
|
/**
|
|
594
586
|
* Recover (clear) a stale BTC reservation via LIT-attested proof.
|
|
595
587
|
*
|
|
@@ -639,6 +631,59 @@ export declare class DiamondHandsSDK {
|
|
|
639
631
|
error?: string;
|
|
640
632
|
failedStep?: "attestation" | "submit" | "config";
|
|
641
633
|
}>;
|
|
634
|
+
/**
|
|
635
|
+
* Sign + broadcast the PKP vault→vault self-spend that invalidates one
|
|
636
|
+
* stuck authorized outpoint (btc-utxo-invalidator 1.0.0). Once the returned
|
|
637
|
+
* `invalidatorTxid` reaches >=6 Bitcoin confirmations, `recoverStaleSpend`
|
|
638
|
+
* clears the on-chain reservation — the trustless replacement for the
|
|
639
|
+
* AdminModule cancelStaleSpendByAdmin path on unspent stuck/corrupt
|
|
640
|
+
* reservations (incident 2026-07-22). Requires the borrower (or position
|
|
641
|
+
* delegate) signer; the signature is scoped to exactly this outpoint.
|
|
642
|
+
*/
|
|
643
|
+
invalidateStaleSpend(params: {
|
|
644
|
+
positionId: string;
|
|
645
|
+
utxoTxid: string;
|
|
646
|
+
utxoVout: number;
|
|
647
|
+
rpcUrl?: string;
|
|
648
|
+
}): Promise<{
|
|
649
|
+
success: boolean;
|
|
650
|
+
alreadySpent?: {
|
|
651
|
+
spendingTxid: string;
|
|
652
|
+
};
|
|
653
|
+
invalidatorTxid?: string;
|
|
654
|
+
invalidatorAmount?: number;
|
|
655
|
+
networkFee?: number;
|
|
656
|
+
/** True when the on-chain record's declared value ≠ the real output (corrupt-record recovery). */
|
|
657
|
+
valueMismatch?: boolean;
|
|
658
|
+
error?: string;
|
|
659
|
+
failedStep?: string;
|
|
660
|
+
}>;
|
|
661
|
+
/**
|
|
662
|
+
* Resumable, stateless clearing state machine for one stuck reservation —
|
|
663
|
+
* Bitcoin itself is the state store, so every call either advances the flow
|
|
664
|
+
* one step or reports where it stands (survives reloads and the multi-day
|
|
665
|
+
* 6-confirmation wait; no internal polling).
|
|
666
|
+
*
|
|
667
|
+
* (a) reservation gone → phase "cleared"
|
|
668
|
+
* (b) outpoint spent, >=6 confs → recoverStaleSpend → "cleared"/"failed"
|
|
669
|
+
* outpoint spent, <6 confs → "awaiting-confirmations" (x/6)
|
|
670
|
+
* (c) outpoint unspent → invalidateStaleSpend → "invalidator-broadcast"
|
|
671
|
+
*/
|
|
672
|
+
clearStuckReservation(params: {
|
|
673
|
+
positionId: string;
|
|
674
|
+
utxoTxid: string;
|
|
675
|
+
utxoVout: number;
|
|
676
|
+
esploraBaseUrl?: string;
|
|
677
|
+
}): Promise<{
|
|
678
|
+
phase: "cleared" | "awaiting-confirmations" | "invalidator-broadcast" | "failed";
|
|
679
|
+
invalidatorTxid?: string;
|
|
680
|
+
confirmations?: number;
|
|
681
|
+
required?: number;
|
|
682
|
+
transactionHash?: string;
|
|
683
|
+
classification?: string;
|
|
684
|
+
valueMismatch?: boolean;
|
|
685
|
+
error?: string;
|
|
686
|
+
}>;
|
|
642
687
|
/**
|
|
643
688
|
* Withdraw BTC and execute transfer (Complete Flow)
|
|
644
689
|
*
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Borrower authorization envelope for the btc-utxo-invalidator Lit Action —
|
|
3
|
+
* the SDK-side mirror of `AuthorizationModule.verifyRecoveryAuthorization`
|
|
4
|
+
* (lit-actions/src/modules/authorization.module.ts:539). Field order and
|
|
5
|
+
* types MUST match byte-for-byte; the action recomputes this hash and
|
|
6
|
+
* EIP-191-recovers the borrower/delegate from it.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: the lit-actions side hashes with ethers v5 `solidityKeccak256`, this
|
|
9
|
+
* side with v6 `solidityPackedKeccak256` — identical packed encoding; the
|
|
10
|
+
* unit test asserts byte-equality of the preimages so drift cannot sneak in.
|
|
11
|
+
*/
|
|
12
|
+
import { type Signer } from "ethers";
|
|
13
|
+
/** Must equal RECOVERY_INVALIDATE_ACTION_STRING in lit-actions constants. */
|
|
14
|
+
export declare const RECOVERY_INVALIDATE_ACTION = "btc-utxo-invalidator";
|
|
15
|
+
export interface InvalidateStaleSpendEnvelope {
|
|
16
|
+
positionId: string;
|
|
17
|
+
utxoTxid: string;
|
|
18
|
+
utxoVout: number;
|
|
19
|
+
/** Quantum-aligned unix seconds bound into the signature. */
|
|
20
|
+
timestamp: number;
|
|
21
|
+
chainId: number;
|
|
22
|
+
action: typeof RECOVERY_INVALIDATE_ACTION;
|
|
23
|
+
signature: string;
|
|
24
|
+
borrowerAddress: string;
|
|
25
|
+
}
|
|
26
|
+
/** The exact packed hash `verifyRecoveryAuthorization` recomputes in-TEE. */
|
|
27
|
+
export declare function buildInvalidateMessageHash(params: {
|
|
28
|
+
positionId: string;
|
|
29
|
+
timestamp: number;
|
|
30
|
+
chainId: number;
|
|
31
|
+
utxoTxid: string;
|
|
32
|
+
utxoVout: number;
|
|
33
|
+
}): string;
|
|
34
|
+
/**
|
|
35
|
+
* Build + sign the invalidate envelope with a quantum-aligned timestamp.
|
|
36
|
+
* The signature is scoped to exactly one (positionId, utxoTxid, utxoVout)
|
|
37
|
+
* recovery on one chain and cannot be replayed as any other authorization
|
|
38
|
+
* (the action string is pinned into the hash).
|
|
39
|
+
*/
|
|
40
|
+
export declare function buildInvalidateStaleSpendEnvelope(params: {
|
|
41
|
+
positionId: string;
|
|
42
|
+
utxoTxid: string;
|
|
43
|
+
utxoVout: number;
|
|
44
|
+
chainId: number;
|
|
45
|
+
signer: Signer;
|
|
46
|
+
}): Promise<InvalidateStaleSpendEnvelope>;
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
* - EXECUTED — outpoint spent by a tx that pays the authorized target →
|
|
17
17
|
* auto-clear, show `spendingTxid` as the completion proof.
|
|
18
18
|
* - SPENT_MISMATCH — outpoint spent but the spending tx pays the target
|
|
19
|
-
* nothing → unexecutable;
|
|
19
|
+
* nothing → unexecutable; recoverStaleSpend clears it.
|
|
20
20
|
* - CORRUPT — authorization contradicts the chain (declared value ≠
|
|
21
21
|
* real output value, targetAmount > real value, or vout
|
|
22
|
-
* out of range) →
|
|
22
|
+
* out of range) → operator recovery (admin clearing path);
|
|
23
|
+
* never Execute.
|
|
23
24
|
* - UNFUNDED — funding tx unknown/unconfirmed → wait; no Execute yet.
|
|
24
25
|
*
|
|
25
26
|
* Esplora `spent: true` claims are only trusted when the spending tx can be
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gvnrdao/dh-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.308",
|
|
4
4
|
"description": "TypeScript SDK for Diamond Hands Protocol - Bitcoin-backed lending with LIT Protocol PKPs",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -82,8 +82,8 @@
|
|
|
82
82
|
},
|
|
83
83
|
"sideEffects": false,
|
|
84
84
|
"dependencies": {
|
|
85
|
-
"@gvnrdao/dh-lit-actions": "0.0.
|
|
86
|
-
"@gvnrdao/dh-lit-ops": "0.0.
|
|
85
|
+
"@gvnrdao/dh-lit-actions": "^0.0.316",
|
|
86
|
+
"@gvnrdao/dh-lit-ops": "^0.0.307",
|
|
87
87
|
"@noble/hashes": "^1.5.0",
|
|
88
88
|
"axios": "^1.17.0",
|
|
89
89
|
"bech32": "^2.0.0",
|