@gvnrdao/dh-sdk 0.0.224 → 0.0.225
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 +118 -17
- package/dist/index.mjs +118 -17
- package/dist/modules/diamond-hands-sdk.d.ts +43 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -14325,16 +14325,16 @@ var init_deployment_addresses = __esm({
|
|
|
14325
14325
|
},
|
|
14326
14326
|
upgraded: {
|
|
14327
14327
|
PositionManager: {
|
|
14328
|
-
previousImplementation: "
|
|
14329
|
-
newImplementation: "
|
|
14330
|
-
upgradedAt: "2026-
|
|
14328
|
+
previousImplementation: "0x94096F14f58Cb427B36f2a5aeE24348a26534C74",
|
|
14329
|
+
newImplementation: "0x45f74eFd06A08040DD69C3059E2edb6966d57518",
|
|
14330
|
+
upgradedAt: "2026-05-04T09:25:00.744Z",
|
|
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-
|
|
14335
|
+
previousImplementation: "0xF79384d5186B6081124a560e181dC5E0Cf0444dD",
|
|
14336
|
+
newImplementation: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
|
|
14337
|
+
upgradedAt: "2026-05-04T08:28:12.942Z",
|
|
14338
14338
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14339
14339
|
reason: "Shared upgrade script: LoanOperationsManagerModule implementation update"
|
|
14340
14340
|
},
|
|
@@ -14395,9 +14395,9 @@ 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-
|
|
14398
|
+
previousImplementation: "0x920e4f52c251B758e351c0d14c4418ad4E5B77ed",
|
|
14399
|
+
newImplementation: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
|
|
14400
|
+
upgradedAt: "2026-05-04T08:26:01.565Z",
|
|
14401
14401
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14402
14402
|
reason: "Shared upgrade script: CollateralManagerModule implementation update"
|
|
14403
14403
|
},
|
|
@@ -14409,9 +14409,9 @@ 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-
|
|
14412
|
+
previousImplementation: "0x605bf1C988bb307AFA07326954D593A71580e99d",
|
|
14413
|
+
newImplementation: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
|
|
14414
|
+
upgradedAt: "2026-05-04T08:13:12.840Z",
|
|
14415
14415
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14416
14416
|
reason: "Shared upgrade script: BTCSpendAuthorizer implementation update"
|
|
14417
14417
|
},
|
|
@@ -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: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
|
|
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: "0x45f74eFd06A08040DD69C3059E2edb6966d57518",
|
|
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: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
|
|
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: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
|
|
14523
14523
|
UPGRADE_VALIDATOR: "0x592e650edD9bA26ecc407989fdd6F9cdcDeC27A6",
|
|
14524
14524
|
UPGRADE_VALIDATOR_IMPL: "0xEFf189e5872bC7158191eD39d31E745aF2A6FDa7",
|
|
14525
14525
|
BITCOIN_PROVIDER_REGISTRY: "0xbfA0c48B070D0a9A9CD27469AeacFD2d4261cEE2",
|
|
@@ -42387,6 +42387,107 @@ 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
|
+
}
|
|
42390
42491
|
/**
|
|
42391
42492
|
* Execute pending Bitcoin transfers
|
|
42392
42493
|
*
|
|
@@ -42447,7 +42548,7 @@ Error data: ${errorData || "none"}`
|
|
|
42447
42548
|
positionId,
|
|
42448
42549
|
utxoIdentifier,
|
|
42449
42550
|
networkFee,
|
|
42450
|
-
destination: spend.
|
|
42551
|
+
destination: spend.targetAddress,
|
|
42451
42552
|
rpcUrl
|
|
42452
42553
|
});
|
|
42453
42554
|
results.push({
|
package/dist/index.mjs
CHANGED
|
@@ -14331,16 +14331,16 @@ var init_deployment_addresses = __esm({
|
|
|
14331
14331
|
},
|
|
14332
14332
|
upgraded: {
|
|
14333
14333
|
PositionManager: {
|
|
14334
|
-
previousImplementation: "
|
|
14335
|
-
newImplementation: "
|
|
14336
|
-
upgradedAt: "2026-
|
|
14334
|
+
previousImplementation: "0x94096F14f58Cb427B36f2a5aeE24348a26534C74",
|
|
14335
|
+
newImplementation: "0x45f74eFd06A08040DD69C3059E2edb6966d57518",
|
|
14336
|
+
upgradedAt: "2026-05-04T09:25:00.744Z",
|
|
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-
|
|
14341
|
+
previousImplementation: "0xF79384d5186B6081124a560e181dC5E0Cf0444dD",
|
|
14342
|
+
newImplementation: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
|
|
14343
|
+
upgradedAt: "2026-05-04T08:28:12.942Z",
|
|
14344
14344
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14345
14345
|
reason: "Shared upgrade script: LoanOperationsManagerModule implementation update"
|
|
14346
14346
|
},
|
|
@@ -14401,9 +14401,9 @@ 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-
|
|
14404
|
+
previousImplementation: "0x920e4f52c251B758e351c0d14c4418ad4E5B77ed",
|
|
14405
|
+
newImplementation: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
|
|
14406
|
+
upgradedAt: "2026-05-04T08:26:01.565Z",
|
|
14407
14407
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14408
14408
|
reason: "Shared upgrade script: CollateralManagerModule implementation update"
|
|
14409
14409
|
},
|
|
@@ -14415,9 +14415,9 @@ 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-
|
|
14418
|
+
previousImplementation: "0x605bf1C988bb307AFA07326954D593A71580e99d",
|
|
14419
|
+
newImplementation: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
|
|
14420
|
+
upgradedAt: "2026-05-04T08:13:12.840Z",
|
|
14421
14421
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
14422
14422
|
reason: "Shared upgrade script: BTCSpendAuthorizer implementation update"
|
|
14423
14423
|
},
|
|
@@ -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: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
|
|
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: "0x45f74eFd06A08040DD69C3059E2edb6966d57518",
|
|
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: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
|
|
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: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
|
|
14529
14529
|
UPGRADE_VALIDATOR: "0x592e650edD9bA26ecc407989fdd6F9cdcDeC27A6",
|
|
14530
14530
|
UPGRADE_VALIDATOR_IMPL: "0xEFf189e5872bC7158191eD39d31E745aF2A6FDa7",
|
|
14531
14531
|
BITCOIN_PROVIDER_REGISTRY: "0xbfA0c48B070D0a9A9CD27469AeacFD2d4261cEE2",
|
|
@@ -42315,6 +42315,107 @@ 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
|
+
}
|
|
42318
42419
|
/**
|
|
42319
42420
|
* Execute pending Bitcoin transfers
|
|
42320
42421
|
*
|
|
@@ -42375,7 +42476,7 @@ Error data: ${errorData || "none"}`
|
|
|
42375
42476
|
positionId,
|
|
42376
42477
|
utxoIdentifier,
|
|
42377
42478
|
networkFee,
|
|
42378
|
-
destination: spend.
|
|
42479
|
+
destination: spend.targetAddress,
|
|
42379
42480
|
rpcUrl
|
|
42380
42481
|
});
|
|
42381
42482
|
results.push({
|
|
@@ -353,6 +353,49 @@ 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
|
+
}>;
|
|
356
399
|
/**
|
|
357
400
|
* Execute pending Bitcoin transfers
|
|
358
401
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gvnrdao/dh-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.225",
|
|
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",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
},
|
|
71
71
|
"sideEffects": false,
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@gvnrdao/dh-lit-actions": "^0.0.
|
|
74
|
-
"@gvnrdao/dh-lit-ops": "^0.0.
|
|
73
|
+
"@gvnrdao/dh-lit-actions": "^0.0.287",
|
|
74
|
+
"@gvnrdao/dh-lit-ops": "^0.0.260",
|
|
75
75
|
"@noble/hashes": "^1.5.0",
|
|
76
76
|
"axios": "^1.15.2",
|
|
77
77
|
"bech32": "^2.0.0",
|