@gvnrdao/dh-sdk 0.0.275 → 0.0.276

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.
@@ -73,11 +73,11 @@ var SEPOLIA_DEPLOYMENT = {
73
73
  reason: "Shared upgrade script: PositionManager implementation update"
74
74
  },
75
75
  LoanOperationsManagerModule: {
76
- previousImplementation: "0x291B412c573a4F52410f09D7Ba82eead17D9a674",
77
- newImplementation: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
78
- upgradedAt: "2026-05-17T20:02:12.883Z",
76
+ previousImplementation: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
77
+ newImplementation: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
78
+ upgradedAt: "2026-06-05T10:52:25.179Z",
79
79
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
80
- reason: "Shared upgrade script: LoanOperationsManagerModule implementation update"
80
+ reason: "audit #3 v1.6.0: LoanOperationsManagerModule \u2014 Chainlink feed-staleness gate (maxBtcFeedAgeBorrow / maxBtcFeedAgeLiquidation)"
81
81
  },
82
82
  UCDController: {
83
83
  previousImplementation: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
@@ -282,7 +282,7 @@ var SEPOLIA_DEPLOYMENT = {
282
282
  CIRCUIT_BREAKER_MODULE: "0x3D0B2cAE481821E57BA9CC3807bCC0d0D7F18bd8",
283
283
  ADMIN_MODULE: "0xAcd1f07915b17CA3727e7fE89BdF618A1545a1ed",
284
284
  UCD_CONTROLLER_IMPL: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
285
- LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
285
+ LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
286
286
  TERM_MANAGER_MODULE_IMPL: "0x358d6A7A864853beAA3E157fEB83dCEb1628E8eB",
287
287
  CIRCUIT_BREAKER_MODULE_IMPL: "0xF6277dEF72D51312CC99616B5380f34Eb7603D75",
288
288
  ADMIN_MODULE_IMPL: "0xBBA86246169f81a307Fafff02C1e3D8456aab973",
@@ -40,11 +40,11 @@ var SEPOLIA_DEPLOYMENT = {
40
40
  reason: "Shared upgrade script: PositionManager implementation update"
41
41
  },
42
42
  LoanOperationsManagerModule: {
43
- previousImplementation: "0x291B412c573a4F52410f09D7Ba82eead17D9a674",
44
- newImplementation: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
45
- upgradedAt: "2026-05-17T20:02:12.883Z",
43
+ previousImplementation: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
44
+ newImplementation: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
45
+ upgradedAt: "2026-06-05T10:52:25.179Z",
46
46
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
47
- reason: "Shared upgrade script: LoanOperationsManagerModule implementation update"
47
+ reason: "audit #3 v1.6.0: LoanOperationsManagerModule \u2014 Chainlink feed-staleness gate (maxBtcFeedAgeBorrow / maxBtcFeedAgeLiquidation)"
48
48
  },
49
49
  UCDController: {
50
50
  previousImplementation: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
@@ -249,7 +249,7 @@ var SEPOLIA_DEPLOYMENT = {
249
249
  CIRCUIT_BREAKER_MODULE: "0x3D0B2cAE481821E57BA9CC3807bCC0d0D7F18bd8",
250
250
  ADMIN_MODULE: "0xAcd1f07915b17CA3727e7fE89BdF618A1545a1ed",
251
251
  UCD_CONTROLLER_IMPL: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
252
- LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
252
+ LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
253
253
  TERM_MANAGER_MODULE_IMPL: "0x358d6A7A864853beAA3E157fEB83dCEb1628E8eB",
254
254
  CIRCUIT_BREAKER_MODULE_IMPL: "0xF6277dEF72D51312CC99616B5380f34Eb7603D75",
255
255
  ADMIN_MODULE_IMPL: "0xBBA86246169f81a307Fafff02C1e3D8456aab973",
package/dist/index.js CHANGED
@@ -3683,11 +3683,11 @@ var init_deployment_addresses = __esm({
3683
3683
  reason: "Shared upgrade script: PositionManager implementation update"
3684
3684
  },
3685
3685
  LoanOperationsManagerModule: {
3686
- previousImplementation: "0x291B412c573a4F52410f09D7Ba82eead17D9a674",
3687
- newImplementation: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
3688
- upgradedAt: "2026-05-17T20:02:12.883Z",
3686
+ previousImplementation: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
3687
+ newImplementation: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
3688
+ upgradedAt: "2026-06-05T10:52:25.179Z",
3689
3689
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
3690
- reason: "Shared upgrade script: LoanOperationsManagerModule implementation update"
3690
+ reason: "audit #3 v1.6.0: LoanOperationsManagerModule \u2014 Chainlink feed-staleness gate (maxBtcFeedAgeBorrow / maxBtcFeedAgeLiquidation)"
3691
3691
  },
3692
3692
  UCDController: {
3693
3693
  previousImplementation: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
@@ -3892,7 +3892,7 @@ var init_deployment_addresses = __esm({
3892
3892
  CIRCUIT_BREAKER_MODULE: "0x3D0B2cAE481821E57BA9CC3807bCC0d0D7F18bd8",
3893
3893
  ADMIN_MODULE: "0xAcd1f07915b17CA3727e7fE89BdF618A1545a1ed",
3894
3894
  UCD_CONTROLLER_IMPL: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
3895
- LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
3895
+ LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
3896
3896
  TERM_MANAGER_MODULE_IMPL: "0x358d6A7A864853beAA3E157fEB83dCEb1628E8eB",
3897
3897
  CIRCUIT_BREAKER_MODULE_IMPL: "0xF6277dEF72D51312CC99616B5380f34Eb7603D75",
3898
3898
  ADMIN_MODULE_IMPL: "0xBBA86246169f81a307Fafff02C1e3D8456aab973",
@@ -37202,9 +37202,9 @@ var require_ToPrimitive = __commonJS({
37202
37202
  }
37203
37203
  });
37204
37204
 
37205
- // node_modules/es-abstract/2024/ToString.js
37205
+ // node_modules/es-abstract/2025/ToString.js
37206
37206
  var require_ToString = __commonJS({
37207
- "node_modules/es-abstract/2024/ToString.js"(exports2, module2) {
37207
+ "node_modules/es-abstract/2025/ToString.js"(exports2, module2) {
37208
37208
  "use strict";
37209
37209
  var GetIntrinsic = require_get_intrinsic();
37210
37210
  var $String = GetIntrinsic("%String%");
@@ -37225,13 +37225,20 @@ var require_implementation3 = __commonJS({
37225
37225
  var RequireObjectCoercible = require_RequireObjectCoercible();
37226
37226
  var ToString = require_ToString();
37227
37227
  var callBound = require_call_bound();
37228
+ var safeRegexTester = require_safe_regex_test();
37228
37229
  var $replace = callBound("String.prototype.replace");
37230
+ var $charAt = callBound("String.prototype.charAt");
37231
+ var $slice = callBound("String.prototype.slice");
37229
37232
  var mvsIsWS = /^\s$/.test("\u180E");
37230
37233
  var leftWhitespace = mvsIsWS ? /^[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+/ : /^[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+/;
37231
- var rightWhitespace = mvsIsWS ? /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+$/ : /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+$/;
37234
+ var isWhitespace = safeRegexTester(mvsIsWS ? /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]$/ : /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]$/);
37232
37235
  module2.exports = function trim() {
37233
- var S = ToString(RequireObjectCoercible(this));
37234
- return $replace($replace(S, leftWhitespace, ""), rightWhitespace, "");
37236
+ var S = $replace(ToString(RequireObjectCoercible(this)), leftWhitespace, "");
37237
+ var end = S.length;
37238
+ while (end > 0 && isWhitespace($charAt(S, end - 1))) {
37239
+ end -= 1;
37240
+ }
37241
+ return $slice(S, 0, end);
37235
37242
  };
37236
37243
  }
37237
37244
  });
@@ -37484,6 +37491,22 @@ var require_ToObject = __commonJS({
37484
37491
  }
37485
37492
  });
37486
37493
 
37494
+ // node_modules/es-abstract/2024/ToString.js
37495
+ var require_ToString2 = __commonJS({
37496
+ "node_modules/es-abstract/2024/ToString.js"(exports2, module2) {
37497
+ "use strict";
37498
+ var GetIntrinsic = require_get_intrinsic();
37499
+ var $String = GetIntrinsic("%String%");
37500
+ var $TypeError = require_type();
37501
+ module2.exports = function ToString(argument) {
37502
+ if (typeof argument === "symbol") {
37503
+ throw new $TypeError("Cannot convert a Symbol value to a string");
37504
+ }
37505
+ return $String(argument);
37506
+ };
37507
+ }
37508
+ });
37509
+
37487
37510
  // node_modules/array.prototype.findindex/implementation.js
37488
37511
  var require_implementation4 = __commonJS({
37489
37512
  "node_modules/array.prototype.findindex/implementation.js"(exports2, module2) {
@@ -37494,7 +37517,7 @@ var require_implementation4 = __commonJS({
37494
37517
  var LengthOfArrayLike = require_LengthOfArrayLike();
37495
37518
  var ToBoolean = require_ToBoolean();
37496
37519
  var ToObject = require_ToObject();
37497
- var ToString = require_ToString();
37520
+ var ToString = require_ToString2();
37498
37521
  module2.exports = function findIndex(predicate) {
37499
37522
  var O = ToObject(this);
37500
37523
  var len = LengthOfArrayLike(O);
@@ -94338,6 +94361,13 @@ var ZeroAddress = "0x0000000000000000000000000000000000000000";
94338
94361
  // node_modules/ethers/lib.esm/constants/hashes.js
94339
94362
  var ZeroHash = "0x0000000000000000000000000000000000000000000000000000000000000000";
94340
94363
 
94364
+ // node_modules/ethers/lib.esm/constants/numbers.js
94365
+ var N = BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");
94366
+ var WeiPerEther = BigInt("1000000000000000000");
94367
+ var MaxUint256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
94368
+ var MinInt256 = BigInt("0x8000000000000000000000000000000000000000000000000000000000000000") * BigInt(-1);
94369
+ var MaxInt256 = BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
94370
+
94341
94371
  // node_modules/ethers/lib.esm/crypto/signature.js
94342
94372
  var BN_04 = BigInt(0);
94343
94373
  var BN_13 = BigInt(1);
@@ -123020,6 +123050,78 @@ Error data: ${errorData || "none"}`
123020
123050
  );
123021
123051
  return psm.getAvailableReserves(stablecoinAddress);
123022
123052
  }
123053
+ /**
123054
+ * Execute a PSM stablecoin → UCD swap.
123055
+ * Handles stablecoin approval to the PSM contract if the current allowance is insufficient.
123056
+ *
123057
+ * @param params.stablecoinAddress - ERC-20 address of the stablecoin to swap in
123058
+ * @param params.amountWei - Stablecoin amount in native decimals (bigint)
123059
+ * @param params.minUcdOutWei - Minimum UCD to receive; reverts if below this (1% slippage guard)
123060
+ * @param params.signer - Connected signer for the approval and swap transactions
123061
+ */
123062
+ async psmSwap(params) {
123063
+ const psmAddress = this.config.contractAddresses?.simplePsmV2;
123064
+ if (!psmAddress) {
123065
+ throw new Error(
123066
+ "SimplePSMV2 address not configured \u2014 provide contractAddresses.simplePsmV2"
123067
+ );
123068
+ }
123069
+ const signerAddress = await params.signer.getAddress();
123070
+ const erc20Abi = [
123071
+ "function allowance(address owner, address spender) view returns (uint256)",
123072
+ "function approve(address spender, uint256 amount) returns (bool)"
123073
+ ];
123074
+ const stablecoin = new Contract(params.stablecoinAddress, erc20Abi, params.signer);
123075
+ const allowance = await stablecoin.allowance(signerAddress, psmAddress);
123076
+ if (allowance < params.amountWei) {
123077
+ const approveTx = await stablecoin.approve(psmAddress, MaxUint256);
123078
+ await approveTx.wait();
123079
+ }
123080
+ const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
123081
+ const tx = await psm.swap(params.stablecoinAddress, params.amountWei, params.minUcdOutWei);
123082
+ const receipt = await tx.wait();
123083
+ if (!receipt)
123084
+ throw new Error("PSM swap transaction receipt unavailable");
123085
+ return { hash: tx.hash, blockNumber: receipt.blockNumber };
123086
+ }
123087
+ /**
123088
+ * Execute a PSM UCD → stablecoin redeem.
123089
+ * Handles UCD approval to UCDController (not PSM) to satisfy the M-4 burn allowance guard:
123090
+ * UCDToken.burn(from, amount) calls _spendAllowance(from, msg.sender=ucdController, amount).
123091
+ *
123092
+ * @param params.stablecoinAddress - ERC-20 address of the stablecoin to receive
123093
+ * @param params.ucdAmountWei - UCD amount to redeem (18 decimals, bigint)
123094
+ * @param params.minStablecoinOutWei - Minimum stablecoin to receive (slippage guard)
123095
+ * @param params.signer - Connected signer
123096
+ */
123097
+ async psmRedeem(params) {
123098
+ const psmAddress = this.config.contractAddresses?.simplePsmV2;
123099
+ const ucdAddress = this.config.contractAddresses?.ucdToken;
123100
+ const ucdControllerAddress = this.config.contractAddresses?.ucdController;
123101
+ if (!psmAddress)
123102
+ throw new Error("SimplePSMV2 address not configured \u2014 provide contractAddresses.simplePsmV2");
123103
+ if (!ucdAddress)
123104
+ throw new Error("UCDToken address not configured \u2014 provide contractAddresses.ucdToken");
123105
+ if (!ucdControllerAddress)
123106
+ throw new Error("UCDController address not configured \u2014 provide contractAddresses.ucdController");
123107
+ const signerAddress = await params.signer.getAddress();
123108
+ const erc20Abi = [
123109
+ "function allowance(address owner, address spender) view returns (uint256)",
123110
+ "function approve(address spender, uint256 amount) returns (bool)"
123111
+ ];
123112
+ const ucdToken = new Contract(ucdAddress, erc20Abi, params.signer);
123113
+ const allowance = await ucdToken.allowance(signerAddress, ucdControllerAddress);
123114
+ if (allowance < params.ucdAmountWei) {
123115
+ const approveTx = await ucdToken.approve(ucdControllerAddress, MaxUint256);
123116
+ await approveTx.wait();
123117
+ }
123118
+ const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
123119
+ const tx = await psm.redeem(params.stablecoinAddress, params.ucdAmountWei, params.minStablecoinOutWei);
123120
+ const receipt = await tx.wait();
123121
+ if (!receipt)
123122
+ throw new Error("PSM redeem transaction receipt unavailable");
123123
+ return { hash: tx.hash, blockNumber: receipt.blockNumber };
123124
+ }
123023
123125
  /**
123024
123126
  * Wait for the subgraph to index up to (and including) the given block number.
123025
123127
  * Call after on-chain actions (createLoan, mintUCD, etc.) before querying the subgraph.
package/dist/index.mjs CHANGED
@@ -3689,11 +3689,11 @@ var init_deployment_addresses = __esm({
3689
3689
  reason: "Shared upgrade script: PositionManager implementation update"
3690
3690
  },
3691
3691
  LoanOperationsManagerModule: {
3692
- previousImplementation: "0x291B412c573a4F52410f09D7Ba82eead17D9a674",
3693
- newImplementation: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
3694
- upgradedAt: "2026-05-17T20:02:12.883Z",
3692
+ previousImplementation: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
3693
+ newImplementation: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
3694
+ upgradedAt: "2026-06-05T10:52:25.179Z",
3695
3695
  upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
3696
- reason: "Shared upgrade script: LoanOperationsManagerModule implementation update"
3696
+ reason: "audit #3 v1.6.0: LoanOperationsManagerModule \u2014 Chainlink feed-staleness gate (maxBtcFeedAgeBorrow / maxBtcFeedAgeLiquidation)"
3697
3697
  },
3698
3698
  UCDController: {
3699
3699
  previousImplementation: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
@@ -3898,7 +3898,7 @@ var init_deployment_addresses = __esm({
3898
3898
  CIRCUIT_BREAKER_MODULE: "0x3D0B2cAE481821E57BA9CC3807bCC0d0D7F18bd8",
3899
3899
  ADMIN_MODULE: "0xAcd1f07915b17CA3727e7fE89BdF618A1545a1ed",
3900
3900
  UCD_CONTROLLER_IMPL: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
3901
- LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
3901
+ LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
3902
3902
  TERM_MANAGER_MODULE_IMPL: "0x358d6A7A864853beAA3E157fEB83dCEb1628E8eB",
3903
3903
  CIRCUIT_BREAKER_MODULE_IMPL: "0xF6277dEF72D51312CC99616B5380f34Eb7603D75",
3904
3904
  ADMIN_MODULE_IMPL: "0xBBA86246169f81a307Fafff02C1e3D8456aab973",
@@ -37208,9 +37208,9 @@ var require_ToPrimitive = __commonJS({
37208
37208
  }
37209
37209
  });
37210
37210
 
37211
- // node_modules/es-abstract/2024/ToString.js
37211
+ // node_modules/es-abstract/2025/ToString.js
37212
37212
  var require_ToString = __commonJS({
37213
- "node_modules/es-abstract/2024/ToString.js"(exports2, module2) {
37213
+ "node_modules/es-abstract/2025/ToString.js"(exports2, module2) {
37214
37214
  "use strict";
37215
37215
  var GetIntrinsic = require_get_intrinsic();
37216
37216
  var $String = GetIntrinsic("%String%");
@@ -37231,13 +37231,20 @@ var require_implementation3 = __commonJS({
37231
37231
  var RequireObjectCoercible = require_RequireObjectCoercible();
37232
37232
  var ToString = require_ToString();
37233
37233
  var callBound = require_call_bound();
37234
+ var safeRegexTester = require_safe_regex_test();
37234
37235
  var $replace = callBound("String.prototype.replace");
37236
+ var $charAt = callBound("String.prototype.charAt");
37237
+ var $slice = callBound("String.prototype.slice");
37235
37238
  var mvsIsWS = /^\s$/.test("\u180E");
37236
37239
  var leftWhitespace = mvsIsWS ? /^[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+/ : /^[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+/;
37237
- var rightWhitespace = mvsIsWS ? /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+$/ : /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]+$/;
37240
+ var isWhitespace = safeRegexTester(mvsIsWS ? /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]$/ : /[\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF]$/);
37238
37241
  module2.exports = function trim() {
37239
- var S = ToString(RequireObjectCoercible(this));
37240
- return $replace($replace(S, leftWhitespace, ""), rightWhitespace, "");
37242
+ var S = $replace(ToString(RequireObjectCoercible(this)), leftWhitespace, "");
37243
+ var end = S.length;
37244
+ while (end > 0 && isWhitespace($charAt(S, end - 1))) {
37245
+ end -= 1;
37246
+ }
37247
+ return $slice(S, 0, end);
37241
37248
  };
37242
37249
  }
37243
37250
  });
@@ -37490,6 +37497,22 @@ var require_ToObject = __commonJS({
37490
37497
  }
37491
37498
  });
37492
37499
 
37500
+ // node_modules/es-abstract/2024/ToString.js
37501
+ var require_ToString2 = __commonJS({
37502
+ "node_modules/es-abstract/2024/ToString.js"(exports2, module2) {
37503
+ "use strict";
37504
+ var GetIntrinsic = require_get_intrinsic();
37505
+ var $String = GetIntrinsic("%String%");
37506
+ var $TypeError = require_type();
37507
+ module2.exports = function ToString(argument) {
37508
+ if (typeof argument === "symbol") {
37509
+ throw new $TypeError("Cannot convert a Symbol value to a string");
37510
+ }
37511
+ return $String(argument);
37512
+ };
37513
+ }
37514
+ });
37515
+
37493
37516
  // node_modules/array.prototype.findindex/implementation.js
37494
37517
  var require_implementation4 = __commonJS({
37495
37518
  "node_modules/array.prototype.findindex/implementation.js"(exports2, module2) {
@@ -37500,7 +37523,7 @@ var require_implementation4 = __commonJS({
37500
37523
  var LengthOfArrayLike = require_LengthOfArrayLike();
37501
37524
  var ToBoolean = require_ToBoolean();
37502
37525
  var ToObject = require_ToObject();
37503
- var ToString = require_ToString();
37526
+ var ToString = require_ToString2();
37504
37527
  module2.exports = function findIndex(predicate) {
37505
37528
  var O = ToObject(this);
37506
37529
  var len = LengthOfArrayLike(O);
@@ -94260,6 +94283,13 @@ var ZeroAddress = "0x0000000000000000000000000000000000000000";
94260
94283
  // node_modules/ethers/lib.esm/constants/hashes.js
94261
94284
  var ZeroHash = "0x0000000000000000000000000000000000000000000000000000000000000000";
94262
94285
 
94286
+ // node_modules/ethers/lib.esm/constants/numbers.js
94287
+ var N = BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141");
94288
+ var WeiPerEther = BigInt("1000000000000000000");
94289
+ var MaxUint256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
94290
+ var MinInt256 = BigInt("0x8000000000000000000000000000000000000000000000000000000000000000") * BigInt(-1);
94291
+ var MaxInt256 = BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
94292
+
94263
94293
  // node_modules/ethers/lib.esm/crypto/signature.js
94264
94294
  var BN_04 = BigInt(0);
94265
94295
  var BN_13 = BigInt(1);
@@ -122942,6 +122972,78 @@ Error data: ${errorData || "none"}`
122942
122972
  );
122943
122973
  return psm.getAvailableReserves(stablecoinAddress);
122944
122974
  }
122975
+ /**
122976
+ * Execute a PSM stablecoin → UCD swap.
122977
+ * Handles stablecoin approval to the PSM contract if the current allowance is insufficient.
122978
+ *
122979
+ * @param params.stablecoinAddress - ERC-20 address of the stablecoin to swap in
122980
+ * @param params.amountWei - Stablecoin amount in native decimals (bigint)
122981
+ * @param params.minUcdOutWei - Minimum UCD to receive; reverts if below this (1% slippage guard)
122982
+ * @param params.signer - Connected signer for the approval and swap transactions
122983
+ */
122984
+ async psmSwap(params) {
122985
+ const psmAddress = this.config.contractAddresses?.simplePsmV2;
122986
+ if (!psmAddress) {
122987
+ throw new Error(
122988
+ "SimplePSMV2 address not configured \u2014 provide contractAddresses.simplePsmV2"
122989
+ );
122990
+ }
122991
+ const signerAddress = await params.signer.getAddress();
122992
+ const erc20Abi = [
122993
+ "function allowance(address owner, address spender) view returns (uint256)",
122994
+ "function approve(address spender, uint256 amount) returns (bool)"
122995
+ ];
122996
+ const stablecoin = new Contract(params.stablecoinAddress, erc20Abi, params.signer);
122997
+ const allowance = await stablecoin.allowance(signerAddress, psmAddress);
122998
+ if (allowance < params.amountWei) {
122999
+ const approveTx = await stablecoin.approve(psmAddress, MaxUint256);
123000
+ await approveTx.wait();
123001
+ }
123002
+ const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
123003
+ const tx = await psm.swap(params.stablecoinAddress, params.amountWei, params.minUcdOutWei);
123004
+ const receipt = await tx.wait();
123005
+ if (!receipt)
123006
+ throw new Error("PSM swap transaction receipt unavailable");
123007
+ return { hash: tx.hash, blockNumber: receipt.blockNumber };
123008
+ }
123009
+ /**
123010
+ * Execute a PSM UCD → stablecoin redeem.
123011
+ * Handles UCD approval to UCDController (not PSM) to satisfy the M-4 burn allowance guard:
123012
+ * UCDToken.burn(from, amount) calls _spendAllowance(from, msg.sender=ucdController, amount).
123013
+ *
123014
+ * @param params.stablecoinAddress - ERC-20 address of the stablecoin to receive
123015
+ * @param params.ucdAmountWei - UCD amount to redeem (18 decimals, bigint)
123016
+ * @param params.minStablecoinOutWei - Minimum stablecoin to receive (slippage guard)
123017
+ * @param params.signer - Connected signer
123018
+ */
123019
+ async psmRedeem(params) {
123020
+ const psmAddress = this.config.contractAddresses?.simplePsmV2;
123021
+ const ucdAddress = this.config.contractAddresses?.ucdToken;
123022
+ const ucdControllerAddress = this.config.contractAddresses?.ucdController;
123023
+ if (!psmAddress)
123024
+ throw new Error("SimplePSMV2 address not configured \u2014 provide contractAddresses.simplePsmV2");
123025
+ if (!ucdAddress)
123026
+ throw new Error("UCDToken address not configured \u2014 provide contractAddresses.ucdToken");
123027
+ if (!ucdControllerAddress)
123028
+ throw new Error("UCDController address not configured \u2014 provide contractAddresses.ucdController");
123029
+ const signerAddress = await params.signer.getAddress();
123030
+ const erc20Abi = [
123031
+ "function allowance(address owner, address spender) view returns (uint256)",
123032
+ "function approve(address spender, uint256 amount) returns (bool)"
123033
+ ];
123034
+ const ucdToken = new Contract(ucdAddress, erc20Abi, params.signer);
123035
+ const allowance = await ucdToken.allowance(signerAddress, ucdControllerAddress);
123036
+ if (allowance < params.ucdAmountWei) {
123037
+ const approveTx = await ucdToken.approve(ucdControllerAddress, MaxUint256);
123038
+ await approveTx.wait();
123039
+ }
123040
+ const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
123041
+ const tx = await psm.redeem(params.stablecoinAddress, params.ucdAmountWei, params.minStablecoinOutWei);
123042
+ const receipt = await tx.wait();
123043
+ if (!receipt)
123044
+ throw new Error("PSM redeem transaction receipt unavailable");
123045
+ return { hash: tx.hash, blockNumber: receipt.blockNumber };
123046
+ }
122945
123047
  /**
122946
123048
  * Wait for the subgraph to index up to (and including) the given block number.
122947
123049
  * Call after on-chain actions (createLoan, mintUCD, etc.) before querying the subgraph.
@@ -11,7 +11,7 @@
11
11
  * - Dependency injection pattern
12
12
  * - Result-based error handling
13
13
  */
14
- import { type TransactionResponse } from "ethers";
14
+ import { type Signer, type TransactionResponse } from "ethers";
15
15
  import { Result } from "../types/result";
16
16
  import { Satoshis } from "../types/branded/domain-values";
17
17
  import { SDKError } from "../utils/error-handler";
@@ -672,6 +672,43 @@ export declare class DiamondHandsSDK {
672
672
  * @param stablecoinAddress - EVM address of the stablecoin to query.
673
673
  */
674
674
  getPSMAvailableReserves(stablecoinAddress: string): Promise<bigint>;
675
+ /**
676
+ * Execute a PSM stablecoin → UCD swap.
677
+ * Handles stablecoin approval to the PSM contract if the current allowance is insufficient.
678
+ *
679
+ * @param params.stablecoinAddress - ERC-20 address of the stablecoin to swap in
680
+ * @param params.amountWei - Stablecoin amount in native decimals (bigint)
681
+ * @param params.minUcdOutWei - Minimum UCD to receive; reverts if below this (1% slippage guard)
682
+ * @param params.signer - Connected signer for the approval and swap transactions
683
+ */
684
+ psmSwap(params: {
685
+ stablecoinAddress: string;
686
+ amountWei: bigint;
687
+ minUcdOutWei: bigint;
688
+ signer: Signer;
689
+ }): Promise<{
690
+ hash: string;
691
+ blockNumber: number;
692
+ }>;
693
+ /**
694
+ * Execute a PSM UCD → stablecoin redeem.
695
+ * Handles UCD approval to UCDController (not PSM) to satisfy the M-4 burn allowance guard:
696
+ * UCDToken.burn(from, amount) calls _spendAllowance(from, msg.sender=ucdController, amount).
697
+ *
698
+ * @param params.stablecoinAddress - ERC-20 address of the stablecoin to receive
699
+ * @param params.ucdAmountWei - UCD amount to redeem (18 decimals, bigint)
700
+ * @param params.minStablecoinOutWei - Minimum stablecoin to receive (slippage guard)
701
+ * @param params.signer - Connected signer
702
+ */
703
+ psmRedeem(params: {
704
+ stablecoinAddress: string;
705
+ ucdAmountWei: bigint;
706
+ minStablecoinOutWei: bigint;
707
+ signer: Signer;
708
+ }): Promise<{
709
+ hash: string;
710
+ blockNumber: number;
711
+ }>;
675
712
  /**
676
713
  * Wait for the subgraph to index up to (and including) the given block number.
677
714
  * Call after on-chain actions (createLoan, mintUCD, etc.) before querying the subgraph.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gvnrdao/dh-sdk",
3
- "version": "0.0.275",
3
+ "version": "0.0.276",
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",