@gvnrdao/dh-sdk 0.0.225 → 0.0.227
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +113 -128
- package/dist/index.mjs +113 -128
- package/dist/modules/diamond-hands-sdk.d.ts +35 -43
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -14325,18 +14325,18 @@ var init_deployment_addresses = __esm({
|
|
|
14325
14325
|
},
|
|
14326
14326
|
upgraded: {
|
|
14327
14327
|
PositionManager: {
|
|
14328
|
-
previousImplementation: "
|
|
14329
|
-
newImplementation: "
|
|
14330
|
-
upgradedAt: "2026-
|
|
14328
|
+
previousImplementation: "0x0e40B4D1708f49319f32d51AF01674c26acACeBF",
|
|
14329
|
+
newImplementation: "0x94096F14f58Cb427B36f2a5aeE24348a26534C74",
|
|
14330
|
+
upgradedAt: "2026-04-30T16:23:00.805Z",
|
|
14331
14331
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14332
14332
|
reason: "Shared upgrade script: PositionManager implementation update"
|
|
14333
14333
|
},
|
|
14334
14334
|
LoanOperationsManagerModule: {
|
|
14335
|
-
previousImplementation: "
|
|
14336
|
-
newImplementation: "
|
|
14337
|
-
upgradedAt: "2026-05-
|
|
14335
|
+
previousImplementation: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
|
|
14336
|
+
newImplementation: "0x8a795b082c002aC07fb43Db0ae8eF8bE653cc4bb",
|
|
14337
|
+
upgradedAt: "2026-05-04T13:22:08.881Z",
|
|
14338
14338
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14339
|
-
reason: "
|
|
14339
|
+
reason: "Add cancelStaleSpend to cancel pending BTC withdrawals"
|
|
14340
14340
|
},
|
|
14341
14341
|
UCDController: {
|
|
14342
14342
|
previousImplementation: "0xB5322F0D4a07d4342FA38137ebD95ac41D1c6036",
|
|
@@ -14395,11 +14395,11 @@ var init_deployment_addresses = __esm({
|
|
|
14395
14395
|
reason: "Shared upgrade script: PositionManagerCoreModule implementation update"
|
|
14396
14396
|
},
|
|
14397
14397
|
CollateralManagerModule: {
|
|
14398
|
-
previousImplementation: "
|
|
14399
|
-
newImplementation: "
|
|
14400
|
-
upgradedAt: "2026-05-
|
|
14398
|
+
previousImplementation: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
|
|
14399
|
+
newImplementation: "0x72D17f489A7Ea57Fb665A340424aB7D04a4910aA",
|
|
14400
|
+
upgradedAt: "2026-05-04T13:22:08.881Z",
|
|
14401
14401
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14402
|
-
reason: "
|
|
14402
|
+
reason: "Add cancelStaleSpend to cancel pending BTC withdrawals"
|
|
14403
14403
|
},
|
|
14404
14404
|
LiquidationManagerModule: {
|
|
14405
14405
|
previousImplementation: "0xf74d5437691df92087170861213e26064358A7fb",
|
|
@@ -14409,11 +14409,11 @@ var init_deployment_addresses = __esm({
|
|
|
14409
14409
|
reason: "Shared upgrade script: LiquidationManagerModule implementation update"
|
|
14410
14410
|
},
|
|
14411
14411
|
BTCSpendAuthorizer: {
|
|
14412
|
-
previousImplementation: "
|
|
14413
|
-
newImplementation: "
|
|
14414
|
-
upgradedAt: "2026-05-
|
|
14412
|
+
previousImplementation: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
|
|
14413
|
+
newImplementation: "0xBA4FAF0b804D72Bc4bdD2827f39DfE9256B5EF4F",
|
|
14414
|
+
upgradedAt: "2026-05-04T13:22:08.881Z",
|
|
14415
14415
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14416
|
-
reason: "
|
|
14416
|
+
reason: "Add cancelStaleSpend + BTCSpendCancelled event"
|
|
14417
14417
|
},
|
|
14418
14418
|
SimplePSMV2: {
|
|
14419
14419
|
previousImplementation: "0xBdEFa375db7F9A498B81bcfdDd14FD16D02ca0BF",
|
|
@@ -14503,23 +14503,23 @@ var init_deployment_addresses = __esm({
|
|
|
14503
14503
|
CIRCUIT_BREAKER_MODULE: "0x3D0B2cAE481821E57BA9CC3807bCC0d0D7F18bd8",
|
|
14504
14504
|
ADMIN_MODULE: "0xAcd1f07915b17CA3727e7fE89BdF618A1545a1ed",
|
|
14505
14505
|
UCD_CONTROLLER_IMPL: "0x2d4d689A70B56b6E0B9F70BffA6265A55173A4A1",
|
|
14506
|
-
LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "
|
|
14506
|
+
LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x8a795b082c002aC07fb43Db0ae8eF8bE653cc4bb",
|
|
14507
14507
|
TERM_MANAGER_MODULE_IMPL: "0xcc3D2dD7aAfaE5DE923dfd53833a40077178dd75",
|
|
14508
14508
|
CIRCUIT_BREAKER_MODULE_IMPL: "0x8e9e10B14E6a91ec271FBEb4FD3fB1FE06b545dD",
|
|
14509
14509
|
ADMIN_MODULE_IMPL: "0x67AE2F872c37f33db9bC631e135432B2845d308b",
|
|
14510
14510
|
POSITION_MANAGER_VIEWS_IMPL: "0xadF8e0F34082a8fC23e727276e0aEf3af183C8Fd",
|
|
14511
|
-
POSITION_MANAGER_IMPL: "
|
|
14511
|
+
POSITION_MANAGER_IMPL: "0x94096F14f58Cb427B36f2a5aeE24348a26534C74",
|
|
14512
14512
|
SIMPLE_PSM_V2: "0x19EcF7BA26e054fd4Ff06009A03070103dbBB058",
|
|
14513
14513
|
SIMPLE_PSM_V2_IMPL: "0x4107104fDF61AACC674f1F168c275f034c8112BF",
|
|
14514
14514
|
UCD_TOKEN_IMPL: "0x155Da00Ee0beb1d9D5BA34Aeb62c9ad4E8227d5D",
|
|
14515
14515
|
POSITION_MANAGER_CORE_MODULE: "0xfFAA39a08887FeFB697eBC8691A8630CbCC33391",
|
|
14516
14516
|
POSITION_MANAGER_CORE_MODULE_IMPL: "0x41168d9BF8e696eBAB05ea539321ac212859d80b",
|
|
14517
14517
|
COLLATERAL_MANAGER_MODULE: "0x967E92c976Fc0fa8268D37D4d6B7245d912aA7dB",
|
|
14518
|
-
COLLATERAL_MANAGER_MODULE_IMPL: "
|
|
14518
|
+
COLLATERAL_MANAGER_MODULE_IMPL: "0x72D17f489A7Ea57Fb665A340424aB7D04a4910aA",
|
|
14519
14519
|
LIQUIDATION_MANAGER_MODULE: "0xC4AB00f39e7ceD812F5C67058C9fa44e15d40e76",
|
|
14520
14520
|
LIQUIDATION_MANAGER_MODULE_IMPL: "0xf74d5437691df92087170861213e26064358A7fb",
|
|
14521
14521
|
BTC_SPEND_AUTHORIZER: "0xd7E9Eb5eE53f1d9ee55Dc162bBC7486bE437B6bD",
|
|
14522
|
-
BTC_SPEND_AUTHORIZER_IMPL: "
|
|
14522
|
+
BTC_SPEND_AUTHORIZER_IMPL: "0xBA4FAF0b804D72Bc4bdD2827f39DfE9256B5EF4F",
|
|
14523
14523
|
UPGRADE_VALIDATOR: "0x592e650edD9bA26ecc407989fdd6F9cdcDeC27A6",
|
|
14524
14524
|
UPGRADE_VALIDATOR_IMPL: "0xEFf189e5872bC7158191eD39d31E745aF2A6FDa7",
|
|
14525
14525
|
BITCOIN_PROVIDER_REGISTRY: "0xbfA0c48B070D0a9A9CD27469AeacFD2d4261cEE2",
|
|
@@ -42387,107 +42387,6 @@ Error data: ${errorData || "none"}`
|
|
|
42387
42387
|
};
|
|
42388
42388
|
}
|
|
42389
42389
|
}
|
|
42390
|
-
/**
|
|
42391
|
-
* Cancel a stale authorized BTC spend whose signing/broadcast step never completed.
|
|
42392
|
-
*
|
|
42393
|
-
* Removes the entry from BTCSpendAuthorizer, restoring the UTXO to the available
|
|
42394
|
-
* balance and allowing the borrower to retry via withdrawBTC() + executeBTCWithdrawal().
|
|
42395
|
-
* Only the position's borrower may call this. Inputs come from getPendingWithdrawals().
|
|
42396
|
-
*
|
|
42397
|
-
* @param positionId - Position identifier
|
|
42398
|
-
* @param txid - Bitcoin UTXO txid (from getPendingWithdrawals)
|
|
42399
|
-
* @param vout - Output index (from getPendingWithdrawals)
|
|
42400
|
-
*/
|
|
42401
|
-
async cancelStaleSpend(positionId, txid, vout) {
|
|
42402
|
-
this.ensureInitialized();
|
|
42403
|
-
try {
|
|
42404
|
-
const utxoKey = ethers_exports.utils.solidityKeccak256(["string", "uint32"], [txid, vout]);
|
|
42405
|
-
const contract = new ethers_exports.Contract(
|
|
42406
|
-
this.getContractAddressesOrThrow().positionManager,
|
|
42407
|
-
["function cancelStaleSpend(bytes32,bytes32) external"],
|
|
42408
|
-
this.getSignerOrThrow()
|
|
42409
|
-
);
|
|
42410
|
-
const tx = await contract["cancelStaleSpend"](
|
|
42411
|
-
this.toBytes32(positionId),
|
|
42412
|
-
utxoKey
|
|
42413
|
-
);
|
|
42414
|
-
const receipt = await tx.wait();
|
|
42415
|
-
return { success: true, transactionHash: receipt.transactionHash };
|
|
42416
|
-
} catch (error) {
|
|
42417
|
-
return {
|
|
42418
|
-
success: false,
|
|
42419
|
-
error: error instanceof Error ? error.message : String(error)
|
|
42420
|
-
};
|
|
42421
|
-
}
|
|
42422
|
-
}
|
|
42423
|
-
/**
|
|
42424
|
-
* Check which authorized BTC withdrawals have not yet been broadcast to Bitcoin.
|
|
42425
|
-
*
|
|
42426
|
-
* `withdrawBTC()` records an authorized spend on-chain but never clears it, even
|
|
42427
|
-
* after execution. This method cross-references each authorized spend against the
|
|
42428
|
-
* Bitcoin network (Esplora /outspend) to determine whether the signing+broadcast
|
|
42429
|
-
* step (`executeBTCWithdrawal`) was actually completed.
|
|
42430
|
-
*
|
|
42431
|
-
* status 'pending' → UTXO still unspent; executeBTCWithdrawal was never called
|
|
42432
|
-
* status 'executed' → UTXO has been spent; withdrawal completed successfully
|
|
42433
|
-
*
|
|
42434
|
-
* @param positionId - Position identifier
|
|
42435
|
-
*/
|
|
42436
|
-
async getPendingWithdrawals(positionId) {
|
|
42437
|
-
this.ensureInitialized();
|
|
42438
|
-
const bitcoinProviderUrl = this.config.bitcoinProviders && this.config.bitcoinProviders.length > 0 ? this.config.bitcoinProviders[0]?.url || "" : "";
|
|
42439
|
-
if (!bitcoinProviderUrl) {
|
|
42440
|
-
throw new Error(
|
|
42441
|
-
"bitcoinProviders not configured in SDK config \u2014 required for UTXO spend check"
|
|
42442
|
-
);
|
|
42443
|
-
}
|
|
42444
|
-
const contractAddresses = this.getContractAddressesOrThrow();
|
|
42445
|
-
const positionManagerAbi = [
|
|
42446
|
-
"function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
|
|
42447
|
-
];
|
|
42448
|
-
const positionManager = new ethers_exports.Contract(
|
|
42449
|
-
contractAddresses.positionManager,
|
|
42450
|
-
positionManagerAbi,
|
|
42451
|
-
this.getProviderOrThrow()
|
|
42452
|
-
);
|
|
42453
|
-
const positionIdBytes32 = this.toBytes32(positionId);
|
|
42454
|
-
const authorizedSpends = await positionManager["getAuthorizedSpends"](
|
|
42455
|
-
positionIdBytes32
|
|
42456
|
-
);
|
|
42457
|
-
const withdrawals = [];
|
|
42458
|
-
for (const spend of authorizedSpends) {
|
|
42459
|
-
let status = "pending";
|
|
42460
|
-
try {
|
|
42461
|
-
const resp = await fetch(
|
|
42462
|
-
`${bitcoinProviderUrl}/tx/${spend.txid}/outspend/${spend.vout}`
|
|
42463
|
-
);
|
|
42464
|
-
if (resp.ok) {
|
|
42465
|
-
const data = await resp.json();
|
|
42466
|
-
status = data.spent === true ? "executed" : "pending";
|
|
42467
|
-
}
|
|
42468
|
-
} catch {
|
|
42469
|
-
if (this.config.debug) {
|
|
42470
|
-
log.warn(`\u26A0\uFE0F Could not check outspend for ${spend.txid}:${spend.vout} \u2014 assuming pending`);
|
|
42471
|
-
}
|
|
42472
|
-
}
|
|
42473
|
-
withdrawals.push({
|
|
42474
|
-
txid: spend.txid,
|
|
42475
|
-
vout: Number(spend.vout),
|
|
42476
|
-
satoshis: BigInt(spend.satoshis.toString()),
|
|
42477
|
-
targetAddress: spend.targetAddress,
|
|
42478
|
-
targetAmount: BigInt(spend.targetAmount.toString()),
|
|
42479
|
-
authorizedAt: Number(spend.authorizedAt),
|
|
42480
|
-
status
|
|
42481
|
-
});
|
|
42482
|
-
}
|
|
42483
|
-
const totalPendingSats = withdrawals.filter((w) => w.status === "pending").reduce((sum, w) => sum + w.satoshis, 0n);
|
|
42484
|
-
return {
|
|
42485
|
-
positionId,
|
|
42486
|
-
withdrawals,
|
|
42487
|
-
hasPending: withdrawals.some((w) => w.status === "pending"),
|
|
42488
|
-
totalPendingSats
|
|
42489
|
-
};
|
|
42490
|
-
}
|
|
42491
42390
|
/**
|
|
42492
42391
|
* Execute pending Bitcoin transfers
|
|
42493
42392
|
*
|
|
@@ -42508,25 +42407,25 @@ Error data: ${errorData || "none"}`
|
|
|
42508
42407
|
});
|
|
42509
42408
|
}
|
|
42510
42409
|
const contractAddresses = this.getContractAddressesOrThrow();
|
|
42511
|
-
const
|
|
42512
|
-
if (!
|
|
42410
|
+
const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
|
|
42411
|
+
if (!btcSpendAuthorizerAddress) {
|
|
42513
42412
|
return [
|
|
42514
42413
|
{
|
|
42515
42414
|
success: false,
|
|
42516
|
-
error: "
|
|
42415
|
+
error: "BTCSpendAuthorizer address not configured"
|
|
42517
42416
|
}
|
|
42518
42417
|
];
|
|
42519
42418
|
}
|
|
42520
|
-
const
|
|
42419
|
+
const btcSpendAuthorizerAbi = [
|
|
42521
42420
|
"function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
|
|
42522
42421
|
];
|
|
42523
|
-
const
|
|
42524
|
-
|
|
42525
|
-
|
|
42422
|
+
const btcSpendAuthorizer = new ethers_exports.Contract(
|
|
42423
|
+
btcSpendAuthorizerAddress,
|
|
42424
|
+
btcSpendAuthorizerAbi,
|
|
42526
42425
|
this.getProviderOrThrow()
|
|
42527
42426
|
);
|
|
42528
42427
|
const positionIdBytes32 = this.toBytes32(positionId);
|
|
42529
|
-
const authorizedSpends = await
|
|
42428
|
+
const authorizedSpends = await btcSpendAuthorizer["getAuthorizedSpends"](
|
|
42530
42429
|
positionIdBytes32
|
|
42531
42430
|
);
|
|
42532
42431
|
if (this.config.debug) {
|
|
@@ -42577,6 +42476,92 @@ Error data: ${errorData || "none"}`
|
|
|
42577
42476
|
];
|
|
42578
42477
|
}
|
|
42579
42478
|
}
|
|
42479
|
+
/**
|
|
42480
|
+
* Get pending BTC withdrawals for a position
|
|
42481
|
+
*
|
|
42482
|
+
* Returns all authorized spends recorded in BTCSpendAuthorizer that have not yet
|
|
42483
|
+
* been broadcast to the Bitcoin network. An empty array means no pending withdrawals.
|
|
42484
|
+
*
|
|
42485
|
+
* @param positionId - Position identifier
|
|
42486
|
+
* @returns Array of pending withdrawals, each including a pre-computed utxoKey for use with cancelPendingWithdrawal
|
|
42487
|
+
*/
|
|
42488
|
+
async getPendingWithdrawals(positionId) {
|
|
42489
|
+
this.ensureInitialized();
|
|
42490
|
+
const contractAddresses = this.getContractAddressesOrThrow();
|
|
42491
|
+
const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
|
|
42492
|
+
if (!btcSpendAuthorizerAddress) {
|
|
42493
|
+
throw new SDKError({
|
|
42494
|
+
code: "SDK_CONTRACT_ADDRESSES_NOT_CONFIGURED",
|
|
42495
|
+
message: "BTCSpendAuthorizer address not configured",
|
|
42496
|
+
category: "CONFIGURATION" /* CONFIGURATION */,
|
|
42497
|
+
severity: "HIGH" /* HIGH */,
|
|
42498
|
+
originalError: new Error("BTCSpendAuthorizer address not configured")
|
|
42499
|
+
});
|
|
42500
|
+
}
|
|
42501
|
+
const abi = [
|
|
42502
|
+
"function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
|
|
42503
|
+
];
|
|
42504
|
+
const contract = new ethers_exports.Contract(
|
|
42505
|
+
btcSpendAuthorizerAddress,
|
|
42506
|
+
abi,
|
|
42507
|
+
this.getProviderOrThrow()
|
|
42508
|
+
);
|
|
42509
|
+
const positionIdBytes32 = this.toBytes32(positionId);
|
|
42510
|
+
const raw = await contract["getAuthorizedSpends"](positionIdBytes32);
|
|
42511
|
+
return raw.map((spend) => ({
|
|
42512
|
+
txid: spend.txid,
|
|
42513
|
+
vout: Number(spend.vout),
|
|
42514
|
+
satoshis: Number(spend.satoshis),
|
|
42515
|
+
targetAddress: spend.targetAddress,
|
|
42516
|
+
targetAmount: Number(spend.targetAmount),
|
|
42517
|
+
authorizedAt: Number(spend.authorizedAt),
|
|
42518
|
+
utxoKey: ethers_exports.utils.solidityKeccak256(
|
|
42519
|
+
["string", "uint32"],
|
|
42520
|
+
[spend.txid, Number(spend.vout)]
|
|
42521
|
+
)
|
|
42522
|
+
}));
|
|
42523
|
+
}
|
|
42524
|
+
/**
|
|
42525
|
+
* Cancel a pending BTC withdrawal
|
|
42526
|
+
*
|
|
42527
|
+
* Removes a stale authorized spend from BTCSpendAuthorizer, unlocking the UTXO
|
|
42528
|
+
* and allowing the borrower to retry the withdrawal from scratch.
|
|
42529
|
+
* Only the position's borrower may call this — requires a connected signer.
|
|
42530
|
+
*
|
|
42531
|
+
* @param positionId - Position identifier
|
|
42532
|
+
* @param txid - Bitcoin UTXO transaction ID (from getPendingWithdrawals)
|
|
42533
|
+
* @param vout - Output index (from getPendingWithdrawals)
|
|
42534
|
+
* @returns Transaction hash of the cancellation EVM transaction
|
|
42535
|
+
*/
|
|
42536
|
+
async cancelPendingWithdrawal(positionId, txid, vout) {
|
|
42537
|
+
this.ensureInitialized();
|
|
42538
|
+
try {
|
|
42539
|
+
const signer = this.getSignerOrThrow();
|
|
42540
|
+
const contractAddresses = this.getContractAddressesOrThrow();
|
|
42541
|
+
const positionManagerAddress = contractAddresses.positionManager;
|
|
42542
|
+
if (!positionManagerAddress) {
|
|
42543
|
+
return { success: false, error: "PositionManager address not configured" };
|
|
42544
|
+
}
|
|
42545
|
+
const utxoKey = ethers_exports.utils.solidityKeccak256(
|
|
42546
|
+
["string", "uint32"],
|
|
42547
|
+
[txid, vout]
|
|
42548
|
+
);
|
|
42549
|
+
const positionManager = new ethers_exports.Contract(
|
|
42550
|
+
positionManagerAddress,
|
|
42551
|
+
["function cancelStaleSpend(bytes32 positionId, bytes32 utxoKey) external"],
|
|
42552
|
+
signer
|
|
42553
|
+
);
|
|
42554
|
+
const positionIdBytes32 = this.toBytes32(positionId);
|
|
42555
|
+
const tx = await positionManager["cancelStaleSpend"](positionIdBytes32, utxoKey);
|
|
42556
|
+
const receipt = await tx.wait();
|
|
42557
|
+
return { success: true, transactionHash: receipt.transactionHash };
|
|
42558
|
+
} catch (error) {
|
|
42559
|
+
return {
|
|
42560
|
+
success: false,
|
|
42561
|
+
error: error instanceof Error ? error.message : String(error)
|
|
42562
|
+
};
|
|
42563
|
+
}
|
|
42564
|
+
}
|
|
42580
42565
|
/**
|
|
42581
42566
|
* Withdraw BTC and execute transfer (Complete Flow)
|
|
42582
42567
|
*
|
package/dist/index.mjs
CHANGED
|
@@ -14331,18 +14331,18 @@ var init_deployment_addresses = __esm({
|
|
|
14331
14331
|
},
|
|
14332
14332
|
upgraded: {
|
|
14333
14333
|
PositionManager: {
|
|
14334
|
-
previousImplementation: "
|
|
14335
|
-
newImplementation: "
|
|
14336
|
-
upgradedAt: "2026-
|
|
14334
|
+
previousImplementation: "0x0e40B4D1708f49319f32d51AF01674c26acACeBF",
|
|
14335
|
+
newImplementation: "0x94096F14f58Cb427B36f2a5aeE24348a26534C74",
|
|
14336
|
+
upgradedAt: "2026-04-30T16:23:00.805Z",
|
|
14337
14337
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14338
14338
|
reason: "Shared upgrade script: PositionManager implementation update"
|
|
14339
14339
|
},
|
|
14340
14340
|
LoanOperationsManagerModule: {
|
|
14341
|
-
previousImplementation: "
|
|
14342
|
-
newImplementation: "
|
|
14343
|
-
upgradedAt: "2026-05-
|
|
14341
|
+
previousImplementation: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
|
|
14342
|
+
newImplementation: "0x8a795b082c002aC07fb43Db0ae8eF8bE653cc4bb",
|
|
14343
|
+
upgradedAt: "2026-05-04T13:22:08.881Z",
|
|
14344
14344
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14345
|
-
reason: "
|
|
14345
|
+
reason: "Add cancelStaleSpend to cancel pending BTC withdrawals"
|
|
14346
14346
|
},
|
|
14347
14347
|
UCDController: {
|
|
14348
14348
|
previousImplementation: "0xB5322F0D4a07d4342FA38137ebD95ac41D1c6036",
|
|
@@ -14401,11 +14401,11 @@ var init_deployment_addresses = __esm({
|
|
|
14401
14401
|
reason: "Shared upgrade script: PositionManagerCoreModule implementation update"
|
|
14402
14402
|
},
|
|
14403
14403
|
CollateralManagerModule: {
|
|
14404
|
-
previousImplementation: "
|
|
14405
|
-
newImplementation: "
|
|
14406
|
-
upgradedAt: "2026-05-
|
|
14404
|
+
previousImplementation: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
|
|
14405
|
+
newImplementation: "0x72D17f489A7Ea57Fb665A340424aB7D04a4910aA",
|
|
14406
|
+
upgradedAt: "2026-05-04T13:22:08.881Z",
|
|
14407
14407
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14408
|
-
reason: "
|
|
14408
|
+
reason: "Add cancelStaleSpend to cancel pending BTC withdrawals"
|
|
14409
14409
|
},
|
|
14410
14410
|
LiquidationManagerModule: {
|
|
14411
14411
|
previousImplementation: "0xf74d5437691df92087170861213e26064358A7fb",
|
|
@@ -14415,11 +14415,11 @@ var init_deployment_addresses = __esm({
|
|
|
14415
14415
|
reason: "Shared upgrade script: LiquidationManagerModule implementation update"
|
|
14416
14416
|
},
|
|
14417
14417
|
BTCSpendAuthorizer: {
|
|
14418
|
-
previousImplementation: "
|
|
14419
|
-
newImplementation: "
|
|
14420
|
-
upgradedAt: "2026-05-
|
|
14418
|
+
previousImplementation: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
|
|
14419
|
+
newImplementation: "0xBA4FAF0b804D72Bc4bdD2827f39DfE9256B5EF4F",
|
|
14420
|
+
upgradedAt: "2026-05-04T13:22:08.881Z",
|
|
14421
14421
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14422
|
-
reason: "
|
|
14422
|
+
reason: "Add cancelStaleSpend + BTCSpendCancelled event"
|
|
14423
14423
|
},
|
|
14424
14424
|
SimplePSMV2: {
|
|
14425
14425
|
previousImplementation: "0xBdEFa375db7F9A498B81bcfdDd14FD16D02ca0BF",
|
|
@@ -14509,23 +14509,23 @@ var init_deployment_addresses = __esm({
|
|
|
14509
14509
|
CIRCUIT_BREAKER_MODULE: "0x3D0B2cAE481821E57BA9CC3807bCC0d0D7F18bd8",
|
|
14510
14510
|
ADMIN_MODULE: "0xAcd1f07915b17CA3727e7fE89BdF618A1545a1ed",
|
|
14511
14511
|
UCD_CONTROLLER_IMPL: "0x2d4d689A70B56b6E0B9F70BffA6265A55173A4A1",
|
|
14512
|
-
LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "
|
|
14512
|
+
LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x8a795b082c002aC07fb43Db0ae8eF8bE653cc4bb",
|
|
14513
14513
|
TERM_MANAGER_MODULE_IMPL: "0xcc3D2dD7aAfaE5DE923dfd53833a40077178dd75",
|
|
14514
14514
|
CIRCUIT_BREAKER_MODULE_IMPL: "0x8e9e10B14E6a91ec271FBEb4FD3fB1FE06b545dD",
|
|
14515
14515
|
ADMIN_MODULE_IMPL: "0x67AE2F872c37f33db9bC631e135432B2845d308b",
|
|
14516
14516
|
POSITION_MANAGER_VIEWS_IMPL: "0xadF8e0F34082a8fC23e727276e0aEf3af183C8Fd",
|
|
14517
|
-
POSITION_MANAGER_IMPL: "
|
|
14517
|
+
POSITION_MANAGER_IMPL: "0x94096F14f58Cb427B36f2a5aeE24348a26534C74",
|
|
14518
14518
|
SIMPLE_PSM_V2: "0x19EcF7BA26e054fd4Ff06009A03070103dbBB058",
|
|
14519
14519
|
SIMPLE_PSM_V2_IMPL: "0x4107104fDF61AACC674f1F168c275f034c8112BF",
|
|
14520
14520
|
UCD_TOKEN_IMPL: "0x155Da00Ee0beb1d9D5BA34Aeb62c9ad4E8227d5D",
|
|
14521
14521
|
POSITION_MANAGER_CORE_MODULE: "0xfFAA39a08887FeFB697eBC8691A8630CbCC33391",
|
|
14522
14522
|
POSITION_MANAGER_CORE_MODULE_IMPL: "0x41168d9BF8e696eBAB05ea539321ac212859d80b",
|
|
14523
14523
|
COLLATERAL_MANAGER_MODULE: "0x967E92c976Fc0fa8268D37D4d6B7245d912aA7dB",
|
|
14524
|
-
COLLATERAL_MANAGER_MODULE_IMPL: "
|
|
14524
|
+
COLLATERAL_MANAGER_MODULE_IMPL: "0x72D17f489A7Ea57Fb665A340424aB7D04a4910aA",
|
|
14525
14525
|
LIQUIDATION_MANAGER_MODULE: "0xC4AB00f39e7ceD812F5C67058C9fa44e15d40e76",
|
|
14526
14526
|
LIQUIDATION_MANAGER_MODULE_IMPL: "0xf74d5437691df92087170861213e26064358A7fb",
|
|
14527
14527
|
BTC_SPEND_AUTHORIZER: "0xd7E9Eb5eE53f1d9ee55Dc162bBC7486bE437B6bD",
|
|
14528
|
-
BTC_SPEND_AUTHORIZER_IMPL: "
|
|
14528
|
+
BTC_SPEND_AUTHORIZER_IMPL: "0xBA4FAF0b804D72Bc4bdD2827f39DfE9256B5EF4F",
|
|
14529
14529
|
UPGRADE_VALIDATOR: "0x592e650edD9bA26ecc407989fdd6F9cdcDeC27A6",
|
|
14530
14530
|
UPGRADE_VALIDATOR_IMPL: "0xEFf189e5872bC7158191eD39d31E745aF2A6FDa7",
|
|
14531
14531
|
BITCOIN_PROVIDER_REGISTRY: "0xbfA0c48B070D0a9A9CD27469AeacFD2d4261cEE2",
|
|
@@ -42315,107 +42315,6 @@ Error data: ${errorData || "none"}`
|
|
|
42315
42315
|
};
|
|
42316
42316
|
}
|
|
42317
42317
|
}
|
|
42318
|
-
/**
|
|
42319
|
-
* Cancel a stale authorized BTC spend whose signing/broadcast step never completed.
|
|
42320
|
-
*
|
|
42321
|
-
* Removes the entry from BTCSpendAuthorizer, restoring the UTXO to the available
|
|
42322
|
-
* balance and allowing the borrower to retry via withdrawBTC() + executeBTCWithdrawal().
|
|
42323
|
-
* Only the position's borrower may call this. Inputs come from getPendingWithdrawals().
|
|
42324
|
-
*
|
|
42325
|
-
* @param positionId - Position identifier
|
|
42326
|
-
* @param txid - Bitcoin UTXO txid (from getPendingWithdrawals)
|
|
42327
|
-
* @param vout - Output index (from getPendingWithdrawals)
|
|
42328
|
-
*/
|
|
42329
|
-
async cancelStaleSpend(positionId, txid, vout) {
|
|
42330
|
-
this.ensureInitialized();
|
|
42331
|
-
try {
|
|
42332
|
-
const utxoKey = ethers_exports.utils.solidityKeccak256(["string", "uint32"], [txid, vout]);
|
|
42333
|
-
const contract = new ethers_exports.Contract(
|
|
42334
|
-
this.getContractAddressesOrThrow().positionManager,
|
|
42335
|
-
["function cancelStaleSpend(bytes32,bytes32) external"],
|
|
42336
|
-
this.getSignerOrThrow()
|
|
42337
|
-
);
|
|
42338
|
-
const tx = await contract["cancelStaleSpend"](
|
|
42339
|
-
this.toBytes32(positionId),
|
|
42340
|
-
utxoKey
|
|
42341
|
-
);
|
|
42342
|
-
const receipt = await tx.wait();
|
|
42343
|
-
return { success: true, transactionHash: receipt.transactionHash };
|
|
42344
|
-
} catch (error) {
|
|
42345
|
-
return {
|
|
42346
|
-
success: false,
|
|
42347
|
-
error: error instanceof Error ? error.message : String(error)
|
|
42348
|
-
};
|
|
42349
|
-
}
|
|
42350
|
-
}
|
|
42351
|
-
/**
|
|
42352
|
-
* Check which authorized BTC withdrawals have not yet been broadcast to Bitcoin.
|
|
42353
|
-
*
|
|
42354
|
-
* `withdrawBTC()` records an authorized spend on-chain but never clears it, even
|
|
42355
|
-
* after execution. This method cross-references each authorized spend against the
|
|
42356
|
-
* Bitcoin network (Esplora /outspend) to determine whether the signing+broadcast
|
|
42357
|
-
* step (`executeBTCWithdrawal`) was actually completed.
|
|
42358
|
-
*
|
|
42359
|
-
* status 'pending' → UTXO still unspent; executeBTCWithdrawal was never called
|
|
42360
|
-
* status 'executed' → UTXO has been spent; withdrawal completed successfully
|
|
42361
|
-
*
|
|
42362
|
-
* @param positionId - Position identifier
|
|
42363
|
-
*/
|
|
42364
|
-
async getPendingWithdrawals(positionId) {
|
|
42365
|
-
this.ensureInitialized();
|
|
42366
|
-
const bitcoinProviderUrl = this.config.bitcoinProviders && this.config.bitcoinProviders.length > 0 ? this.config.bitcoinProviders[0]?.url || "" : "";
|
|
42367
|
-
if (!bitcoinProviderUrl) {
|
|
42368
|
-
throw new Error(
|
|
42369
|
-
"bitcoinProviders not configured in SDK config \u2014 required for UTXO spend check"
|
|
42370
|
-
);
|
|
42371
|
-
}
|
|
42372
|
-
const contractAddresses = this.getContractAddressesOrThrow();
|
|
42373
|
-
const positionManagerAbi = [
|
|
42374
|
-
"function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
|
|
42375
|
-
];
|
|
42376
|
-
const positionManager = new ethers_exports.Contract(
|
|
42377
|
-
contractAddresses.positionManager,
|
|
42378
|
-
positionManagerAbi,
|
|
42379
|
-
this.getProviderOrThrow()
|
|
42380
|
-
);
|
|
42381
|
-
const positionIdBytes32 = this.toBytes32(positionId);
|
|
42382
|
-
const authorizedSpends = await positionManager["getAuthorizedSpends"](
|
|
42383
|
-
positionIdBytes32
|
|
42384
|
-
);
|
|
42385
|
-
const withdrawals = [];
|
|
42386
|
-
for (const spend of authorizedSpends) {
|
|
42387
|
-
let status = "pending";
|
|
42388
|
-
try {
|
|
42389
|
-
const resp = await fetch(
|
|
42390
|
-
`${bitcoinProviderUrl}/tx/${spend.txid}/outspend/${spend.vout}`
|
|
42391
|
-
);
|
|
42392
|
-
if (resp.ok) {
|
|
42393
|
-
const data = await resp.json();
|
|
42394
|
-
status = data.spent === true ? "executed" : "pending";
|
|
42395
|
-
}
|
|
42396
|
-
} catch {
|
|
42397
|
-
if (this.config.debug) {
|
|
42398
|
-
log.warn(`\u26A0\uFE0F Could not check outspend for ${spend.txid}:${spend.vout} \u2014 assuming pending`);
|
|
42399
|
-
}
|
|
42400
|
-
}
|
|
42401
|
-
withdrawals.push({
|
|
42402
|
-
txid: spend.txid,
|
|
42403
|
-
vout: Number(spend.vout),
|
|
42404
|
-
satoshis: BigInt(spend.satoshis.toString()),
|
|
42405
|
-
targetAddress: spend.targetAddress,
|
|
42406
|
-
targetAmount: BigInt(spend.targetAmount.toString()),
|
|
42407
|
-
authorizedAt: Number(spend.authorizedAt),
|
|
42408
|
-
status
|
|
42409
|
-
});
|
|
42410
|
-
}
|
|
42411
|
-
const totalPendingSats = withdrawals.filter((w) => w.status === "pending").reduce((sum, w) => sum + w.satoshis, 0n);
|
|
42412
|
-
return {
|
|
42413
|
-
positionId,
|
|
42414
|
-
withdrawals,
|
|
42415
|
-
hasPending: withdrawals.some((w) => w.status === "pending"),
|
|
42416
|
-
totalPendingSats
|
|
42417
|
-
};
|
|
42418
|
-
}
|
|
42419
42318
|
/**
|
|
42420
42319
|
* Execute pending Bitcoin transfers
|
|
42421
42320
|
*
|
|
@@ -42436,25 +42335,25 @@ Error data: ${errorData || "none"}`
|
|
|
42436
42335
|
});
|
|
42437
42336
|
}
|
|
42438
42337
|
const contractAddresses = this.getContractAddressesOrThrow();
|
|
42439
|
-
const
|
|
42440
|
-
if (!
|
|
42338
|
+
const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
|
|
42339
|
+
if (!btcSpendAuthorizerAddress) {
|
|
42441
42340
|
return [
|
|
42442
42341
|
{
|
|
42443
42342
|
success: false,
|
|
42444
|
-
error: "
|
|
42343
|
+
error: "BTCSpendAuthorizer address not configured"
|
|
42445
42344
|
}
|
|
42446
42345
|
];
|
|
42447
42346
|
}
|
|
42448
|
-
const
|
|
42347
|
+
const btcSpendAuthorizerAbi = [
|
|
42449
42348
|
"function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
|
|
42450
42349
|
];
|
|
42451
|
-
const
|
|
42452
|
-
|
|
42453
|
-
|
|
42350
|
+
const btcSpendAuthorizer = new ethers_exports.Contract(
|
|
42351
|
+
btcSpendAuthorizerAddress,
|
|
42352
|
+
btcSpendAuthorizerAbi,
|
|
42454
42353
|
this.getProviderOrThrow()
|
|
42455
42354
|
);
|
|
42456
42355
|
const positionIdBytes32 = this.toBytes32(positionId);
|
|
42457
|
-
const authorizedSpends = await
|
|
42356
|
+
const authorizedSpends = await btcSpendAuthorizer["getAuthorizedSpends"](
|
|
42458
42357
|
positionIdBytes32
|
|
42459
42358
|
);
|
|
42460
42359
|
if (this.config.debug) {
|
|
@@ -42505,6 +42404,92 @@ Error data: ${errorData || "none"}`
|
|
|
42505
42404
|
];
|
|
42506
42405
|
}
|
|
42507
42406
|
}
|
|
42407
|
+
/**
|
|
42408
|
+
* Get pending BTC withdrawals for a position
|
|
42409
|
+
*
|
|
42410
|
+
* Returns all authorized spends recorded in BTCSpendAuthorizer that have not yet
|
|
42411
|
+
* been broadcast to the Bitcoin network. An empty array means no pending withdrawals.
|
|
42412
|
+
*
|
|
42413
|
+
* @param positionId - Position identifier
|
|
42414
|
+
* @returns Array of pending withdrawals, each including a pre-computed utxoKey for use with cancelPendingWithdrawal
|
|
42415
|
+
*/
|
|
42416
|
+
async getPendingWithdrawals(positionId) {
|
|
42417
|
+
this.ensureInitialized();
|
|
42418
|
+
const contractAddresses = this.getContractAddressesOrThrow();
|
|
42419
|
+
const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
|
|
42420
|
+
if (!btcSpendAuthorizerAddress) {
|
|
42421
|
+
throw new SDKError({
|
|
42422
|
+
code: "SDK_CONTRACT_ADDRESSES_NOT_CONFIGURED",
|
|
42423
|
+
message: "BTCSpendAuthorizer address not configured",
|
|
42424
|
+
category: "CONFIGURATION" /* CONFIGURATION */,
|
|
42425
|
+
severity: "HIGH" /* HIGH */,
|
|
42426
|
+
originalError: new Error("BTCSpendAuthorizer address not configured")
|
|
42427
|
+
});
|
|
42428
|
+
}
|
|
42429
|
+
const abi = [
|
|
42430
|
+
"function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
|
|
42431
|
+
];
|
|
42432
|
+
const contract = new ethers_exports.Contract(
|
|
42433
|
+
btcSpendAuthorizerAddress,
|
|
42434
|
+
abi,
|
|
42435
|
+
this.getProviderOrThrow()
|
|
42436
|
+
);
|
|
42437
|
+
const positionIdBytes32 = this.toBytes32(positionId);
|
|
42438
|
+
const raw = await contract["getAuthorizedSpends"](positionIdBytes32);
|
|
42439
|
+
return raw.map((spend) => ({
|
|
42440
|
+
txid: spend.txid,
|
|
42441
|
+
vout: Number(spend.vout),
|
|
42442
|
+
satoshis: Number(spend.satoshis),
|
|
42443
|
+
targetAddress: spend.targetAddress,
|
|
42444
|
+
targetAmount: Number(spend.targetAmount),
|
|
42445
|
+
authorizedAt: Number(spend.authorizedAt),
|
|
42446
|
+
utxoKey: ethers_exports.utils.solidityKeccak256(
|
|
42447
|
+
["string", "uint32"],
|
|
42448
|
+
[spend.txid, Number(spend.vout)]
|
|
42449
|
+
)
|
|
42450
|
+
}));
|
|
42451
|
+
}
|
|
42452
|
+
/**
|
|
42453
|
+
* Cancel a pending BTC withdrawal
|
|
42454
|
+
*
|
|
42455
|
+
* Removes a stale authorized spend from BTCSpendAuthorizer, unlocking the UTXO
|
|
42456
|
+
* and allowing the borrower to retry the withdrawal from scratch.
|
|
42457
|
+
* Only the position's borrower may call this — requires a connected signer.
|
|
42458
|
+
*
|
|
42459
|
+
* @param positionId - Position identifier
|
|
42460
|
+
* @param txid - Bitcoin UTXO transaction ID (from getPendingWithdrawals)
|
|
42461
|
+
* @param vout - Output index (from getPendingWithdrawals)
|
|
42462
|
+
* @returns Transaction hash of the cancellation EVM transaction
|
|
42463
|
+
*/
|
|
42464
|
+
async cancelPendingWithdrawal(positionId, txid, vout) {
|
|
42465
|
+
this.ensureInitialized();
|
|
42466
|
+
try {
|
|
42467
|
+
const signer = this.getSignerOrThrow();
|
|
42468
|
+
const contractAddresses = this.getContractAddressesOrThrow();
|
|
42469
|
+
const positionManagerAddress = contractAddresses.positionManager;
|
|
42470
|
+
if (!positionManagerAddress) {
|
|
42471
|
+
return { success: false, error: "PositionManager address not configured" };
|
|
42472
|
+
}
|
|
42473
|
+
const utxoKey = ethers_exports.utils.solidityKeccak256(
|
|
42474
|
+
["string", "uint32"],
|
|
42475
|
+
[txid, vout]
|
|
42476
|
+
);
|
|
42477
|
+
const positionManager = new ethers_exports.Contract(
|
|
42478
|
+
positionManagerAddress,
|
|
42479
|
+
["function cancelStaleSpend(bytes32 positionId, bytes32 utxoKey) external"],
|
|
42480
|
+
signer
|
|
42481
|
+
);
|
|
42482
|
+
const positionIdBytes32 = this.toBytes32(positionId);
|
|
42483
|
+
const tx = await positionManager["cancelStaleSpend"](positionIdBytes32, utxoKey);
|
|
42484
|
+
const receipt = await tx.wait();
|
|
42485
|
+
return { success: true, transactionHash: receipt.transactionHash };
|
|
42486
|
+
} catch (error) {
|
|
42487
|
+
return {
|
|
42488
|
+
success: false,
|
|
42489
|
+
error: error instanceof Error ? error.message : String(error)
|
|
42490
|
+
};
|
|
42491
|
+
}
|
|
42492
|
+
}
|
|
42508
42493
|
/**
|
|
42509
42494
|
* Withdraw BTC and execute transfer (Complete Flow)
|
|
42510
42495
|
*
|
|
@@ -353,49 +353,6 @@ export declare class DiamondHandsSDK {
|
|
|
353
353
|
destination?: string;
|
|
354
354
|
error?: string;
|
|
355
355
|
}>;
|
|
356
|
-
/**
|
|
357
|
-
* Cancel a stale authorized BTC spend whose signing/broadcast step never completed.
|
|
358
|
-
*
|
|
359
|
-
* Removes the entry from BTCSpendAuthorizer, restoring the UTXO to the available
|
|
360
|
-
* balance and allowing the borrower to retry via withdrawBTC() + executeBTCWithdrawal().
|
|
361
|
-
* Only the position's borrower may call this. Inputs come from getPendingWithdrawals().
|
|
362
|
-
*
|
|
363
|
-
* @param positionId - Position identifier
|
|
364
|
-
* @param txid - Bitcoin UTXO txid (from getPendingWithdrawals)
|
|
365
|
-
* @param vout - Output index (from getPendingWithdrawals)
|
|
366
|
-
*/
|
|
367
|
-
cancelStaleSpend(positionId: string, txid: string, vout: number): Promise<{
|
|
368
|
-
success: boolean;
|
|
369
|
-
transactionHash?: string;
|
|
370
|
-
error?: string;
|
|
371
|
-
}>;
|
|
372
|
-
/**
|
|
373
|
-
* Check which authorized BTC withdrawals have not yet been broadcast to Bitcoin.
|
|
374
|
-
*
|
|
375
|
-
* `withdrawBTC()` records an authorized spend on-chain but never clears it, even
|
|
376
|
-
* after execution. This method cross-references each authorized spend against the
|
|
377
|
-
* Bitcoin network (Esplora /outspend) to determine whether the signing+broadcast
|
|
378
|
-
* step (`executeBTCWithdrawal`) was actually completed.
|
|
379
|
-
*
|
|
380
|
-
* status 'pending' → UTXO still unspent; executeBTCWithdrawal was never called
|
|
381
|
-
* status 'executed' → UTXO has been spent; withdrawal completed successfully
|
|
382
|
-
*
|
|
383
|
-
* @param positionId - Position identifier
|
|
384
|
-
*/
|
|
385
|
-
getPendingWithdrawals(positionId: string): Promise<{
|
|
386
|
-
positionId: string;
|
|
387
|
-
withdrawals: Array<{
|
|
388
|
-
txid: string;
|
|
389
|
-
vout: number;
|
|
390
|
-
satoshis: bigint;
|
|
391
|
-
targetAddress: string;
|
|
392
|
-
targetAmount: bigint;
|
|
393
|
-
authorizedAt: number;
|
|
394
|
-
status: "pending" | "executed";
|
|
395
|
-
}>;
|
|
396
|
-
hasPending: boolean;
|
|
397
|
-
totalPendingSats: bigint;
|
|
398
|
-
}>;
|
|
399
356
|
/**
|
|
400
357
|
* Execute pending Bitcoin transfers
|
|
401
358
|
*
|
|
@@ -416,6 +373,41 @@ export declare class DiamondHandsSDK {
|
|
|
416
373
|
destination?: string;
|
|
417
374
|
error?: string;
|
|
418
375
|
}>>;
|
|
376
|
+
/**
|
|
377
|
+
* Get pending BTC withdrawals for a position
|
|
378
|
+
*
|
|
379
|
+
* Returns all authorized spends recorded in BTCSpendAuthorizer that have not yet
|
|
380
|
+
* been broadcast to the Bitcoin network. An empty array means no pending withdrawals.
|
|
381
|
+
*
|
|
382
|
+
* @param positionId - Position identifier
|
|
383
|
+
* @returns Array of pending withdrawals, each including a pre-computed utxoKey for use with cancelPendingWithdrawal
|
|
384
|
+
*/
|
|
385
|
+
getPendingWithdrawals(positionId: string): Promise<Array<{
|
|
386
|
+
txid: string;
|
|
387
|
+
vout: number;
|
|
388
|
+
satoshis: number;
|
|
389
|
+
targetAddress: string;
|
|
390
|
+
targetAmount: number;
|
|
391
|
+
authorizedAt: number;
|
|
392
|
+
utxoKey: string;
|
|
393
|
+
}>>;
|
|
394
|
+
/**
|
|
395
|
+
* Cancel a pending BTC withdrawal
|
|
396
|
+
*
|
|
397
|
+
* Removes a stale authorized spend from BTCSpendAuthorizer, unlocking the UTXO
|
|
398
|
+
* and allowing the borrower to retry the withdrawal from scratch.
|
|
399
|
+
* Only the position's borrower may call this — requires a connected signer.
|
|
400
|
+
*
|
|
401
|
+
* @param positionId - Position identifier
|
|
402
|
+
* @param txid - Bitcoin UTXO transaction ID (from getPendingWithdrawals)
|
|
403
|
+
* @param vout - Output index (from getPendingWithdrawals)
|
|
404
|
+
* @returns Transaction hash of the cancellation EVM transaction
|
|
405
|
+
*/
|
|
406
|
+
cancelPendingWithdrawal(positionId: string, txid: string, vout: number): Promise<{
|
|
407
|
+
success: boolean;
|
|
408
|
+
transactionHash?: string;
|
|
409
|
+
error?: string;
|
|
410
|
+
}>;
|
|
419
411
|
/**
|
|
420
412
|
* Withdraw BTC and execute transfer (Complete Flow)
|
|
421
413
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gvnrdao/dh-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.227",
|
|
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",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"sideEffects": false,
|
|
72
72
|
"dependencies": {
|
|
73
73
|
"@gvnrdao/dh-lit-actions": "^0.0.287",
|
|
74
|
-
"@gvnrdao/dh-lit-ops": "^0.0.
|
|
74
|
+
"@gvnrdao/dh-lit-ops": "^0.0.261",
|
|
75
75
|
"@noble/hashes": "^1.5.0",
|
|
76
76
|
"axios": "^1.15.2",
|
|
77
77
|
"bech32": "^2.0.0",
|