@gvnrdao/dh-sdk 0.0.224 → 0.0.226

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
@@ -42407,25 +42407,25 @@ Error data: ${errorData || "none"}`
42407
42407
  });
42408
42408
  }
42409
42409
  const contractAddresses = this.getContractAddressesOrThrow();
42410
- const positionManagerAddress = contractAddresses.positionManager;
42411
- if (!positionManagerAddress) {
42410
+ const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
42411
+ if (!btcSpendAuthorizerAddress) {
42412
42412
  return [
42413
42413
  {
42414
42414
  success: false,
42415
- error: "PositionManager address not configured"
42415
+ error: "BTCSpendAuthorizer address not configured"
42416
42416
  }
42417
42417
  ];
42418
42418
  }
42419
- const positionManagerAbi = [
42419
+ const btcSpendAuthorizerAbi = [
42420
42420
  "function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
42421
42421
  ];
42422
- const positionManager = new ethers_exports.Contract(
42423
- positionManagerAddress,
42424
- positionManagerAbi,
42422
+ const btcSpendAuthorizer = new ethers_exports.Contract(
42423
+ btcSpendAuthorizerAddress,
42424
+ btcSpendAuthorizerAbi,
42425
42425
  this.getProviderOrThrow()
42426
42426
  );
42427
42427
  const positionIdBytes32 = this.toBytes32(positionId);
42428
- const authorizedSpends = await positionManager["getAuthorizedSpends"](
42428
+ const authorizedSpends = await btcSpendAuthorizer["getAuthorizedSpends"](
42429
42429
  positionIdBytes32
42430
42430
  );
42431
42431
  if (this.config.debug) {
@@ -42447,7 +42447,7 @@ Error data: ${errorData || "none"}`
42447
42447
  positionId,
42448
42448
  utxoIdentifier,
42449
42449
  networkFee,
42450
- destination: spend.destination,
42450
+ destination: spend.targetAddress,
42451
42451
  rpcUrl
42452
42452
  });
42453
42453
  results.push({
@@ -42476,6 +42476,92 @@ Error data: ${errorData || "none"}`
42476
42476
  ];
42477
42477
  }
42478
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
+ }
42479
42565
  /**
42480
42566
  * Withdraw BTC and execute transfer (Complete Flow)
42481
42567
  *
package/dist/index.mjs CHANGED
@@ -42335,25 +42335,25 @@ Error data: ${errorData || "none"}`
42335
42335
  });
42336
42336
  }
42337
42337
  const contractAddresses = this.getContractAddressesOrThrow();
42338
- const positionManagerAddress = contractAddresses.positionManager;
42339
- if (!positionManagerAddress) {
42338
+ const btcSpendAuthorizerAddress = contractAddresses.btcSpendAuthorizer;
42339
+ if (!btcSpendAuthorizerAddress) {
42340
42340
  return [
42341
42341
  {
42342
42342
  success: false,
42343
- error: "PositionManager address not configured"
42343
+ error: "BTCSpendAuthorizer address not configured"
42344
42344
  }
42345
42345
  ];
42346
42346
  }
42347
- const positionManagerAbi = [
42347
+ const btcSpendAuthorizerAbi = [
42348
42348
  "function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
42349
42349
  ];
42350
- const positionManager = new ethers_exports.Contract(
42351
- positionManagerAddress,
42352
- positionManagerAbi,
42350
+ const btcSpendAuthorizer = new ethers_exports.Contract(
42351
+ btcSpendAuthorizerAddress,
42352
+ btcSpendAuthorizerAbi,
42353
42353
  this.getProviderOrThrow()
42354
42354
  );
42355
42355
  const positionIdBytes32 = this.toBytes32(positionId);
42356
- const authorizedSpends = await positionManager["getAuthorizedSpends"](
42356
+ const authorizedSpends = await btcSpendAuthorizer["getAuthorizedSpends"](
42357
42357
  positionIdBytes32
42358
42358
  );
42359
42359
  if (this.config.debug) {
@@ -42375,7 +42375,7 @@ Error data: ${errorData || "none"}`
42375
42375
  positionId,
42376
42376
  utxoIdentifier,
42377
42377
  networkFee,
42378
- destination: spend.destination,
42378
+ destination: spend.targetAddress,
42379
42379
  rpcUrl
42380
42380
  });
42381
42381
  results.push({
@@ -42404,6 +42404,92 @@ Error data: ${errorData || "none"}`
42404
42404
  ];
42405
42405
  }
42406
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
+ }
42407
42493
  /**
42408
42494
  * Withdraw BTC and execute transfer (Complete Flow)
42409
42495
  *
@@ -373,6 +373,41 @@ export declare class DiamondHandsSDK {
373
373
  destination?: string;
374
374
  error?: string;
375
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
+ }>;
376
411
  /**
377
412
  * Withdraw BTC and execute transfer (Complete Flow)
378
413
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gvnrdao/dh-sdk",
3
- "version": "0.0.224",
3
+ "version": "0.0.226",
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.286",
74
- "@gvnrdao/dh-lit-ops": "^0.0.259",
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",