@gvnrdao/dh-sdk 0.0.274 → 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.
- package/browser/dist/browser.js +1 -1
- package/dist/constants/chunks/deployment-addresses.d.ts +2 -0
- package/dist/constants/chunks/network-configs.d.ts +2 -0
- package/dist/deployments.js +15 -11
- package/dist/deployments.mjs +15 -11
- package/dist/index.d.ts +2 -0
- package/dist/index.js +454 -37
- package/dist/index.mjs +452 -37
- package/dist/interfaces/chunks/config.i.d.ts +2 -0
- package/dist/modules/contract/contract-manager.module.d.ts +7 -1
- package/dist/modules/diamond-hands-sdk.d.ts +59 -0
- package/dist/modules/withdrawal-address/withdrawal-address.module.d.ts +78 -0
- package/dist/utils/address-conversion.utils.d.ts +12 -0
- package/package.json +5 -5
package/dist/index.mjs
CHANGED
|
@@ -3677,7 +3677,8 @@ var init_deployment_addresses = __esm({
|
|
|
3677
3677
|
mockUsdcToken: "0x96409A98e0D322d6566b7F44a0fAbD1BD4ce2AEc",
|
|
3678
3678
|
mockUsdtToken: "0xF8b7fB38b17a310960E47805Be9adba0b0e0394D",
|
|
3679
3679
|
PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9",
|
|
3680
|
-
FeeRecipientRegistry: "0x95795F8403DDb629E8527B2934C4e71f5fC0C374"
|
|
3680
|
+
FeeRecipientRegistry: "0x95795F8403DDb629E8527B2934C4e71f5fC0C374",
|
|
3681
|
+
BitcoinWithdrawalAddressRegistry: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe"
|
|
3681
3682
|
},
|
|
3682
3683
|
upgraded: {
|
|
3683
3684
|
PositionManager: {
|
|
@@ -3688,11 +3689,11 @@ var init_deployment_addresses = __esm({
|
|
|
3688
3689
|
reason: "Shared upgrade script: PositionManager implementation update"
|
|
3689
3690
|
},
|
|
3690
3691
|
LoanOperationsManagerModule: {
|
|
3691
|
-
previousImplementation: "
|
|
3692
|
-
newImplementation: "
|
|
3693
|
-
upgradedAt: "2026-
|
|
3692
|
+
previousImplementation: "0x9DA8d69d7BcF9Fa3ba5734580e8C32618aB52D36",
|
|
3693
|
+
newImplementation: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
|
|
3694
|
+
upgradedAt: "2026-06-05T10:52:25.179Z",
|
|
3694
3695
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
3695
|
-
reason: "
|
|
3696
|
+
reason: "audit #3 v1.6.0: LoanOperationsManagerModule \u2014 Chainlink feed-staleness gate (maxBtcFeedAgeBorrow / maxBtcFeedAgeLiquidation)"
|
|
3696
3697
|
},
|
|
3697
3698
|
UCDController: {
|
|
3698
3699
|
previousImplementation: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
|
|
@@ -3751,9 +3752,9 @@ var init_deployment_addresses = __esm({
|
|
|
3751
3752
|
reason: "Shared upgrade script: PositionManagerCoreModule implementation update"
|
|
3752
3753
|
},
|
|
3753
3754
|
CollateralManagerModule: {
|
|
3754
|
-
previousImplementation: "
|
|
3755
|
-
newImplementation: "
|
|
3756
|
-
upgradedAt: "2026-
|
|
3755
|
+
previousImplementation: "0x124e61aBff60CC70c4B81ab3019A8A7D35B412d4",
|
|
3756
|
+
newImplementation: "0xd47FE9126daE9A1e0fFdaCf539BE7345D3642bcb",
|
|
3757
|
+
upgradedAt: "2026-06-05T09:14:12.892Z",
|
|
3757
3758
|
upgradedBy: "0xF20986F02420EF443AE9BE5092FB8A4975cF3aA6",
|
|
3758
3759
|
reason: "Shared upgrade script: CollateralManagerModule implementation update"
|
|
3759
3760
|
},
|
|
@@ -3897,7 +3898,7 @@ var init_deployment_addresses = __esm({
|
|
|
3897
3898
|
CIRCUIT_BREAKER_MODULE: "0x3D0B2cAE481821E57BA9CC3807bCC0d0D7F18bd8",
|
|
3898
3899
|
ADMIN_MODULE: "0xAcd1f07915b17CA3727e7fE89BdF618A1545a1ed",
|
|
3899
3900
|
UCD_CONTROLLER_IMPL: "0x30d0458bE846f4C5D231242eB5a9e9Db68e7232F",
|
|
3900
|
-
LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "
|
|
3901
|
+
LOAN_OPERATIONS_MANAGER_MODULE_IMPL: "0x8c20e9Edf44146718F2EF15eEF47A201CaC229B8",
|
|
3901
3902
|
TERM_MANAGER_MODULE_IMPL: "0x358d6A7A864853beAA3E157fEB83dCEb1628E8eB",
|
|
3902
3903
|
CIRCUIT_BREAKER_MODULE_IMPL: "0xF6277dEF72D51312CC99616B5380f34Eb7603D75",
|
|
3903
3904
|
ADMIN_MODULE_IMPL: "0xBBA86246169f81a307Fafff02C1e3D8456aab973",
|
|
@@ -3929,7 +3930,9 @@ var init_deployment_addresses = __esm({
|
|
|
3929
3930
|
AGENT_MODULE: "0xefb8C29C1e7e92ed7d81a52dbedaed74e37fe380",
|
|
3930
3931
|
FEE_RECIPIENT_REGISTRY: "0x95795F8403DDb629E8527B2934C4e71f5fC0C374",
|
|
3931
3932
|
FEE_RECIPIENT_REGISTRY_IMPL: "0xd08513a7cB2dd354B26cDDf549616F12054c34c9",
|
|
3932
|
-
OPERATION_AUTHORIZATION_REGISTRY_IMPL: "0x9f8072d4672d643e39d8638478e900Fea1f2c81D"
|
|
3933
|
+
OPERATION_AUTHORIZATION_REGISTRY_IMPL: "0x9f8072d4672d643e39d8638478e900Fea1f2c81D",
|
|
3934
|
+
BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe",
|
|
3935
|
+
BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_IMPL: "0xFF270BC4470dBA80430Bd1a3a66EB691599354fA"
|
|
3933
3936
|
}
|
|
3934
3937
|
};
|
|
3935
3938
|
SEPOLIA_CONTRACTS = {
|
|
@@ -3956,7 +3959,8 @@ var init_deployment_addresses = __esm({
|
|
|
3956
3959
|
mockUsdcToken: "0x96409A98e0D322d6566b7F44a0fAbD1BD4ce2AEc",
|
|
3957
3960
|
mockUsdtToken: "0xF8b7fB38b17a310960E47805Be9adba0b0e0394D",
|
|
3958
3961
|
PositionDelegateRegistry: "0x482369De283622E7b05731875ec137d4E3D208F9",
|
|
3959
|
-
FeeRecipientRegistry: "0x95795F8403DDb629E8527B2934C4e71f5fC0C374"
|
|
3962
|
+
FeeRecipientRegistry: "0x95795F8403DDb629E8527B2934C4e71f5fC0C374",
|
|
3963
|
+
BitcoinWithdrawalAddressRegistry: "0x6376D392097F0A81e51BD83960A97EA20eaf1dbe"
|
|
3960
3964
|
};
|
|
3961
3965
|
LOCALHOST_DEPLOYMENT = {
|
|
3962
3966
|
network: "localhost",
|
|
@@ -7272,7 +7276,7 @@ var require_abstract_coder = __commonJS({
|
|
|
7272
7276
|
function toObject2(names2, items, deep) {
|
|
7273
7277
|
if (names2.indexOf(null) >= 0) {
|
|
7274
7278
|
return items.map((item, index) => {
|
|
7275
|
-
if (item instanceof
|
|
7279
|
+
if (item instanceof Result11) {
|
|
7276
7280
|
return toObject2(getNames2(item), item, deep);
|
|
7277
7281
|
}
|
|
7278
7282
|
return item;
|
|
@@ -7281,7 +7285,7 @@ var require_abstract_coder = __commonJS({
|
|
|
7281
7285
|
return names2.reduce((accum, name, index) => {
|
|
7282
7286
|
let item = items.getValue(name);
|
|
7283
7287
|
if (!(name in accum)) {
|
|
7284
|
-
if (deep && item instanceof
|
|
7288
|
+
if (deep && item instanceof Result11) {
|
|
7285
7289
|
item = toObject2(getNames2(item), item, deep);
|
|
7286
7290
|
}
|
|
7287
7291
|
accum[name] = item;
|
|
@@ -7289,7 +7293,7 @@ var require_abstract_coder = __commonJS({
|
|
|
7289
7293
|
return accum;
|
|
7290
7294
|
}, {});
|
|
7291
7295
|
}
|
|
7292
|
-
var
|
|
7296
|
+
var Result11 = class _Result extends Array {
|
|
7293
7297
|
// No longer used; but cannot be removed as it will remove the
|
|
7294
7298
|
// #private field from the .d.ts which may break backwards
|
|
7295
7299
|
// compatibility
|
|
@@ -7493,7 +7497,7 @@ var require_abstract_coder = __commonJS({
|
|
|
7493
7497
|
return new _Result(_guard5, items, keys);
|
|
7494
7498
|
}
|
|
7495
7499
|
};
|
|
7496
|
-
exports2.Result =
|
|
7500
|
+
exports2.Result = Result11;
|
|
7497
7501
|
function checkResultErrors2(result) {
|
|
7498
7502
|
const errors2 = [];
|
|
7499
7503
|
const checkErrors = function(path2, object2) {
|
|
@@ -20184,9 +20188,9 @@ var require_contract = __commonJS({
|
|
|
20184
20188
|
function _ContractBase2() {
|
|
20185
20189
|
return BaseContract2;
|
|
20186
20190
|
}
|
|
20187
|
-
var
|
|
20191
|
+
var Contract3 = class extends _ContractBase2() {
|
|
20188
20192
|
};
|
|
20189
|
-
exports2.Contract =
|
|
20193
|
+
exports2.Contract = Contract3;
|
|
20190
20194
|
}
|
|
20191
20195
|
});
|
|
20192
20196
|
|
|
@@ -31451,17 +31455,17 @@ var require_pkg_src = __commonJS({
|
|
|
31451
31455
|
}
|
|
31452
31456
|
},
|
|
31453
31457
|
btcWithdrawal: {
|
|
31454
|
-
cid: "
|
|
31458
|
+
cid: "QmNqErzpgDUair9bPK7oPQczjKjRcsmcej37izponrEcqp",
|
|
31455
31459
|
authorizedCidHex: cidToHex(
|
|
31456
|
-
"
|
|
31460
|
+
"QmNqErzpgDUair9bPK7oPQczjKjRcsmcej37izponrEcqp"
|
|
31457
31461
|
),
|
|
31458
31462
|
name: "Btc Withdrawal",
|
|
31459
31463
|
description: "Production Btc Withdrawal",
|
|
31460
31464
|
version: "1.0.0",
|
|
31461
31465
|
deployed: true,
|
|
31462
|
-
deployedAt:
|
|
31463
|
-
size:
|
|
31464
|
-
hash: "
|
|
31466
|
+
deployedAt: 1780651980768,
|
|
31467
|
+
size: 75137,
|
|
31468
|
+
hash: "368f9aea32cf2e660b0f75b88b6ee043cf5956319d7b3c6c695d4b984b3bd555",
|
|
31465
31469
|
validatorWalletAddress: "0xbb137fbda353199e9419b698c57a742124d4987d",
|
|
31466
31470
|
pkp: {
|
|
31467
31471
|
publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
|
|
@@ -32334,7 +32338,7 @@ ${errorReport}`);
|
|
|
32334
32338
|
}
|
|
32335
32339
|
init_debug_logger();
|
|
32336
32340
|
init_session_signature_cache();
|
|
32337
|
-
var
|
|
32341
|
+
var import_ethers14 = require_lib2();
|
|
32338
32342
|
var EXPIRED_LOAN_MIN_LIQUIDATION_THRESHOLD_BPS = 11e3;
|
|
32339
32343
|
var GRACE_PERIOD_DAYS = 30;
|
|
32340
32344
|
var SATOSHIS_PER_BITCOIN = 100000000n;
|
|
@@ -34486,12 +34490,12 @@ ${errorReport}`);
|
|
|
34486
34490
|
}
|
|
34487
34491
|
async function executeVaultSnapshot(params) {
|
|
34488
34492
|
global.ethers = {
|
|
34489
|
-
...
|
|
34493
|
+
...import_ethers14.ethers,
|
|
34490
34494
|
providers: {
|
|
34491
|
-
StaticJsonRpcProvider:
|
|
34495
|
+
StaticJsonRpcProvider: import_ethers14.ethers.JsonRpcProvider
|
|
34492
34496
|
},
|
|
34493
|
-
Contract:
|
|
34494
|
-
utils:
|
|
34497
|
+
Contract: import_ethers14.ethers.Contract,
|
|
34498
|
+
utils: import_ethers14.ethers
|
|
34495
34499
|
// v6 moved utils to top level
|
|
34496
34500
|
};
|
|
34497
34501
|
global.Lit = {
|
|
@@ -34759,7 +34763,8 @@ function getSepoliaConfig() {
|
|
|
34759
34763
|
bitcoinProviderRegistry: SEPOLIA_CONTRACTS.BitcoinProviderRegistry || "",
|
|
34760
34764
|
contractVersionRegistry: SEPOLIA_CONTRACTS.ContractVersionRegistry || "",
|
|
34761
34765
|
feeRecipientRegistry: SEPOLIA_CONTRACTS.FeeRecipientRegistry || "",
|
|
34762
|
-
positionDelegateRegistry: SEPOLIA_CONTRACTS.PositionDelegateRegistry || ""
|
|
34766
|
+
positionDelegateRegistry: SEPOLIA_CONTRACTS.PositionDelegateRegistry || "",
|
|
34767
|
+
bitcoinWithdrawalAddressRegistry: SEPOLIA_CONTRACTS.BitcoinWithdrawalAddressRegistry || ""
|
|
34763
34768
|
},
|
|
34764
34769
|
subgraphs: {
|
|
34765
34770
|
// Lazy getter for the same module-init snapshot reason as serviceEndpoint.
|
|
@@ -37203,9 +37208,9 @@ var require_ToPrimitive = __commonJS({
|
|
|
37203
37208
|
}
|
|
37204
37209
|
});
|
|
37205
37210
|
|
|
37206
|
-
// node_modules/es-abstract/
|
|
37211
|
+
// node_modules/es-abstract/2025/ToString.js
|
|
37207
37212
|
var require_ToString = __commonJS({
|
|
37208
|
-
"node_modules/es-abstract/
|
|
37213
|
+
"node_modules/es-abstract/2025/ToString.js"(exports2, module2) {
|
|
37209
37214
|
"use strict";
|
|
37210
37215
|
var GetIntrinsic = require_get_intrinsic();
|
|
37211
37216
|
var $String = GetIntrinsic("%String%");
|
|
@@ -37226,13 +37231,20 @@ var require_implementation3 = __commonJS({
|
|
|
37226
37231
|
var RequireObjectCoercible = require_RequireObjectCoercible();
|
|
37227
37232
|
var ToString = require_ToString();
|
|
37228
37233
|
var callBound = require_call_bound();
|
|
37234
|
+
var safeRegexTester = require_safe_regex_test();
|
|
37229
37235
|
var $replace = callBound("String.prototype.replace");
|
|
37236
|
+
var $charAt = callBound("String.prototype.charAt");
|
|
37237
|
+
var $slice = callBound("String.prototype.slice");
|
|
37230
37238
|
var mvsIsWS = /^\s$/.test("\u180E");
|
|
37231
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]+/;
|
|
37232
|
-
var
|
|
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]$/);
|
|
37233
37241
|
module2.exports = function trim() {
|
|
37234
|
-
var S = ToString(RequireObjectCoercible(this));
|
|
37235
|
-
|
|
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);
|
|
37236
37248
|
};
|
|
37237
37249
|
}
|
|
37238
37250
|
});
|
|
@@ -37485,6 +37497,22 @@ var require_ToObject = __commonJS({
|
|
|
37485
37497
|
}
|
|
37486
37498
|
});
|
|
37487
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
|
+
|
|
37488
37516
|
// node_modules/array.prototype.findindex/implementation.js
|
|
37489
37517
|
var require_implementation4 = __commonJS({
|
|
37490
37518
|
"node_modules/array.prototype.findindex/implementation.js"(exports2, module2) {
|
|
@@ -37495,7 +37523,7 @@ var require_implementation4 = __commonJS({
|
|
|
37495
37523
|
var LengthOfArrayLike = require_LengthOfArrayLike();
|
|
37496
37524
|
var ToBoolean = require_ToBoolean();
|
|
37497
37525
|
var ToObject = require_ToObject();
|
|
37498
|
-
var ToString =
|
|
37526
|
+
var ToString = require_ToString2();
|
|
37499
37527
|
module2.exports = function findIndex(predicate) {
|
|
37500
37528
|
var O = ToObject(this);
|
|
37501
37529
|
var len = LengthOfArrayLike(O);
|
|
@@ -94255,6 +94283,13 @@ var ZeroAddress = "0x0000000000000000000000000000000000000000";
|
|
|
94255
94283
|
// node_modules/ethers/lib.esm/constants/hashes.js
|
|
94256
94284
|
var ZeroHash = "0x0000000000000000000000000000000000000000000000000000000000000000";
|
|
94257
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
|
+
|
|
94258
94293
|
// node_modules/ethers/lib.esm/crypto/signature.js
|
|
94259
94294
|
var BN_04 = BigInt(0);
|
|
94260
94295
|
var BN_13 = BigInt(1);
|
|
@@ -108788,6 +108823,15 @@ function safeValidateBitcoinAddress(address, network = "regtest") {
|
|
|
108788
108823
|
}
|
|
108789
108824
|
return address;
|
|
108790
108825
|
}
|
|
108826
|
+
function normalizeBitcoinAddress(address) {
|
|
108827
|
+
if (!address || typeof address !== "string")
|
|
108828
|
+
return address;
|
|
108829
|
+
const trimmed = address.trim();
|
|
108830
|
+
if (/^(bc1|tb1|bcrt1)/i.test(trimmed)) {
|
|
108831
|
+
return trimmed.toLowerCase();
|
|
108832
|
+
}
|
|
108833
|
+
return trimmed;
|
|
108834
|
+
}
|
|
108791
108835
|
|
|
108792
108836
|
// src/protocol/protocol-pause.ts
|
|
108793
108837
|
var GET_PROTOCOL_PAUSE_STATUS_ABI = [
|
|
@@ -108979,6 +109023,21 @@ var LIQUIDATION_MANAGER_ABI = [
|
|
|
108979
109023
|
"function canLiquidate(bytes32 positionId) external view returns (bool)",
|
|
108980
109024
|
"function vrfSeeds(bytes32 positionId) external view returns (uint256)"
|
|
108981
109025
|
];
|
|
109026
|
+
var BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_ABI = [
|
|
109027
|
+
"function addAddress(string btcAddress) external",
|
|
109028
|
+
"function removeAddress(string btcAddress) external",
|
|
109029
|
+
"function removeAddressByHash(bytes32 addrHash) external",
|
|
109030
|
+
"function isApproved(address user, string btcAddress) external view returns (bool)",
|
|
109031
|
+
"function isApprovedByHash(address user, bytes32 addrHash) external view returns (bool)",
|
|
109032
|
+
"function isPresent(address user, bytes32 addrHash) external view returns (bool)",
|
|
109033
|
+
"function getAddedAt(address user, bytes32 addrHash) external view returns (uint64)",
|
|
109034
|
+
"function getUsableAt(address user, bytes32 addrHash) external view returns (uint256)",
|
|
109035
|
+
"function getAddressHashes(address user) external view returns (bytes32[])",
|
|
109036
|
+
"function addressCount(address user) external view returns (uint256)",
|
|
109037
|
+
"function addressDelay() external view returns (uint256)",
|
|
109038
|
+
"event AddressAdded(address indexed user, bytes32 indexed addrHash, string btcAddress, uint64 addedAt, uint256 usableAt)",
|
|
109039
|
+
"event AddressRemoved(address indexed user, bytes32 indexed addrHash, string btcAddress)"
|
|
109040
|
+
];
|
|
108982
109041
|
var ContractManager = class {
|
|
108983
109042
|
config;
|
|
108984
109043
|
contracts = null;
|
|
@@ -109039,6 +109098,11 @@ var ContractManager = class {
|
|
|
109039
109098
|
contractAddresses.liquidationManager || ZeroAddress,
|
|
109040
109099
|
LIQUIDATION_MANAGER_ABI,
|
|
109041
109100
|
contractRunner
|
|
109101
|
+
),
|
|
109102
|
+
bitcoinWithdrawalAddressRegistry: new Contract(
|
|
109103
|
+
contractAddresses.bitcoinWithdrawalAddressRegistry || ZeroAddress,
|
|
109104
|
+
BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_ABI,
|
|
109105
|
+
contractRunner
|
|
109042
109106
|
)
|
|
109043
109107
|
};
|
|
109044
109108
|
this.contracts = contracts;
|
|
@@ -109069,7 +109133,16 @@ var ContractManager = class {
|
|
|
109069
109133
|
"loanOperationsManager",
|
|
109070
109134
|
"termManager",
|
|
109071
109135
|
"circuitBreaker",
|
|
109072
|
-
"liquidationManager"
|
|
109136
|
+
"liquidationManager",
|
|
109137
|
+
// INTENTIONALLY OPTIONAL — do not promote to requiredAddresses.
|
|
109138
|
+
// The on-chain CollateralManager gate is inert while its registry is
|
|
109139
|
+
// address(0) (staged rollout), so pre-v1.3 deployments, browser/default
|
|
109140
|
+
// configs, and tests legitimately omit this address. The SDK's layer-1
|
|
109141
|
+
// early-reject (WithdrawalAddressModule.assertApprovedForWithdrawal)
|
|
109142
|
+
// already no-ops via isConfigured() when the address is absent/ZeroAddress,
|
|
109143
|
+
// and the contract instance defaults to ZeroAddress. Making this required
|
|
109144
|
+
// would throw at init for every config that hasn't deployed the registry.
|
|
109145
|
+
"bitcoinWithdrawalAddressRegistry"
|
|
109073
109146
|
];
|
|
109074
109147
|
const missing = [];
|
|
109075
109148
|
const invalid = [];
|
|
@@ -109182,6 +109255,16 @@ var ContractManager = class {
|
|
|
109182
109255
|
}
|
|
109183
109256
|
return success(contractsResult.value.liquidationManager);
|
|
109184
109257
|
}
|
|
109258
|
+
/**
|
|
109259
|
+
* Get the BitcoinWithdrawalAddressRegistry contract (per-wallet approved-address allowlist).
|
|
109260
|
+
*/
|
|
109261
|
+
getBitcoinWithdrawalAddressRegistry() {
|
|
109262
|
+
const contractsResult = this.getContracts();
|
|
109263
|
+
if (!contractsResult.success) {
|
|
109264
|
+
return contractsResult;
|
|
109265
|
+
}
|
|
109266
|
+
return success(contractsResult.value.bitcoinWithdrawalAddressRegistry);
|
|
109267
|
+
}
|
|
109185
109268
|
/**
|
|
109186
109269
|
* Get the provider instance
|
|
109187
109270
|
*/
|
|
@@ -111271,6 +111354,168 @@ function createLoanQuery(config) {
|
|
|
111271
111354
|
}
|
|
111272
111355
|
}
|
|
111273
111356
|
|
|
111357
|
+
// src/modules/withdrawal-address/withdrawal-address.module.ts
|
|
111358
|
+
var WithdrawalAddressModule = class {
|
|
111359
|
+
config;
|
|
111360
|
+
constructor(config) {
|
|
111361
|
+
this.config = config;
|
|
111362
|
+
}
|
|
111363
|
+
/** Resolve the registry contract, or fail if it isn't configured for this network. */
|
|
111364
|
+
getRegistry() {
|
|
111365
|
+
const res = this.config.contractManager.getBitcoinWithdrawalAddressRegistry();
|
|
111366
|
+
if (!res.success)
|
|
111367
|
+
return res;
|
|
111368
|
+
const target = res.value.target;
|
|
111369
|
+
if (!target || target === ZeroAddress) {
|
|
111370
|
+
return failure(
|
|
111371
|
+
new SDKError({
|
|
111372
|
+
code: "SDK_WITHDRAWAL_REGISTRY_NOT_CONFIGURED",
|
|
111373
|
+
message: "BitcoinWithdrawalAddressRegistry address is not configured for this network",
|
|
111374
|
+
category: "CONFIGURATION" /* CONFIGURATION */,
|
|
111375
|
+
severity: "MEDIUM" /* MEDIUM */
|
|
111376
|
+
})
|
|
111377
|
+
);
|
|
111378
|
+
}
|
|
111379
|
+
return success(res.value);
|
|
111380
|
+
}
|
|
111381
|
+
/** True iff the registry is wired for this network (enforcement is active). */
|
|
111382
|
+
isConfigured() {
|
|
111383
|
+
return this.getRegistry().success;
|
|
111384
|
+
}
|
|
111385
|
+
/** keccak256 of the canonicalized address — matches the on-chain key. */
|
|
111386
|
+
static addressHash(btcAddress) {
|
|
111387
|
+
return keccak256(toUtf8Bytes(normalizeBitcoinAddress(btcAddress)));
|
|
111388
|
+
}
|
|
111389
|
+
/**
|
|
111390
|
+
* Add a Bitcoin address to the caller's allowlist. It becomes usable only
|
|
111391
|
+
* after the registry's delay elapses. Returns the submitted tx.
|
|
111392
|
+
*/
|
|
111393
|
+
async addAddress(btcAddress) {
|
|
111394
|
+
const reg = this.getRegistry();
|
|
111395
|
+
if (!reg.success)
|
|
111396
|
+
return reg;
|
|
111397
|
+
try {
|
|
111398
|
+
const tx = await reg.value.addAddress(
|
|
111399
|
+
normalizeBitcoinAddress(btcAddress)
|
|
111400
|
+
);
|
|
111401
|
+
return success(tx);
|
|
111402
|
+
} catch (error2) {
|
|
111403
|
+
return this.txFailure("addAddress", error2, btcAddress);
|
|
111404
|
+
}
|
|
111405
|
+
}
|
|
111406
|
+
/** Remove a Bitcoin address from the caller's allowlist (effective immediately). */
|
|
111407
|
+
async removeAddress(btcAddress) {
|
|
111408
|
+
const reg = this.getRegistry();
|
|
111409
|
+
if (!reg.success)
|
|
111410
|
+
return reg;
|
|
111411
|
+
try {
|
|
111412
|
+
const tx = await reg.value.removeAddress(
|
|
111413
|
+
normalizeBitcoinAddress(btcAddress)
|
|
111414
|
+
);
|
|
111415
|
+
return success(tx);
|
|
111416
|
+
} catch (error2) {
|
|
111417
|
+
return this.txFailure("removeAddress", error2, btcAddress);
|
|
111418
|
+
}
|
|
111419
|
+
}
|
|
111420
|
+
/**
|
|
111421
|
+
* Authoritative contract read: is `btcAddress` approved (present AND past its
|
|
111422
|
+
* delay) for `user`?
|
|
111423
|
+
*/
|
|
111424
|
+
async isApproved(user, btcAddress) {
|
|
111425
|
+
const reg = this.getRegistry();
|
|
111426
|
+
if (!reg.success)
|
|
111427
|
+
return reg;
|
|
111428
|
+
try {
|
|
111429
|
+
const ok = await reg.value.isApproved(
|
|
111430
|
+
user,
|
|
111431
|
+
normalizeBitcoinAddress(btcAddress)
|
|
111432
|
+
);
|
|
111433
|
+
return success(ok);
|
|
111434
|
+
} catch (error2) {
|
|
111435
|
+
return this.txFailure("isApproved", error2, btcAddress);
|
|
111436
|
+
}
|
|
111437
|
+
}
|
|
111438
|
+
/**
|
|
111439
|
+
* Read the user's allowlist from the contract: hashes + timestamps + derived
|
|
111440
|
+
* approval state. NOTE: the raw address strings are NOT on-chain — use the
|
|
111441
|
+
* subgraph (WithdrawalAddressBook) to render human-readable addresses.
|
|
111442
|
+
*/
|
|
111443
|
+
async getEntries(user) {
|
|
111444
|
+
const reg = this.getRegistry();
|
|
111445
|
+
if (!reg.success)
|
|
111446
|
+
return reg;
|
|
111447
|
+
try {
|
|
111448
|
+
const hashes = await reg.value.getAddressHashes(user);
|
|
111449
|
+
const entries = [];
|
|
111450
|
+
for (const addrHash of hashes) {
|
|
111451
|
+
const addedAt = Number(await reg.value.getAddedAt(user, addrHash));
|
|
111452
|
+
const usableAt = Number(await reg.value.getUsableAt(user, addrHash));
|
|
111453
|
+
const approved = await reg.value.isApprovedByHash(
|
|
111454
|
+
user,
|
|
111455
|
+
addrHash
|
|
111456
|
+
);
|
|
111457
|
+
entries.push({ addrHash, addedAt, usableAt, approved });
|
|
111458
|
+
}
|
|
111459
|
+
return success(entries);
|
|
111460
|
+
} catch (error2) {
|
|
111461
|
+
return this.txFailure("getEntries", error2, user);
|
|
111462
|
+
}
|
|
111463
|
+
}
|
|
111464
|
+
/** The current global delay (seconds) before a newly-added address is usable. */
|
|
111465
|
+
async getAddressDelay() {
|
|
111466
|
+
const reg = this.getRegistry();
|
|
111467
|
+
if (!reg.success)
|
|
111468
|
+
return reg;
|
|
111469
|
+
try {
|
|
111470
|
+
const delay = await reg.value.addressDelay();
|
|
111471
|
+
return success(Number(delay));
|
|
111472
|
+
} catch (error2) {
|
|
111473
|
+
return this.txFailure("addressDelay", error2, "");
|
|
111474
|
+
}
|
|
111475
|
+
}
|
|
111476
|
+
/**
|
|
111477
|
+
* Early-reject guard used by `withdrawBTC`. Resolves to a typed error if the
|
|
111478
|
+
* destination is not approved for `borrower`. When the registry is not
|
|
111479
|
+
* configured for the network, this is a no-op (the on-chain gate remains the
|
|
111480
|
+
* hard guarantee).
|
|
111481
|
+
*/
|
|
111482
|
+
async assertApprovedForWithdrawal(borrower, btcAddress) {
|
|
111483
|
+
if (!this.isConfigured())
|
|
111484
|
+
return success(void 0);
|
|
111485
|
+
const res = await this.isApproved(borrower, btcAddress);
|
|
111486
|
+
if (!res.success)
|
|
111487
|
+
return res;
|
|
111488
|
+
if (!res.value) {
|
|
111489
|
+
return failure(
|
|
111490
|
+
new SDKError({
|
|
111491
|
+
code: "SDK_WITHDRAWAL_ADDRESS_NOT_APPROVED",
|
|
111492
|
+
message: `Bitcoin address ${btcAddress} is not an approved withdrawal destination for ${borrower} (not on the allowlist, or its time-lock has not elapsed). Add it and wait for the delay first.`,
|
|
111493
|
+
category: "VALIDATION" /* VALIDATION */,
|
|
111494
|
+
severity: "MEDIUM" /* MEDIUM */,
|
|
111495
|
+
context: { borrower, btcAddress }
|
|
111496
|
+
})
|
|
111497
|
+
);
|
|
111498
|
+
}
|
|
111499
|
+
return success(void 0);
|
|
111500
|
+
}
|
|
111501
|
+
txFailure(op, error2, context) {
|
|
111502
|
+
const msg = error2 instanceof Error ? error2.message : String(error2);
|
|
111503
|
+
return failure(
|
|
111504
|
+
new SDKError({
|
|
111505
|
+
code: `SDK_WITHDRAWAL_REGISTRY_${op.toUpperCase()}_FAILED`,
|
|
111506
|
+
message: `WithdrawalAddressRegistry.${op} failed: ${msg}`,
|
|
111507
|
+
category: "CONTRACT" /* CONTRACT */,
|
|
111508
|
+
severity: "MEDIUM" /* MEDIUM */,
|
|
111509
|
+
originalError: error2 instanceof Error ? error2 : new Error(String(error2)),
|
|
111510
|
+
context: { op, context }
|
|
111511
|
+
})
|
|
111512
|
+
);
|
|
111513
|
+
}
|
|
111514
|
+
};
|
|
111515
|
+
function createWithdrawalAddressModule(config) {
|
|
111516
|
+
return new WithdrawalAddressModule(config);
|
|
111517
|
+
}
|
|
111518
|
+
|
|
111274
111519
|
// src/types/branded/domain-values.ts
|
|
111275
111520
|
var UCD_BRAND = Symbol.for("diamond-hands.UCD");
|
|
111276
111521
|
var SATOSHIS_BRAND = Symbol.for("diamond-hands.Satoshis");
|
|
@@ -117103,6 +117348,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
117103
117348
|
loanCreator;
|
|
117104
117349
|
loanQuery;
|
|
117105
117350
|
bitcoinOperations;
|
|
117351
|
+
withdrawalAddressModule;
|
|
117106
117352
|
mockTokenManager;
|
|
117107
117353
|
graphClient;
|
|
117108
117354
|
/**
|
|
@@ -117286,6 +117532,10 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
117286
117532
|
);
|
|
117287
117533
|
}
|
|
117288
117534
|
this.contractManager = contractManagerResult.value;
|
|
117535
|
+
this.withdrawalAddressModule = createWithdrawalAddressModule({
|
|
117536
|
+
contractManager: this.contractManager,
|
|
117537
|
+
debug: config.debug
|
|
117538
|
+
});
|
|
117289
117539
|
this.litOps = new LitOps({
|
|
117290
117540
|
mode: config.mode || "standalone",
|
|
117291
117541
|
network: config.litNetwork || DEFAULT_LIT_NETWORK,
|
|
@@ -117360,6 +117610,11 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
117360
117610
|
);
|
|
117361
117611
|
}
|
|
117362
117612
|
const graphHeaders = !serviceMode && config.graphApiKey ? { Authorization: `Bearer ${config.graphApiKey}` } : void 0;
|
|
117613
|
+
if (graphHeaders && typeof window !== "undefined" && typeof window.document !== "undefined") {
|
|
117614
|
+
log.warn(
|
|
117615
|
+
"graphApiKey is being used in standalone mode inside a browser \u2014 the key will be exposed to end users. Use service mode (serviceEndpoint + session auth) for any user-facing app so GRAPH_API_KEY stays server-side."
|
|
117616
|
+
);
|
|
117617
|
+
}
|
|
117363
117618
|
this.graphClient = new DiamondHandsGraph(
|
|
117364
117619
|
{
|
|
117365
117620
|
endpoint: graphEndpoint,
|
|
@@ -118171,7 +118426,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
118171
118426
|
);
|
|
118172
118427
|
}
|
|
118173
118428
|
const chain = this.config.chain || (Number(network2.chainId) === 1 ? "ethereum" : "sepolia");
|
|
118174
|
-
const devBitcoinProviderUrl =
|
|
118429
|
+
const devBitcoinProviderUrl = request.customBitcoinRpcUrl || this.config.bitcoinProviders?.[0]?.url;
|
|
118175
118430
|
if (this.config.debug) {
|
|
118176
118431
|
log.info(` Network: ${chain} (chainId: ${network2.chainId})`);
|
|
118177
118432
|
}
|
|
@@ -118217,7 +118472,17 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
118217
118472
|
contractAddresses: contracts
|
|
118218
118473
|
},
|
|
118219
118474
|
userSignature: auth.signature,
|
|
118220
|
-
|
|
118475
|
+
// lit-ops reads `bitcoinProviderUrl` (request field) and maps it to the
|
|
118476
|
+
// validator's `devBitcoinProviderUrl` jsParam on Hardhat.
|
|
118477
|
+
...devBitcoinProviderUrl ? { bitcoinProviderUrl: devBitcoinProviderUrl } : {},
|
|
118478
|
+
// Optional override of the mint validator PKP/wallet (e.g. an on-chain-multisig-authorized
|
|
118479
|
+
// validator) — applied to a local copy in lit-ops, never mutating the registry singleton.
|
|
118480
|
+
// When set, authorization is by the on-chain ACTION CID, so the posted code must stay
|
|
118481
|
+
// byte-identical to the registry code (no cache-bust nonce) or the derived CID won't match.
|
|
118482
|
+
...this.config.mintValidatorOverride ? {
|
|
118483
|
+
validatorOverride: this.config.mintValidatorOverride,
|
|
118484
|
+
disableCacheBust: true
|
|
118485
|
+
} : {},
|
|
118221
118486
|
rpcUrl: request.rpcUrl || this.config.ethRpcUrl,
|
|
118222
118487
|
// Pass RPC URL to LIT Action (ngrok for Hardhat)
|
|
118223
118488
|
...request.debugOverrides && {
|
|
@@ -121233,6 +121498,40 @@ Error data: ${errorData || "none"}`
|
|
|
121233
121498
|
this.releaseWriteLock(request.positionId);
|
|
121234
121499
|
}
|
|
121235
121500
|
}
|
|
121501
|
+
/**
|
|
121502
|
+
* Access the approved-withdrawal-address allowlist module (self-service
|
|
121503
|
+
* add/remove + reads). The connected wallet manages its OWN addresses; a
|
|
121504
|
+
* newly-added address is only usable after the registry's time-lock delay.
|
|
121505
|
+
*/
|
|
121506
|
+
get withdrawalAddresses() {
|
|
121507
|
+
return this.withdrawalAddressModule;
|
|
121508
|
+
}
|
|
121509
|
+
/**
|
|
121510
|
+
* Add a Bitcoin address to the connected wallet's approved-withdrawal allowlist.
|
|
121511
|
+
* Usable only after the registry's delay (default 24h) elapses.
|
|
121512
|
+
*/
|
|
121513
|
+
async addApprovedWithdrawalAddress(btcAddress) {
|
|
121514
|
+
return this.withdrawalAddressModule.addAddress(btcAddress);
|
|
121515
|
+
}
|
|
121516
|
+
/** Remove a Bitcoin address from the connected wallet's allowlist (immediate). */
|
|
121517
|
+
async removeApprovedWithdrawalAddress(btcAddress) {
|
|
121518
|
+
return this.withdrawalAddressModule.removeAddress(btcAddress);
|
|
121519
|
+
}
|
|
121520
|
+
/**
|
|
121521
|
+
* Read the connected wallet's (or `user`'s) approved-address entries from the
|
|
121522
|
+
* contract (hashes + timestamps + derived approval state). For human-readable
|
|
121523
|
+
* address strings, query the subgraph `WithdrawalAddressBook`.
|
|
121524
|
+
*/
|
|
121525
|
+
async getApprovedWithdrawalAddresses(user) {
|
|
121526
|
+
let target = user;
|
|
121527
|
+
if (!target) {
|
|
121528
|
+
const signerRes = this.contractManager.getSigner();
|
|
121529
|
+
if (!signerRes.success)
|
|
121530
|
+
return signerRes;
|
|
121531
|
+
target = await signerRes.value.getAddress();
|
|
121532
|
+
}
|
|
121533
|
+
return this.withdrawalAddressModule.getEntries(target);
|
|
121534
|
+
}
|
|
121236
121535
|
/**
|
|
121237
121536
|
* Withdraw Bitcoin from a position
|
|
121238
121537
|
*
|
|
@@ -121317,6 +121616,48 @@ Error data: ${errorData || "none"}`
|
|
|
121317
121616
|
if (this.config.debug) {
|
|
121318
121617
|
log.info(` Position PKP ID: ${position.pkpId}`);
|
|
121319
121618
|
}
|
|
121619
|
+
if (this.withdrawalAddressModule.isConfigured()) {
|
|
121620
|
+
const rawStatus = position.status;
|
|
121621
|
+
const isLiquidated = Number(rawStatus) === 5 || String(rawStatus).toUpperCase() === "LIQUIDATED";
|
|
121622
|
+
let controller;
|
|
121623
|
+
if (isLiquidated) {
|
|
121624
|
+
const litValidatorAddr = this.getContractAddressesOrThrow().litActionValidator;
|
|
121625
|
+
const pkpId = position.pkpId;
|
|
121626
|
+
if (litValidatorAddr && pkpId) {
|
|
121627
|
+
try {
|
|
121628
|
+
const litValidator = new Contract(
|
|
121629
|
+
litValidatorAddr,
|
|
121630
|
+
["function pkpOwners(bytes32) view returns (address)"],
|
|
121631
|
+
this.getProviderOrThrow()
|
|
121632
|
+
);
|
|
121633
|
+
const owner = await litValidator.pkpOwners(
|
|
121634
|
+
pkpId
|
|
121635
|
+
);
|
|
121636
|
+
if (owner && owner !== ZeroAddress) {
|
|
121637
|
+
controller = owner;
|
|
121638
|
+
}
|
|
121639
|
+
} catch {
|
|
121640
|
+
}
|
|
121641
|
+
}
|
|
121642
|
+
} else {
|
|
121643
|
+
controller = position.borrower;
|
|
121644
|
+
if (!controller) {
|
|
121645
|
+
const signerRes = this.contractManager.getSigner();
|
|
121646
|
+
if (signerRes.success) {
|
|
121647
|
+
controller = await signerRes.value.getAddress();
|
|
121648
|
+
}
|
|
121649
|
+
}
|
|
121650
|
+
}
|
|
121651
|
+
if (controller) {
|
|
121652
|
+
const approval = await this.withdrawalAddressModule.assertApprovedForWithdrawal(
|
|
121653
|
+
controller,
|
|
121654
|
+
withdrawalAddress.trim()
|
|
121655
|
+
);
|
|
121656
|
+
if (!approval.success) {
|
|
121657
|
+
return { success: false, error: approval.error.message };
|
|
121658
|
+
}
|
|
121659
|
+
}
|
|
121660
|
+
}
|
|
121320
121661
|
let pkpPublicKey;
|
|
121321
121662
|
let pkpEthAddress;
|
|
121322
121663
|
const pkpCache = this.cacheManager.getCache("pkp-data", {
|
|
@@ -122631,6 +122972,78 @@ Error data: ${errorData || "none"}`
|
|
|
122631
122972
|
);
|
|
122632
122973
|
return psm.getAvailableReserves(stablecoinAddress);
|
|
122633
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
|
+
}
|
|
122634
123047
|
/**
|
|
122635
123048
|
* Wait for the subgraph to index up to (and including) the given block number.
|
|
122636
123049
|
* Call after on-chain actions (createLoan, mintUCD, etc.) before querying the subgraph.
|
|
@@ -123819,6 +124232,7 @@ export {
|
|
|
123819
124232
|
UCDConversions,
|
|
123820
124233
|
VALID_LIT_NETWORKS,
|
|
123821
124234
|
WeiConversions,
|
|
124235
|
+
WithdrawalAddressModule,
|
|
123822
124236
|
andThen,
|
|
123823
124237
|
assertProtocolNotPaused,
|
|
123824
124238
|
assertSafeServiceEndpoint,
|
|
@@ -123833,6 +124247,7 @@ export {
|
|
|
123833
124247
|
createLoanQuery,
|
|
123834
124248
|
createMockTokenManager,
|
|
123835
124249
|
createPKPManager,
|
|
124250
|
+
createWithdrawalAddressModule,
|
|
123836
124251
|
DiamondHandsSDK as default,
|
|
123837
124252
|
failure,
|
|
123838
124253
|
fetchProtocolPauseStatus,
|