@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 CHANGED
@@ -14325,18 +14325,18 @@ var init_deployment_addresses = __esm({
14325
14325
  },
14326
14326
  upgraded: {
14327
14327
  PositionManager: {
14328
- previousImplementation: "0x94096F14f58Cb427B36f2a5aeE24348a26534C74",
14329
- newImplementation: "0x45f74eFd06A08040DD69C3059E2edb6966d57518",
14330
- upgradedAt: "2026-05-04T09:25:00.744Z",
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: "0xF79384d5186B6081124a560e181dC5E0Cf0444dD",
14336
- newImplementation: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
14337
- upgradedAt: "2026-05-04T08:28:12.942Z",
14335
+ previousImplementation: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
14336
+ newImplementation: "0x8a795b082c002aC07fb43Db0ae8eF8bE653cc4bb",
14337
+ upgradedAt: "2026-05-04T13:22:08.881Z",
14338
14338
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
14339
- reason: "Shared upgrade script: LoanOperationsManagerModule implementation update"
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: "0x920e4f52c251B758e351c0d14c4418ad4E5B77ed",
14399
- newImplementation: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
14400
- upgradedAt: "2026-05-04T08:26:01.565Z",
14398
+ previousImplementation: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
14399
+ newImplementation: "0x72D17f489A7Ea57Fb665A340424aB7D04a4910aA",
14400
+ upgradedAt: "2026-05-04T13:22:08.881Z",
14401
14401
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
14402
- reason: "Shared upgrade script: CollateralManagerModule implementation update"
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: "0x605bf1C988bb307AFA07326954D593A71580e99d",
14413
- newImplementation: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
14414
- upgradedAt: "2026-05-04T08:13:12.840Z",
14412
+ previousImplementation: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
14413
+ newImplementation: "0xBA4FAF0b804D72Bc4bdD2827f39DfE9256B5EF4F",
14414
+ upgradedAt: "2026-05-04T13:22:08.881Z",
14415
14415
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
14416
- reason: "Shared upgrade script: BTCSpendAuthorizer implementation update"
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: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
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: "0x45f74eFd06A08040DD69C3059E2edb6966d57518",
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: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
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: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
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 positionManagerAddress = contractAddresses.positionManager;
42512
- if (!positionManagerAddress) {
42410
+ const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
42411
+ if (!btcSpendAuthorizerAddress) {
42513
42412
  return [
42514
42413
  {
42515
42414
  success: false,
42516
- error: "PositionManager address not configured"
42415
+ error: "BTCSpendAuthorizer address not configured"
42517
42416
  }
42518
42417
  ];
42519
42418
  }
42520
- const positionManagerAbi = [
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 positionManager = new ethers_exports.Contract(
42524
- positionManagerAddress,
42525
- positionManagerAbi,
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 positionManager["getAuthorizedSpends"](
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: "0x94096F14f58Cb427B36f2a5aeE24348a26534C74",
14335
- newImplementation: "0x45f74eFd06A08040DD69C3059E2edb6966d57518",
14336
- upgradedAt: "2026-05-04T09:25:00.744Z",
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: "0xF79384d5186B6081124a560e181dC5E0Cf0444dD",
14342
- newImplementation: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
14343
- upgradedAt: "2026-05-04T08:28:12.942Z",
14341
+ previousImplementation: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
14342
+ newImplementation: "0x8a795b082c002aC07fb43Db0ae8eF8bE653cc4bb",
14343
+ upgradedAt: "2026-05-04T13:22:08.881Z",
14344
14344
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
14345
- reason: "Shared upgrade script: LoanOperationsManagerModule implementation update"
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: "0x920e4f52c251B758e351c0d14c4418ad4E5B77ed",
14405
- newImplementation: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
14406
- upgradedAt: "2026-05-04T08:26:01.565Z",
14404
+ previousImplementation: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
14405
+ newImplementation: "0x72D17f489A7Ea57Fb665A340424aB7D04a4910aA",
14406
+ upgradedAt: "2026-05-04T13:22:08.881Z",
14407
14407
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
14408
- reason: "Shared upgrade script: CollateralManagerModule implementation update"
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: "0x605bf1C988bb307AFA07326954D593A71580e99d",
14419
- newImplementation: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
14420
- upgradedAt: "2026-05-04T08:13:12.840Z",
14418
+ previousImplementation: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
14419
+ newImplementation: "0xBA4FAF0b804D72Bc4bdD2827f39DfE9256B5EF4F",
14420
+ upgradedAt: "2026-05-04T13:22:08.881Z",
14421
14421
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
14422
- reason: "Shared upgrade script: BTCSpendAuthorizer implementation update"
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: "0x2C6740cc4F31Aa90a941686c56FFD37467a3164B",
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: "0x45f74eFd06A08040DD69C3059E2edb6966d57518",
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: "0x1Fa0440d3803FEccB612ac9977DE43Cb4008621D",
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: "0x914b3d46F533798A4EFf0Be318E7731c94bf86B1",
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 positionManagerAddress = contractAddresses.positionManager;
42440
- if (!positionManagerAddress) {
42338
+ const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
42339
+ if (!btcSpendAuthorizerAddress) {
42441
42340
  return [
42442
42341
  {
42443
42342
  success: false,
42444
- error: "PositionManager address not configured"
42343
+ error: "BTCSpendAuthorizer address not configured"
42445
42344
  }
42446
42345
  ];
42447
42346
  }
42448
- const positionManagerAbi = [
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 positionManager = new ethers_exports.Contract(
42452
- positionManagerAddress,
42453
- positionManagerAbi,
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 positionManager["getAuthorizedSpends"](
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.225",
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.260",
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",