@gvnrdao/dh-sdk 0.0.306 → 0.0.308
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/index.d.ts +4 -0
- package/dist/index.js +616 -122
- package/dist/index.mjs +539 -44
- package/dist/modules/diamond-hands-sdk.d.ts +79 -12
- package/dist/utils/stale-spend-invalidate-message.d.ts +46 -0
- package/dist/utils/withdrawal-reconciliation.utils.d.ts +65 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1508,6 +1508,19 @@ var require_pkg_src = __commonJS({
|
|
|
1508
1508
|
publicKey: "0x046da0ad6da7dd4a0063cbeac6f2bdb6a9889c2178b23470833356a8ee5630f7f0eee0db348d9d9aaaadd23eccf0063c8f68ee5e446abe30b882bf1de4c932bc21",
|
|
1509
1509
|
ethAddress: "0xc7e1588Db94Bbe92Ab209B833235144Fc5b97607"
|
|
1510
1510
|
}
|
|
1511
|
+
},
|
|
1512
|
+
btcUtxoInvalidator: {
|
|
1513
|
+
cid: "QmRue1EAjuJwCDTtTH4czdkkmDEfNpT7iudvwtjaRs6AdA",
|
|
1514
|
+
authorizedCidHex: cidToHex(
|
|
1515
|
+
"QmRue1EAjuJwCDTtTH4czdkkmDEfNpT7iudvwtjaRs6AdA"
|
|
1516
|
+
),
|
|
1517
|
+
name: "Btc Utxo Invalidator",
|
|
1518
|
+
description: "Production Btc Utxo Invalidator",
|
|
1519
|
+
version: "1.0.0",
|
|
1520
|
+
deployed: true,
|
|
1521
|
+
deployedAt: 1784801043540,
|
|
1522
|
+
size: 60717,
|
|
1523
|
+
hash: "2ca9736edf3d54bba7445491920cba28429029c32a2f2830cad831a37a3cb310"
|
|
1511
1524
|
}
|
|
1512
1525
|
};
|
|
1513
1526
|
function getDeploymentsForNetwork(network) {
|
|
@@ -2253,7 +2266,7 @@ ${errorReport}`);
|
|
|
2253
2266
|
}
|
|
2254
2267
|
init_debug_logger();
|
|
2255
2268
|
init_session_signature_cache();
|
|
2256
|
-
var
|
|
2269
|
+
var import_ethers17 = require("ethers");
|
|
2257
2270
|
var EXPIRED_LOAN_MIN_LIQUIDATION_THRESHOLD_BPS = 11e3;
|
|
2258
2271
|
var GRACE_PERIOD_DAYS = 30;
|
|
2259
2272
|
var SATOSHIS_PER_BITCOIN = 100000000n;
|
|
@@ -5083,12 +5096,12 @@ ${auth.clientId}`;
|
|
|
5083
5096
|
}
|
|
5084
5097
|
async function executeVaultSnapshot(params) {
|
|
5085
5098
|
global.ethers = {
|
|
5086
|
-
...
|
|
5099
|
+
...import_ethers17.ethers,
|
|
5087
5100
|
providers: {
|
|
5088
|
-
StaticJsonRpcProvider:
|
|
5101
|
+
StaticJsonRpcProvider: import_ethers17.ethers.JsonRpcProvider
|
|
5089
5102
|
},
|
|
5090
|
-
Contract:
|
|
5091
|
-
utils:
|
|
5103
|
+
Contract: import_ethers17.ethers.Contract,
|
|
5104
|
+
utils: import_ethers17.ethers
|
|
5092
5105
|
// v6 moved utils to top level
|
|
5093
5106
|
};
|
|
5094
5107
|
global.Lit = {
|
|
@@ -5568,6 +5581,7 @@ __export(src_exports, {
|
|
|
5568
5581
|
PKPManager: () => PKPManager,
|
|
5569
5582
|
PaymentType: () => PaymentType,
|
|
5570
5583
|
PositionStatus: () => PositionStatus,
|
|
5584
|
+
RECOVERY_INVALIDATE_ACTION: () => RECOVERY_INVALIDATE_ACTION,
|
|
5571
5585
|
SDKError: () => SDKError,
|
|
5572
5586
|
SDK_DEFAULTS: () => SDK_DEFAULTS,
|
|
5573
5587
|
SEPOLIA_CONTRACTS: () => SEPOLIA_CONTRACTS,
|
|
@@ -5580,6 +5594,8 @@ __export(src_exports, {
|
|
|
5580
5594
|
assertProtocolNotPaused: () => assertProtocolNotPaused,
|
|
5581
5595
|
assertSafeServiceEndpoint: () => assertSafeServiceEndpoint,
|
|
5582
5596
|
buildBtcExecuteEnvelope: () => buildBtcExecuteEnvelope,
|
|
5597
|
+
buildInvalidateMessageHash: () => buildInvalidateMessageHash,
|
|
5598
|
+
buildInvalidateStaleSpendEnvelope: () => buildInvalidateStaleSpendEnvelope,
|
|
5583
5599
|
collectFailures: () => collectFailures,
|
|
5584
5600
|
collectSuccesses: () => collectSuccesses,
|
|
5585
5601
|
combine: () => combine,
|
|
@@ -5591,6 +5607,7 @@ __export(src_exports, {
|
|
|
5591
5607
|
createPKPManager: () => createPKPManager,
|
|
5592
5608
|
createWithdrawalAddressModule: () => createWithdrawalAddressModule,
|
|
5593
5609
|
default: () => DiamondHandsSDK,
|
|
5610
|
+
defaultHttpGetJson: () => defaultHttpGetJson,
|
|
5594
5611
|
failure: () => failure,
|
|
5595
5612
|
fetchProtocolPauseStatus: () => fetchProtocolPauseStatus,
|
|
5596
5613
|
firstSuccess: () => firstSuccess,
|
|
@@ -5614,6 +5631,7 @@ __export(src_exports, {
|
|
|
5614
5631
|
mapError: () => mapError,
|
|
5615
5632
|
match: () => match,
|
|
5616
5633
|
numericToPositionStatus: () => numericToPositionStatus,
|
|
5634
|
+
reconcileAuthorizedSpend: () => reconcileAuthorizedSpend,
|
|
5617
5635
|
setPositionDelegate: () => setPositionDelegate,
|
|
5618
5636
|
success: () => success,
|
|
5619
5637
|
toPromise: () => toPromise,
|
|
@@ -5628,7 +5646,7 @@ __export(src_exports, {
|
|
|
5628
5646
|
module.exports = __toCommonJS(src_exports);
|
|
5629
5647
|
|
|
5630
5648
|
// src/modules/diamond-hands-sdk.ts
|
|
5631
|
-
var
|
|
5649
|
+
var import_ethers15 = require("ethers");
|
|
5632
5650
|
|
|
5633
5651
|
// src/types/result.ts
|
|
5634
5652
|
function success(value) {
|
|
@@ -7028,10 +7046,197 @@ async function isLaneGuardActiveOnProvider(provider) {
|
|
|
7028
7046
|
}
|
|
7029
7047
|
}
|
|
7030
7048
|
|
|
7031
|
-
// src/utils/
|
|
7049
|
+
// src/utils/withdrawal-reconciliation.utils.ts
|
|
7050
|
+
var defaultHttpGetJson = async (url) => {
|
|
7051
|
+
const res = await fetch(url, { headers: { accept: "application/json" } });
|
|
7052
|
+
let body = null;
|
|
7053
|
+
try {
|
|
7054
|
+
body = await res.json();
|
|
7055
|
+
} catch {
|
|
7056
|
+
body = null;
|
|
7057
|
+
}
|
|
7058
|
+
return { status: res.status, body };
|
|
7059
|
+
};
|
|
7060
|
+
async function reconcileAuthorizedSpend(spend, esploraBaseUrl, httpGetJson = defaultHttpGetJson) {
|
|
7061
|
+
const base = esploraBaseUrl.replace(/\/+$/, "");
|
|
7062
|
+
const fundingRes = await httpGetJson(`${base}/tx/${spend.txid}`);
|
|
7063
|
+
if (fundingRes.status === 404) {
|
|
7064
|
+
return {
|
|
7065
|
+
spend,
|
|
7066
|
+
status: "UNFUNDED",
|
|
7067
|
+
reason: `Funding tx ${spend.txid} not found on the network`
|
|
7068
|
+
};
|
|
7069
|
+
}
|
|
7070
|
+
if (fundingRes.status !== 200) {
|
|
7071
|
+
throw new Error(
|
|
7072
|
+
`Withdrawal reconciliation: esplora /tx/${spend.txid} returned HTTP ${fundingRes.status}`
|
|
7073
|
+
);
|
|
7074
|
+
}
|
|
7075
|
+
const funding = fundingRes.body;
|
|
7076
|
+
if (!funding?.status?.confirmed) {
|
|
7077
|
+
return {
|
|
7078
|
+
spend,
|
|
7079
|
+
status: "UNFUNDED",
|
|
7080
|
+
reason: `Funding tx ${spend.txid} is not confirmed yet`
|
|
7081
|
+
};
|
|
7082
|
+
}
|
|
7083
|
+
const output = funding.vout?.[spend.vout];
|
|
7084
|
+
if (!output || typeof output.value !== "number") {
|
|
7085
|
+
return {
|
|
7086
|
+
spend,
|
|
7087
|
+
status: "CORRUPT",
|
|
7088
|
+
reason: `Authorized vout ${spend.vout} does not exist on tx ${spend.txid} (${funding.vout?.length ?? 0} outputs)`
|
|
7089
|
+
};
|
|
7090
|
+
}
|
|
7091
|
+
const onChainOutputValue = output.value;
|
|
7092
|
+
if (onChainOutputValue !== spend.satoshis) {
|
|
7093
|
+
return {
|
|
7094
|
+
spend,
|
|
7095
|
+
status: "CORRUPT",
|
|
7096
|
+
onChainOutputValue,
|
|
7097
|
+
reason: `Authorization declares ${spend.satoshis} sats for ${spend.txid}:${spend.vout} but the on-chain output is ${onChainOutputValue} sats`
|
|
7098
|
+
};
|
|
7099
|
+
}
|
|
7100
|
+
if (spend.targetAmount > onChainOutputValue) {
|
|
7101
|
+
return {
|
|
7102
|
+
spend,
|
|
7103
|
+
status: "CORRUPT",
|
|
7104
|
+
onChainOutputValue,
|
|
7105
|
+
reason: `Authorized targetAmount ${spend.targetAmount} sats exceeds the ${onChainOutputValue}-sat output it is authorized against`
|
|
7106
|
+
};
|
|
7107
|
+
}
|
|
7108
|
+
const outspendRes = await httpGetJson(
|
|
7109
|
+
`${base}/tx/${spend.txid}/outspend/${spend.vout}`
|
|
7110
|
+
);
|
|
7111
|
+
if (outspendRes.status !== 200) {
|
|
7112
|
+
throw new Error(
|
|
7113
|
+
`Withdrawal reconciliation: esplora outspend for ${spend.txid}:${spend.vout} returned HTTP ${outspendRes.status}`
|
|
7114
|
+
);
|
|
7115
|
+
}
|
|
7116
|
+
const outspend = outspendRes.body;
|
|
7117
|
+
if (outspend?.spent) {
|
|
7118
|
+
const spendingTxid = typeof outspend.txid === "string" && outspend.txid ? outspend.txid : null;
|
|
7119
|
+
if (spendingTxid) {
|
|
7120
|
+
const spendingRes = await httpGetJson(`${base}/tx/${spendingTxid}`);
|
|
7121
|
+
if (spendingRes.status === 200) {
|
|
7122
|
+
const spendingTx = spendingRes.body;
|
|
7123
|
+
const includesOutpoint = (spendingTx.vin ?? []).some(
|
|
7124
|
+
(v) => v.txid === spend.txid && Number(v.vout) === spend.vout
|
|
7125
|
+
);
|
|
7126
|
+
if (includesOutpoint) {
|
|
7127
|
+
const paidToTargetSats = (spendingTx.vout ?? []).filter(
|
|
7128
|
+
(o) => (o.scriptpubkey_address ?? "").toLowerCase() === spend.targetAddress.toLowerCase()
|
|
7129
|
+
).reduce((sum, o) => sum + (o.value ?? 0), 0);
|
|
7130
|
+
if (paidToTargetSats > 0) {
|
|
7131
|
+
return {
|
|
7132
|
+
spend,
|
|
7133
|
+
status: "EXECUTED",
|
|
7134
|
+
spendingTxid,
|
|
7135
|
+
paidToTargetSats,
|
|
7136
|
+
onChainOutputValue,
|
|
7137
|
+
reason: `Outpoint spent by ${spendingTxid}, paying ${paidToTargetSats} sats to the authorized target \u2014 withdrawal complete`
|
|
7138
|
+
};
|
|
7139
|
+
}
|
|
7140
|
+
return {
|
|
7141
|
+
spend,
|
|
7142
|
+
status: "SPENT_MISMATCH",
|
|
7143
|
+
spendingTxid,
|
|
7144
|
+
onChainOutputValue,
|
|
7145
|
+
reason: `Outpoint spent by ${spendingTxid} which pays the authorized target nothing \u2014 authorization is unexecutable`
|
|
7146
|
+
};
|
|
7147
|
+
}
|
|
7148
|
+
}
|
|
7149
|
+
}
|
|
7150
|
+
return {
|
|
7151
|
+
spend,
|
|
7152
|
+
status: "EXECUTABLE",
|
|
7153
|
+
onChainOutputValue,
|
|
7154
|
+
reason: "Esplora claims the outpoint is spent but no spending tx provably includes it (known regtest-faucet artifact) \u2014 treated as unspent"
|
|
7155
|
+
};
|
|
7156
|
+
}
|
|
7157
|
+
return {
|
|
7158
|
+
spend,
|
|
7159
|
+
status: "EXECUTABLE",
|
|
7160
|
+
onChainOutputValue,
|
|
7161
|
+
reason: "Outpoint confirmed, unspent, and coherent with the authorization"
|
|
7162
|
+
};
|
|
7163
|
+
}
|
|
7164
|
+
|
|
7165
|
+
// src/utils/stale-spend-invalidate-message.ts
|
|
7032
7166
|
var import_ethers6 = require("ethers");
|
|
7167
|
+
var RECOVERY_INVALIDATE_ACTION = "btc-utxo-invalidator";
|
|
7033
7168
|
var QUANTUM_SECONDS = 60;
|
|
7034
7169
|
var QUANTUM_SAFE_THRESHOLD = 40;
|
|
7170
|
+
function buildInvalidateMessageHash(params) {
|
|
7171
|
+
const positionIdBytes32 = (0, import_ethers6.zeroPadValue)(
|
|
7172
|
+
params.positionId.startsWith("0x") ? params.positionId : `0x${params.positionId}`,
|
|
7173
|
+
32
|
|
7174
|
+
);
|
|
7175
|
+
const actionHash = (0, import_ethers6.keccak256)((0, import_ethers6.toUtf8Bytes)(RECOVERY_INVALIDATE_ACTION));
|
|
7176
|
+
return (0, import_ethers6.solidityPackedKeccak256)(
|
|
7177
|
+
[
|
|
7178
|
+
"bytes32",
|
|
7179
|
+
// positionId
|
|
7180
|
+
"uint256",
|
|
7181
|
+
// timestamp
|
|
7182
|
+
"uint256",
|
|
7183
|
+
// chainId
|
|
7184
|
+
"string",
|
|
7185
|
+
// utxoTxid (display order)
|
|
7186
|
+
"uint32",
|
|
7187
|
+
// utxoVout
|
|
7188
|
+
"bytes32"
|
|
7189
|
+
// actionHash
|
|
7190
|
+
],
|
|
7191
|
+
[
|
|
7192
|
+
positionIdBytes32,
|
|
7193
|
+
params.timestamp,
|
|
7194
|
+
params.chainId,
|
|
7195
|
+
params.utxoTxid,
|
|
7196
|
+
params.utxoVout,
|
|
7197
|
+
actionHash
|
|
7198
|
+
]
|
|
7199
|
+
);
|
|
7200
|
+
}
|
|
7201
|
+
async function buildInvalidateStaleSpendEnvelope(params) {
|
|
7202
|
+
const { positionId, utxoTxid, utxoVout, chainId, signer } = params;
|
|
7203
|
+
const nowSec = Date.now() / 1e3;
|
|
7204
|
+
const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS) * QUANTUM_SECONDS;
|
|
7205
|
+
const secsIntoQuantum = nowSec - currentQuantumStart;
|
|
7206
|
+
let timestamp;
|
|
7207
|
+
if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD) {
|
|
7208
|
+
const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS;
|
|
7209
|
+
const waitMs = Math.max(0, (nextQuantumStart - nowSec) * 1e3 + 500);
|
|
7210
|
+
await new Promise((r) => setTimeout(r, waitMs));
|
|
7211
|
+
timestamp = nextQuantumStart;
|
|
7212
|
+
} else {
|
|
7213
|
+
timestamp = currentQuantumStart;
|
|
7214
|
+
}
|
|
7215
|
+
const messageHash = buildInvalidateMessageHash({
|
|
7216
|
+
positionId,
|
|
7217
|
+
timestamp,
|
|
7218
|
+
chainId,
|
|
7219
|
+
utxoTxid,
|
|
7220
|
+
utxoVout
|
|
7221
|
+
});
|
|
7222
|
+
const signature = await signer.signMessage((0, import_ethers6.getBytes)(messageHash));
|
|
7223
|
+
const borrowerAddress = await signer.getAddress();
|
|
7224
|
+
return {
|
|
7225
|
+
positionId,
|
|
7226
|
+
utxoTxid,
|
|
7227
|
+
utxoVout,
|
|
7228
|
+
timestamp,
|
|
7229
|
+
chainId,
|
|
7230
|
+
action: RECOVERY_INVALIDATE_ACTION,
|
|
7231
|
+
signature,
|
|
7232
|
+
borrowerAddress
|
|
7233
|
+
};
|
|
7234
|
+
}
|
|
7235
|
+
|
|
7236
|
+
// src/utils/btc-withdrawal-message.ts
|
|
7237
|
+
var import_ethers7 = require("ethers");
|
|
7238
|
+
var QUANTUM_SECONDS2 = 60;
|
|
7239
|
+
var QUANTUM_SAFE_THRESHOLD2 = 40;
|
|
7035
7240
|
function hashBtcInputSet(utxos) {
|
|
7036
7241
|
if (!Array.isArray(utxos) || utxos.length === 0) {
|
|
7037
7242
|
throw new Error("hashBtcInputSet: at least one input is required");
|
|
@@ -7060,7 +7265,7 @@ function hashBtcInputSet(utxos) {
|
|
|
7060
7265
|
seen.add(key);
|
|
7061
7266
|
}
|
|
7062
7267
|
const canonical = normalized.sort((a, b) => a.txid < b.txid ? -1 : a.txid > b.txid ? 1 : a.vout - b.vout).map((u) => `${u.txid}:${u.vout}:${u.value}`).join("|");
|
|
7063
|
-
return (0,
|
|
7268
|
+
return (0, import_ethers7.keccak256)((0, import_ethers7.toUtf8Bytes)(canonical));
|
|
7064
7269
|
}
|
|
7065
7270
|
async function buildBtcExecuteEnvelope(params) {
|
|
7066
7271
|
const {
|
|
@@ -7094,26 +7299,26 @@ async function buildBtcExecuteEnvelope(params) {
|
|
|
7094
7299
|
}
|
|
7095
7300
|
const utxosHash = hashBtcInputSet(utxos);
|
|
7096
7301
|
const nowSec = Date.now() / 1e3;
|
|
7097
|
-
const currentQuantumStart = Math.floor(nowSec /
|
|
7302
|
+
const currentQuantumStart = Math.floor(nowSec / QUANTUM_SECONDS2) * QUANTUM_SECONDS2;
|
|
7098
7303
|
const secsIntoQuantum = nowSec - currentQuantumStart;
|
|
7099
7304
|
let timestamp;
|
|
7100
|
-
if (secsIntoQuantum >
|
|
7101
|
-
const nextQuantumStart = currentQuantumStart +
|
|
7305
|
+
if (secsIntoQuantum > QUANTUM_SAFE_THRESHOLD2) {
|
|
7306
|
+
const nextQuantumStart = currentQuantumStart + QUANTUM_SECONDS2;
|
|
7102
7307
|
const waitMs = Math.max(0, (nextQuantumStart - nowSec) * 1e3 + 500);
|
|
7103
7308
|
await new Promise((r) => setTimeout(r, waitMs));
|
|
7104
7309
|
timestamp = nextQuantumStart;
|
|
7105
7310
|
} else {
|
|
7106
7311
|
timestamp = currentQuantumStart;
|
|
7107
7312
|
}
|
|
7108
|
-
const actionHash = (0,
|
|
7109
|
-
(0,
|
|
7313
|
+
const actionHash = (0, import_ethers7.keccak256)(
|
|
7314
|
+
(0, import_ethers7.toUtf8Bytes)("execute-btc-withdrawal")
|
|
7110
7315
|
);
|
|
7111
7316
|
const utxoIdentifier = `${txid}:${vout}`;
|
|
7112
|
-
const positionIdBytes32 = (0,
|
|
7317
|
+
const positionIdBytes32 = (0, import_ethers7.zeroPadValue)(
|
|
7113
7318
|
positionId.startsWith("0x") ? positionId : `0x${positionId}`,
|
|
7114
7319
|
32
|
|
7115
7320
|
);
|
|
7116
|
-
const messageHash = (0,
|
|
7321
|
+
const messageHash = (0, import_ethers7.solidityPackedKeccak256)(
|
|
7117
7322
|
[
|
|
7118
7323
|
"bytes32",
|
|
7119
7324
|
// positionId
|
|
@@ -7146,7 +7351,7 @@ async function buildBtcExecuteEnvelope(params) {
|
|
|
7146
7351
|
actionHash
|
|
7147
7352
|
]
|
|
7148
7353
|
);
|
|
7149
|
-
const userSignature = await signer.signMessage((0,
|
|
7354
|
+
const userSignature = await signer.signMessage((0, import_ethers7.getBytes)(messageHash));
|
|
7150
7355
|
const borrowerAddress = await signer.getAddress();
|
|
7151
7356
|
return {
|
|
7152
7357
|
positionId,
|
|
@@ -7210,7 +7415,7 @@ function maybeTemperSignature(signature, shouldTemper, operationName) {
|
|
|
7210
7415
|
}
|
|
7211
7416
|
|
|
7212
7417
|
// src/utils/address-conversion.utils.ts
|
|
7213
|
-
var
|
|
7418
|
+
var import_ethers8 = require("ethers");
|
|
7214
7419
|
|
|
7215
7420
|
// src/utils/chunks/bitcoin-utils.ts
|
|
7216
7421
|
var import_sha256 = require("@noble/hashes/sha256");
|
|
@@ -7494,7 +7699,7 @@ function normalizeBitcoinAddress(address) {
|
|
|
7494
7699
|
}
|
|
7495
7700
|
|
|
7496
7701
|
// src/protocol/protocol-pause.ts
|
|
7497
|
-
var
|
|
7702
|
+
var import_ethers9 = require("ethers");
|
|
7498
7703
|
var GET_PROTOCOL_PAUSE_STATUS_ABI = [
|
|
7499
7704
|
"function getProtocolPauseStatus() view returns (tuple(bool positionManagerPaused, bool positionManagerLiquidationsPaused, bool positionManagerCorePaused, bool loanOperationsPaused, bool collateralManagerPaused, bool liquidationManagerPaused, bool circuitBreakerPaused, bool ucdControllerPaused, bool ucdTokenPaused, bool simplePsmPaused))"
|
|
7500
7705
|
];
|
|
@@ -7516,7 +7721,7 @@ function rowToStatus(row) {
|
|
|
7516
7721
|
return row;
|
|
7517
7722
|
}
|
|
7518
7723
|
async function fetchProtocolPauseStatus(provider, positionManagerAddress) {
|
|
7519
|
-
const iface = new
|
|
7724
|
+
const iface = new import_ethers9.Interface(GET_PROTOCOL_PAUSE_STATUS_ABI);
|
|
7520
7725
|
const data = iface.encodeFunctionData("getProtocolPauseStatus", []);
|
|
7521
7726
|
const raw = await provider.call({ to: positionManagerAddress, data });
|
|
7522
7727
|
const decoded = iface.decodeFunctionResult("getProtocolPauseStatus", raw);
|
|
@@ -7649,7 +7854,7 @@ function extractOptionalLitSignature(raw) {
|
|
|
7649
7854
|
}
|
|
7650
7855
|
|
|
7651
7856
|
// src/modules/contract/contract-manager.module.ts
|
|
7652
|
-
var
|
|
7857
|
+
var import_ethers10 = require("ethers");
|
|
7653
7858
|
init_deployment_addresses();
|
|
7654
7859
|
var POSITION_MANAGER_ABI = [
|
|
7655
7860
|
"function createPosition(bytes32 pkpId, bytes calldata validatorSignature, string mainnetVaultAddress, string regtestVaultAddress, uint256 selectedTermMonths, uint256 validatorVersion, bytes calldata pkpPublicKey) external returns (bytes32 positionId)",
|
|
@@ -7726,43 +7931,43 @@ var ContractManager = class {
|
|
|
7726
7931
|
}
|
|
7727
7932
|
const contractRunner = runner;
|
|
7728
7933
|
const contracts = {
|
|
7729
|
-
positionManager: new
|
|
7934
|
+
positionManager: new import_ethers10.Contract(
|
|
7730
7935
|
contractAddresses.positionManager,
|
|
7731
7936
|
POSITION_MANAGER_ABI,
|
|
7732
7937
|
contractRunner
|
|
7733
7938
|
),
|
|
7734
|
-
loanOperationsManager: new
|
|
7735
|
-
contractAddresses.loanOperationsManager ||
|
|
7939
|
+
loanOperationsManager: new import_ethers10.Contract(
|
|
7940
|
+
contractAddresses.loanOperationsManager || import_ethers10.ZeroAddress,
|
|
7736
7941
|
LOAN_OPS_ABI,
|
|
7737
7942
|
contractRunner
|
|
7738
7943
|
),
|
|
7739
|
-
ucdController: new
|
|
7944
|
+
ucdController: new import_ethers10.Contract(
|
|
7740
7945
|
contractAddresses.ucdToken,
|
|
7741
7946
|
UCD_CONTROLLER_ABI,
|
|
7742
7947
|
contractRunner
|
|
7743
7948
|
),
|
|
7744
|
-
priceFeed: new
|
|
7745
|
-
contractAddresses.priceFeedConsumer ||
|
|
7949
|
+
priceFeed: new import_ethers10.Contract(
|
|
7950
|
+
contractAddresses.priceFeedConsumer || import_ethers10.ZeroAddress,
|
|
7746
7951
|
PRICE_FEED_ABI,
|
|
7747
7952
|
contractRunner
|
|
7748
7953
|
),
|
|
7749
|
-
termManager: new
|
|
7750
|
-
contractAddresses.termManager ||
|
|
7954
|
+
termManager: new import_ethers10.Contract(
|
|
7955
|
+
contractAddresses.termManager || import_ethers10.ZeroAddress,
|
|
7751
7956
|
TERM_MANAGER_ABI,
|
|
7752
7957
|
contractRunner
|
|
7753
7958
|
),
|
|
7754
|
-
circuitBreaker: new
|
|
7755
|
-
contractAddresses.circuitBreaker ||
|
|
7959
|
+
circuitBreaker: new import_ethers10.Contract(
|
|
7960
|
+
contractAddresses.circuitBreaker || import_ethers10.ZeroAddress,
|
|
7756
7961
|
CIRCUIT_BREAKER_ABI,
|
|
7757
7962
|
contractRunner
|
|
7758
7963
|
),
|
|
7759
|
-
liquidationManager: new
|
|
7760
|
-
contractAddresses.liquidationManager ||
|
|
7964
|
+
liquidationManager: new import_ethers10.Contract(
|
|
7965
|
+
contractAddresses.liquidationManager || import_ethers10.ZeroAddress,
|
|
7761
7966
|
LIQUIDATION_MANAGER_ABI,
|
|
7762
7967
|
contractRunner
|
|
7763
7968
|
),
|
|
7764
|
-
bitcoinWithdrawalAddressRegistry: new
|
|
7765
|
-
contractAddresses.bitcoinWithdrawalAddressRegistry ||
|
|
7969
|
+
bitcoinWithdrawalAddressRegistry: new import_ethers10.Contract(
|
|
7970
|
+
contractAddresses.bitcoinWithdrawalAddressRegistry || import_ethers10.ZeroAddress,
|
|
7766
7971
|
BITCOIN_WITHDRAWAL_ADDRESS_REGISTRY_ABI,
|
|
7767
7972
|
contractRunner
|
|
7768
7973
|
)
|
|
@@ -7812,13 +8017,13 @@ var ContractManager = class {
|
|
|
7812
8017
|
const address = addresses[key];
|
|
7813
8018
|
if (!address) {
|
|
7814
8019
|
missing.push(String(key));
|
|
7815
|
-
} else if (!(0,
|
|
8020
|
+
} else if (!(0, import_ethers10.isAddress)(address)) {
|
|
7816
8021
|
invalid.push(String(key));
|
|
7817
8022
|
}
|
|
7818
8023
|
}
|
|
7819
8024
|
for (const key of optionalAddresses) {
|
|
7820
8025
|
const address = addresses[key];
|
|
7821
|
-
if (address && !(0,
|
|
8026
|
+
if (address && !(0, import_ethers10.isAddress)(address)) {
|
|
7822
8027
|
invalid.push(String(key));
|
|
7823
8028
|
}
|
|
7824
8029
|
}
|
|
@@ -8794,7 +8999,7 @@ function createPKPManager(config) {
|
|
|
8794
8999
|
}
|
|
8795
9000
|
|
|
8796
9001
|
// src/modules/loan/loan-creator.module.ts
|
|
8797
|
-
var
|
|
9002
|
+
var import_ethers11 = require("ethers");
|
|
8798
9003
|
var import_dh_lit_actions = __toESM(require_pkg_src());
|
|
8799
9004
|
var LoanCreator = class {
|
|
8800
9005
|
config;
|
|
@@ -9124,11 +9329,11 @@ var LoanCreator = class {
|
|
|
9124
9329
|
try {
|
|
9125
9330
|
const mainnetVaultAddress = bitcoinAddresses.mainnet;
|
|
9126
9331
|
const regtestVaultAddress = bitcoinAddresses.regtest;
|
|
9127
|
-
const pkpIdBytes32 = (0,
|
|
9128
|
-
(0,
|
|
9332
|
+
const pkpIdBytes32 = (0, import_ethers11.zeroPadValue)(
|
|
9333
|
+
(0, import_ethers11.toBeHex)(BigInt(pkpData.tokenId)),
|
|
9129
9334
|
32
|
|
9130
9335
|
);
|
|
9131
|
-
const pkpPublicKeyUncompressed =
|
|
9336
|
+
const pkpPublicKeyUncompressed = import_ethers11.SigningKey.computePublicKey(
|
|
9132
9337
|
pkpData.publicKey,
|
|
9133
9338
|
false
|
|
9134
9339
|
);
|
|
@@ -9141,7 +9346,7 @@ var LoanCreator = class {
|
|
|
9141
9346
|
);
|
|
9142
9347
|
log.debug(`BigInt conversion: ${BigInt(pkpData.tokenId).toString()}`);
|
|
9143
9348
|
log.debug(
|
|
9144
|
-
`Hex from BigInt: ${(0,
|
|
9349
|
+
`Hex from BigInt: ${(0, import_ethers11.toBeHex)(BigInt(pkpData.tokenId))}`
|
|
9145
9350
|
);
|
|
9146
9351
|
log.debug(`Final bytes32 (zero-padded): ${pkpIdBytes32}`);
|
|
9147
9352
|
log.debug(
|
|
@@ -9305,8 +9510,8 @@ var LoanCreator = class {
|
|
|
9305
9510
|
}
|
|
9306
9511
|
}
|
|
9307
9512
|
if (this.config.debug) {
|
|
9308
|
-
const pkpIdBytes32Check = (0,
|
|
9309
|
-
(0,
|
|
9513
|
+
const pkpIdBytes32Check = (0, import_ethers11.zeroPadValue)(
|
|
9514
|
+
(0, import_ethers11.toBeHex)(BigInt(pkpData.tokenId)),
|
|
9310
9515
|
32
|
|
9311
9516
|
);
|
|
9312
9517
|
log.error("\u274C Loan creation transaction failed", {
|
|
@@ -9352,8 +9557,8 @@ var LoanCreator = class {
|
|
|
9352
9557
|
const newEventAbi = [
|
|
9353
9558
|
"event PositionCreated(bytes32 indexed positionId, bytes32 indexed pkpId, address indexed borrower, uint256 requestedCollateralRatio, uint256 selectedTerm, uint256 expiryAt)"
|
|
9354
9559
|
];
|
|
9355
|
-
const oldIface = new
|
|
9356
|
-
const newIface = new
|
|
9560
|
+
const oldIface = new import_ethers11.Interface(oldEventAbi);
|
|
9561
|
+
const newIface = new import_ethers11.Interface(newEventAbi);
|
|
9357
9562
|
let positionId;
|
|
9358
9563
|
if (this.config.debug) {
|
|
9359
9564
|
log.info("\u{1F50D} Parsing transaction receipt logs", {
|
|
@@ -9447,7 +9652,7 @@ var LoanStatus = /* @__PURE__ */ ((LoanStatus2) => {
|
|
|
9447
9652
|
})(LoanStatus || {});
|
|
9448
9653
|
|
|
9449
9654
|
// src/modules/loan/loan-query.module.ts
|
|
9450
|
-
var
|
|
9655
|
+
var import_ethers12 = require("ethers");
|
|
9451
9656
|
var POSITION_CORE_ABI = [
|
|
9452
9657
|
"function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
|
|
9453
9658
|
];
|
|
@@ -9745,7 +9950,7 @@ var LoanQuery = class {
|
|
|
9745
9950
|
const isChipotlePkpId2 = typeof rawId === "string" && rawId.length === 40 && !rawId.toLowerCase().startsWith("04");
|
|
9746
9951
|
if (isChipotlePkpId2) {
|
|
9747
9952
|
if (this.config.positionManagerCoreAddress && this.config.provider) {
|
|
9748
|
-
const pmContract = new
|
|
9953
|
+
const pmContract = new import_ethers12.Contract(
|
|
9749
9954
|
this.config.positionManagerCoreAddress,
|
|
9750
9955
|
POSITION_CORE_ABI,
|
|
9751
9956
|
this.config.provider
|
|
@@ -10068,7 +10273,7 @@ function createLoanQuery(config) {
|
|
|
10068
10273
|
}
|
|
10069
10274
|
|
|
10070
10275
|
// src/modules/withdrawal-address/withdrawal-address.module.ts
|
|
10071
|
-
var
|
|
10276
|
+
var import_ethers13 = require("ethers");
|
|
10072
10277
|
var WithdrawalAddressModule = class {
|
|
10073
10278
|
config;
|
|
10074
10279
|
graphClient;
|
|
@@ -10085,7 +10290,7 @@ var WithdrawalAddressModule = class {
|
|
|
10085
10290
|
if (!res.success)
|
|
10086
10291
|
return res;
|
|
10087
10292
|
const target = res.value.target;
|
|
10088
|
-
if (!target || target ===
|
|
10293
|
+
if (!target || target === import_ethers13.ZeroAddress) {
|
|
10089
10294
|
return failure(
|
|
10090
10295
|
new SDKError({
|
|
10091
10296
|
code: "SDK_WITHDRAWAL_REGISTRY_NOT_CONFIGURED",
|
|
@@ -10103,7 +10308,7 @@ var WithdrawalAddressModule = class {
|
|
|
10103
10308
|
}
|
|
10104
10309
|
/** keccak256 of the canonicalized address — matches the on-chain key. */
|
|
10105
10310
|
static addressHash(btcAddress) {
|
|
10106
|
-
return (0,
|
|
10311
|
+
return (0, import_ethers13.keccak256)((0, import_ethers13.toUtf8Bytes)(normalizeBitcoinAddress(btcAddress)));
|
|
10107
10312
|
}
|
|
10108
10313
|
/**
|
|
10109
10314
|
* Add a Bitcoin address to the caller's allowlist. It becomes usable only
|
|
@@ -13149,7 +13354,7 @@ var DiamondHandsGraph = class {
|
|
|
13149
13354
|
};
|
|
13150
13355
|
|
|
13151
13356
|
// src/contracts/typechain-contracts/factories/src/psm/SimplePSMV2__factory.ts
|
|
13152
|
-
var
|
|
13357
|
+
var import_ethers14 = require("ethers");
|
|
13153
13358
|
var _abi = [
|
|
13154
13359
|
{
|
|
13155
13360
|
inputs: [],
|
|
@@ -15717,7 +15922,7 @@ var _abi = [
|
|
|
15717
15922
|
];
|
|
15718
15923
|
var _bytecode = "0x60a080604052346100ea57306080527ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005460ff8160401c166100d9576002600160401b03196001600160401b03821601610073575b60405161485a90816100f0823960805181818161278e01526128870152f35b6001600160401b0319166001600160401b039081177ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005581527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a13880610054565b63f92ee8a960e01b60005260046000fd5b600080fdfe6080604052600436101561001257600080fd5b6000803560e01c8062f7fce91461384657806301ffc9a7146137d5578063021d28931461377c5780630871b20614613743578063114249d214610f6157806311d954f81461371a57806313da3166146136e15780631d44a904146136385780631f77bf65146135ff578063248a9ca3146135e05780632b83cccd146131205780632f2ff15d146130ee57806334bac370146130b557806334e181251461307c57806336568abe14613037578063373c86b614612ffe5780633f4ba83a14612f375780634373b57214612f0e5780634451e89b14612b3a5780634ebd25a514612b015780634f1ef2861461280c5780635273b6f6146127e357806352d1902d1461277b578063568fafca146126ed57806359d5d02a146124205780635bc26aea146123eb5780635c975abb146123bb5780635ecc27081461229d5780638456cb59146121a257806385c15d9a1461216957806389d3ad00146120a25780638bff608e146120695780639010d07c1461201657806390ad8b4014611ffa57806391d1485414611fa15780639b759bf714611f5e5780639baf58d214611f415780639f1d0f59146118a8578063a217fddf1461188c578063a3246ad3146117cf578063ad3cb1cc14611788578063b492fc691461168e578063b9f637af14611463578063bf7d911914611424578063c4c5f62414611371578063c55f15ea1461134e578063ca15c87314611317578063ca2ce65d146112de578063cc1f8ffa146112ac578063cf46075e146111a2578063d21a74ff14611165578063d2f8253614611142578063d547741f14611107578063d5d3f78b14610f9a578063d66bd52414610f61578063e1f1c4a714610f44578063e1f3962c14610f18578063ec2f96fe14610ef4578063eda5a26a14610af7578063f1a1eb8414610ab4578063f385116d14610a7b578063f77c479114610a54578063f8c8765e14610661578063faaebd2114610628578063facdfb5e14610488578063fc99bd9a14610377578063fe32e7281461033e5763ffa1ad741461030857600080fd5b3461033b578060031936011261033b57610337610323613a68565b604051918291602083526020830190613a17565b0390f35b80fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361036661392e565b168152601283522054604051908152f35b503461033b57604036600319011261033b5761039161392e565b6010546024359291906001600160a01b03163303610479576001600160a01b03168082526002602052604082205490929060ff16156104665780156104575782825260076020526040822054926103e88285613cb0565b848110610448576001600160ff1b0381116104395760008051602061482e833981519152604085968493846104369852600760205280838a205582519182526020820152a23090339061421c565b80f35b630700fcb360e11b8452600484fd5b63446c8cc960e01b8452600484fd5b63162908e360e11b8252600482fd5b506024916374ed46ad60e01b8252600452fd5b6349db3bd360e01b8252600482fd5b503461033b57602036600319011261033b576104a261392e565b6104aa613f12565b6010546001600160a01b03163303610479576001600160a01b03168082526002602052604082205460ff161561061657808252600760205260408220546040516370a0823160e01b8152306004820152602081602481865afa90811561060b5784916105d4575b50818111156105c5576105248282613b6c565b8215908115610570575b505060008051602061482e833981519152916040918486526007602052808387205582519182526020820152a260016000805160206147ce8339815191525580f35b61271081029080820461271014901517156105b157606484029184830460641417156105b157116105a257388061052e565b63a73af74d60e01b8452600484fd5b634e487b7160e01b86526011600452602486fd5b6105cf8183613b6c565b610524565b90506020813d602011610603575b816105ef602093836139c3565b810103126105fe575138610511565b600080fd5b3d91506105e2565b6040513d86823e3d90fd5b6374ed46ad60e01b8252600452602490fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361065061392e565b168152600483522054604051908152f35b503461033b57608036600319011261033b5761067b61392e565b610683613944565b6044356001600160a01b03811690818103610a50576064356001600160a01b0381169390849003610a4c5760008051602061480e83398151915254604081901c60ff161595906001600160401b031680159081610a44575b6001149081610a3a575b159081610a31575b50610a225760008051602061480e83398151915280546001600160401b0319166001179055856109fd575b6001600160a01b03169081156109ee576001600160a01b03169081156109df5783156109d05761074661448a565b61074e61448a565b61075661448a565b61075e61448a565b60016000805160206147ce8339815191525561077861448a565b61078061448a565b86546001600160a01b0319908116919091178755600180549182168317905560405163313ce56760e01b8152909190602081600481855afa88918161099f575b506107d457633a24e95b60e11b8852600488fd5b6001600160a81b03199092161760a091821b60ff60a01b16176001819055901c60ff16601119810161098d575061080b8186614348565b80610965575b156109205761082e816000805160206147ee833981519152614348565b8061092f575b15610920576108519060008051602061470e833981519152614348565b90816108e9575b50156108da57806108af575b5061086c5780f35b60ff60401b1960008051602061480e833981519152541660008051602061480e833981519152556000805160206146ee833981519152602060405160018152a180f35b601080546001600160a01b031916821790558260008051602061474e8339815191528180a338610864565b63cf5a8e3360e01b8352600483fd5b6109199060008051602061470e83398151915286526000805160206146ae833981519152602052604086206144d0565b5038610858565b63cf5a8e3360e01b8552600485fd5b6000805160206147ee83398151915286526000805160206146ae83398151915260205261095f83604088206144d0565b50610834565b8580526000805160206146ae83398151915260205261098783604088206144d0565b50610811565b63167738cf60e21b8652600452602485fd5b6109c291925060203d6020116109c9575b6109ba81836139c3565b810190613ba9565b90386107c0565b503d6109b0565b630b5eba9f60e41b8752600487fd5b63c1ab6dc160e01b8752600487fd5b6336abb4df60e11b8752600487fd5b60008051602061480e833981519152805460ff60401b1916600160401b179055610718565b63f92ee8a960e01b8752600487fd5b905015386106ed565b303b1591506106e5565b8791506106db565b8580fd5b8480fd5b503461033b578060031936011261033b57546040516001600160a01b039091168152602090f35b503461033b57602036600319011261033b576020906040906001600160a01b03610aa361392e565b168152600a83522054604051908152f35b503461033b57604036600319011261033b576020906040906001600160a01b03610adc61392e565b16815260158352818120602435825283522054604051908152f35b503461033b5761016036600319011261033b57610b1261392e565b90606435604435602435610b24613a58565b9160a4359160c43560e43561010435916101243595610144359760018060a01b03601054163303610ee5576001600160a01b038c16808c52600260205260408c2054909a9060ff16610ed1578a15610ec2578615610eb3576127108811610e99576103e88111610e815760ff82169c60128e118e8115610e76575b50610e6257803b15610e4e578915610e3a578a15610e265782610bc191614260565b84151580610e1d575b610e065785151580610dfd575b610de6578b9c602460208d9e9d604051928380926370a0823160e01b82523060048301525afa9c8d15610dda579c610da6575b506001600160ff1b038c11610d97578a8d8f9760408f97838f918f8f8f8f90859f988f99879f9660008051602061476e8339815191529f978b9f988f8d6000805160206146ce8339815191529f988e8e610d4f9b60008051602061468e8339815191529f8f8f8487526002602052878720600160ff198254161790558487526003602052878720558386526004602052868620558285526006602052878686205582855260056020528585209060ff19825416179055818452600c6020528885852055818452600d6020528985852055818452600e6020528a85852055818452600f6020528b8585205581845260076020528484205582526012602052828220558d8152601360205220558a7f991d1ef1b5c0820d213328cba6682059e00a50e49c469a454eb3557e78eaf6668e80518b81528c6020820152a28c5198899889613cbd565b0390a28151908b82526020820152a28151908782526020820152a280610d73578280f35b604060008051602061482e833981519152918151908582526020820152a281808280f35b63556e7a8160e01b8e5260048efd5b909b506020813d602011610dd2575b81610dc2602093836139c3565b810103126105fe57519a38610c0a565b3d9150610db5565b604051903d90823e3d90fd5b60448c858863dd85772b60e01b8352600452602452fd5b50838610610bd7565b60448c8487637449915760e01b8352600452602452fd5b50828510610bca565b636835314760e11b8d52600160045260248dfd5b636835314760e11b8d5260048d905260248dfd5b63377e3f9960e21b8d5260048c905260248dfd5b63ca95039160e01b8d5260048e905260248dfd5b60069150108e610b9f565b631051834f60e11b8c526004526103e860245260448bfd5b63c1e9a14160e01b8c52600488905261271060245260448cfd5b63a2ec3a5560e01b8c5260048cfd5b63df407ac560e01b8c5260048cfd5b6317f4215b60e21b8c5260048b905260248cfd5b6349db3bd360e01b8b5260048bfd5b503461033b578060031936011261033b57602060ff60015460a01c16604051908152f35b503461033b57602036600319011261033b576020610f3c610f3761392e565b613df5565b604051908152f35b503461033b578060031936011261033b5760206040516127108152f35b503461033b57602036600319011261033b576020906040906001600160a01b03610f8961392e565b168152600783522054604051908152f35b503461033b57602036600319011261033b57610fb461392e565b6010546001600160a01b03163303610479576001600160a01b03168082526002602052604082205460ff16156106165780825260076020526040822054806110f1575080825260026020526040822060ff1981541690558082526003602052816040812055808252600460205281604081205580825260056020526040822060ff198154169055808252600c602052816040812055808252600d602052816040812055808252600e602052816040812055808252600f602052816040812055808252600660205281604081205580825260076020526040822054818352600760205282604081205560405190827f3302a1b37f04242bb55603f5449e7ecd690a35eef08ba1353c48c20e2aae9cda8580a2806110ce578380f35b8160409160008051602061482e8339815191529352846020820152a23880808380f35b604492916376bc059760e11b8352600452602452fd5b503461033b57604036600319011261033b5761113e600435611127613944565b9061113961113482613b79565b614088565b61411a565b5080f35b503461033b578060031936011261033b57602060ff600854166040519015158152f35b503461033b57602036600319011261033b5760209060ff906040906001600160a01b0361119061392e565b16815260058452205416604051908152f35b503461033b57602036600319011261033b576111bc61392e565b6111c4613f12565b6010546001600160a01b03163303610479576001600160a01b03168082526002602052604082205460ff161561061657808252600760205260408220546040516370a0823160e01b8152306004820152602081602481865afa90811561060b57849161126c575b5060008051602061482e833981519152916040918486526007602052808387205582519182526020820152a260016000805160206147ce8339815191525580f35b90506020813d6020116112a4575b81611287602093836139c3565b810103126105fe575160008051602061482e83398151915261122b565b3d915061127a565b503461033b57604036600319011261033b5760206112d46112cb61392e565b60243590613cf6565b6040519015158152f35b503461033b57602036600319011261033b576020906040906001600160a01b0361130661392e565b168152601383522054604051908152f35b503461033b57602036600319011261033b57604060209160043581526000805160206146ae83398151915283522054604051908152f35b503461033b578060031936011261033b576020604051670de0b6b3a76400008152f35b503461033b57604036600319011261033b5761138b61392e565b6010546024359291906001600160a01b03163303610479576001600160a01b031680825260076020526040822054929081841061140d578060008051602061482e8339815191526040866113e3866104369899613b6c565b84895260076020528289205583885260076020528188205482519182526020820152a2339061404c565b5091604492633cb8e07360e01b8352600452602452fd5b503461033b57602036600319011261033b5760209060ff906040906001600160a01b0361144f61392e565b168152600284522054166040519015158152f35b503461033b5761012036600319011261033b5761147e61392e565b6064359190604435602435611491613a58565b601054610104359660e4359260c4359260a43592906001600160a01b0316330361167f576001600160a01b038816808a52600260205260408a205490989060ff161561166b57861561165c576127108811611642576103e882116116285760ff83169060128211801561161e575b61160a578361150d91614260565b85151580611601575b6115ea578a1515806115e1575b6115ca579260008051602061468e83398151915297969592828c956115c4979460408e8e80825260036020528c8383205580825260046020528d838320558152600660205220558b8d52600560205260408d209060ff198254161790558a8c52600c6020528260408d20558a8c52600d6020528360408d20558a8c52600e6020528460408d20558a8c52600f6020528560408d205560405198899889613cbd565b0390a280f35b60448a868d63dd85772b60e01b8352600452602452fd5b50848b10611523565b60448a8588637449915760e01b8352600452602452fd5b50838610611516565b63ca95039160e01b8b52600482905260248bfd5b50600682106114ff565b631051834f60e11b8a5260048290526103e860245260448afd5b63c1e9a14160e01b8a52600488905261271060245260448afd5b63a2ec3a5560e01b8a5260048afd5b6374ed46ad60e01b8a52600489905260248afd5b6349db3bd360e01b8952600489fd5b503461033b57604036600319011261033b576116a861392e565b6001600160a01b0316808252600260205260408220546024359060ff16156117745780156117655761271061172a604085670de0b6b3a76400006117196117329688859a52600560205260ff85852054169080916012811061173f575b505088845260036020528484205490613a8b565b049581526004602052205484613a8b565b048092613b6c565b9082519182526020820152f35b61175e925060ff61175261175892613ad4565b16613ae5565b90613a8b565b3880611705565b63162908e360e11b8352600483fd5b6374ed46ad60e01b83526004829052602483fd5b503461033b578060031936011261033b5761033760408051906117ab81836139c3565b60058252640352e302e360dc1b602083015251918291602083526020830190613a17565b503461033b57602036600319011261033b5760043581526000805160206146ae83398151915260205260408120604051908160208254918281520190819285526020852090855b818110611876575050508261182c9103836139c3565b604051928392602084019060208552518091526040840192915b818110611854575050500390f35b82516001600160a01b0316845285945060209384019390920191600101611846565b8254845260209093019260019283019201611816565b503461033b578060031936011261033b57602090604051908152f35b503461033b576118b736613969565b9190926118c2613f12565b6118ca613f4e565b338152600960205260408120544303611f1f57338152600a602052600360408220541015611f1057338152600a602052604081206119088154613b9a565b90555b6001600160a01b0382168082526002602052604082205490929060ff16611e6f575b828252600260205260ff60408320541615610466578415610457578315611e6057828252600c60205260408220548510611e3b57828252600e60205260408220548015611e2c57808611611e155750846119869161415e565b6040516370a0823160e01b8152306004820152602081602481865afa908115611e0a578291611dd8575b506119bd8530338661421c565b6040516370a0823160e01b8152306004820152602081602481875afa908115611cef57908692918491611d9f575b50906119f691613b6c565b10611d905781815260076020526040812054611a128582613cb0565b818110611d81576001600160ff1b038111611d72576040849260008051602061482e833981519152928486526007602052808387205582519182526020820152a2818152600560205260ff604082205416849060128110611d11575b50611a8f670de0b6b3a7640000918484526003602052604084205490613a8b565b04908281526004602052612710611aaa604083205484613a8b565b0491611ab68382613b6c565b94808610611cfa57506001546040516318160ddd60e01b815290602090829060049082906001600160a01b03165afa908115611cef578391611cbd575b5082546001600160a01b0316803b15611ca45783809160846040518094819363ae494fa160e01b83523360048401528c60248401528b60448401528d60648401525af1801561060b57908491611ca8575b505083611c34575b6001546040516318160ddd60e01b81529190602090839060049082906001600160a01b03165afa801561060b578490611c00575b611b8a9250613b6c565b90808203611bea575050507fb3e2773606abfd36b5bd91394b3a54d1398336c65005baf7bf7a05efeffaf75b611bcd602095604051918291339588429285613bdd565b0390a360016000805160206147ce83398151915255604051908152f35b632d8562a360e11b835260045260245260449150fd5b506020823d602011611c2c575b81611c1a602093836139c3565b810103126105fe57611b8a9151611b80565b3d9150611c0d565b82546001600160a01b0316803b15611ca45783809160846040518094819363ae494fa160e01b83523060048401528a60248401528b60448401528160648401525af1801561060b57908491611c8b575b5050611b4c565b81611c95916139c3565b611ca0578238611c84565b8280fd5b8380fd5b81611cb2916139c3565b611ca0578238611b44565b90506020813d602011611ce7575b81611cd8602093836139c3565b810103126105fe575138611af3565b3d9150611ccb565b6040513d85823e3d90fd5b6371c4efed60e01b83526004869052602452604482fd5b611d21915061175260ff91613ad4565b8015611d5e5780600019048511611d4f57611a8f611d48670de0b6b3a76400009287613a8b565b9150611a6e565b63035fc53d60e41b8252600482fd5b634e487b7160e01b82526012600452602482fd5b630700fcb360e11b8352600483fd5b63446c8cc960e01b8352600483fd5b639bfa3c1760e01b8152600490fd5b919250506020813d602011611dd0575b81611dbc602093836139c3565b810103126105fe57518591906119f66119eb565b3d9150611daf565b90506020813d602011611e02575b81611df3602093836139c3565b810103126105fe5751386119b0565b3d9150611de6565b6040513d84823e3d90fd5b631d7f2ac360e01b83526004869052602452604482fd5b633b5db2f360e11b8352600483fd5b50908152600c6020526040812054630d54e9e160e01b82526004849052602452604490fd5b632cd84af360e01b8252600482fd5b60405163313ce56760e01b815291939291602081600481865afa859181611eef575b50611ea55763105482c760e21b8552600485fd5b93919293838352600560205260ff806040852054169116908103611ec9575061192d565b90506044928252600560205260ff604083205416631e43476360e11b8352600452602452fd5b611f0991925060203d6020116109c9576109ba81836139c3565b9038611e91565b63a74c1c5f60e01b8152600490fd5b3381526009602052436040822055338152600a6020526001604082205561190b565b503461033b578060031936011261033b5760206040516103e88152f35b503461033b57604036600319011261033b576020906040906001600160a01b03611f8661392e565b16815260148352818120602435825283522054604051908152f35b503461033b57604036600319011261033b576040611fbd613944565b91600435815260008051602061478e833981519152602052209060018060a01b0316600052602052602060ff604060002054166040519015158152f35b503461033b578060031936011261033b57602060405160648152f35b503461033b57604036600319011261033b5761205060209160043581526000805160206146ae8339815191528352604060243591206144b8565b905460405160039290921b1c6001600160a01b03168152f35b503461033b57602036600319011261033b576020906040906001600160a01b0361209161392e565b168152600983522054604051908152f35b503461033b57604036600319011261033b576120bc61392e565b60105460243591906001600160a01b0316330361215a576001600160a01b031690811561214b57604060008051602061476e8339815191529183855260136020528185205490848652601360205280838720558486526015602052828620438752602052828620548587526019602052838720558486526017602052438387205582519182526020820152a280f35b63df407ac560e01b8352600483fd5b6349db3bd360e01b8352600483fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361219161392e565b168152600383522054604051908152f35b503461033b578060031936011261033b5760008051602061470e833981519152815260008051602061478e83398151915260209081526040808320336000908152925290205460ff1615612278576121f8613f4e565b600160ff196000805160206147ae8339815191525416176000805160206147ae833981519152557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a16040514281527f80170b5fcdd2bf1e0660ef4b8851f86685f64d41b1a19de1471947ece8725aac60203392a280f35b63e2517d3f60e01b81523360045260008051602061470e833981519152602452604490fd5b503461033b57602036600319011261033b576122b761392e565b60008051602061480e8339815191525460ff8160401c169081156123a3575b506123945760008051602061480e83398151915280546001600160481b0319166003600160401b0117905581805260008051602061478e83398151915260209081526040808420336000908152925290205460ff161561237c5761233990613c5e565b60ff60401b1960008051602061480e833981519152541660008051602061480e833981519152556000805160206146ee833981519152602060405160038152a180f35b63e2517d3f60e01b8252336004526024829052604482fd5b63f92ee8a960e01b8252600482fd5b60036001600160401b039190911610159050386122d6565b503461033b578060031936011261033b57602060ff6000805160206147ae83398151915254166040519015158152f35b503461033b57602036600319011261033b5761240561392e565b6010546001600160a01b031633036104795761043690613c5e565b503461033b57606036600319011261033b5761243a61392e565b612442613944565b60105490926044359290916001600160a01b0316330361047957612464613f4e565b6011546001600160a01b03169182156126de5760405163babcc53960e01b81526001600160a01b0386166004820181905293602090829060249082905afa908115611e0a57829161269f575b5015612690578215612681576001546001600160a01b03928316921682036125d1576040516370a0823160e01b8152306004820152602081602481865afa908115611e0a57829161259f575b50935b841561259057600019810361258a5750835b841561257b5780851161256357505061252d836020958361404c565b7f0bf519e4b3821615dbdd874fa1a5fbb4bb651b4e6beabedd4ac318e770233b2c604080518581524287820152a3604051908152f35b630555ed4f60e31b8252600485905260245260449150fd5b632e11316f60e11b8252600482fd5b93612511565b63f09872eb60e01b8252600482fd5b90506020813d6020116125c9575b816125ba602093836139c3565b810103126105fe5751386124fc565b3d91506125ad565b8181526002602052604081205460ff161561266f576040516370a0823160e01b8152306004820152602081602481865afa908115611e0a57829161263d575b5082825260076020526040822054808211156126355761262f91613b6c565b936124ff565b50508061262f565b90506020813d602011612667575b81612658602093836139c3565b810103126105fe575138612610565b3d915061264b565b60249163eef7849760e01b8252600452fd5b634e46966960e11b8152600490fd5b63133307bb60e21b8152600490fd5b90506020813d6020116126d6575b816126ba602093836139c3565b810103126126d2575180151581036126d257386124b0565b5080fd5b3d91506126ad565b630e048e7160e41b8152600490fd5b503461033b57602036600319011261033b5761270761392e565b6010546001600160a01b03163303610479576001600160a01b0316801561276c57601180546001600160a01b0319811683179091556001600160a01b03167f1e9c406f2707909cfd9f61e744f73bcab77e5997d063276f67883c5257d51cf08380a380f35b634e46966960e11b8252600482fd5b503461033b578060031936011261033b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031630036127d457602060405160008051602061472e8339815191528152f35b63703e46dd60e11b8152600490fd5b503461033b578060031936011261033b576010546040516001600160a01b039091168152602090f35b50604036600319011261033b5761282161392e565b602435906001600160401b038211611ca05736602383011215611ca0578160040135908361284e836139fc565b9361285c60405195866139c3565b83855260208501933660248284010111611ca057806024602093018637850101526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016308114908115612ade575b50612acf576010546001600160a01b03163303612ac0576001600160a01b038116928315612ab157813b15612aa25760008051602061472e83398151915254846128fa613a68565b7f6ea8b34d59b2818d3f37a08dddaa06f5886b9c20c907b36f03ca6528e106e86f61293060405192604084526040840190613a17565b4260208401526001600160a01b038516929081900390a36040516352d1902d60e01b8152602081600481895afa879181612a6a575b5061297e57634c9c8ce360e01b87526004869052602487fd5b908160008051602061472e83398151915288979303612a585750833b15612a44576001600160a01b031916811760008051602061472e833981519152558491907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b8380a2805115612a295761113e9382915190845af43d15612a21573d91612a05836139fc565b92612a1360405194856139c3565b83523d85602085013e61460c565b60609161460c565b5050505034612a355780f35b63b398979f60e01b8152600490fd5b634c9c8ce360e01b86526004829052602486fd5b632a87526960e21b8752600452602486fd5b9091506020813d602011612a9a575b81612a86602093836139c3565b81010312612a9657519038612965565b8780fd5b3d9150612a79565b636f7c43f160e01b8552600485fd5b63e6c4247b60e01b8552600485fd5b6349db3bd360e01b8452600484fd5b63703e46dd60e11b8452600484fd5b60008051602061472e833981519152546001600160a01b031614159050386128b2565b503461033b57602036600319011261033b576020906040906001600160a01b03612b2961392e565b168152600e83522054604051908152f35b503461033b57606036600319011261033b57612b5461395a565b6024356001600160401b038111611ca057612b73903690600401613993565b916044356001600160401b038111610a5057612b93903690600401613993565b60008051602061480e8339815191529291925460ff8160401c16908115612ef6575b50612ee75760008051602061480e83398151915280546001600160481b0319166002600160401b011790556000805160206147ee833981519152865260008051602061478e83398151915260209081526040808820336000908152925290205460ff1615612ec257612c2561448a565b612c2d61448a565b60016000805160206147ce83398151915255600b549160ff8316612eb357818603612ea457612c5b86613bf9565b92612c6960405194856139c3565b868452601f19612c7888613bf9565b01366020860137875b878110612daf575060019060ff191617600b5515159460ff196008541660ff871617600855865b818110612d0c578760008051602061466e833981519152602089604051908152a160ff60401b1960008051602061480e833981519152541660008051602061480e833981519152556000805160206146ee833981519152602060405160028152a180f35b808860008051602061482e8339815191526040612d34612d2f600196888d613c10565b613c36565b612d3f85898c613c10565b357f8f955fa878b4aae8b1ac37b1ab715307470f2822ceff87e23d33ef1e044814a783612d6c888d613c4a565b5193898060a01b0316968793848252600660205280838320558482526007602052858383205582519182526020820152a28151908d82526020820152a201612ca8565b612dbd612d2f828a8a613c10565b612dc8828689613c10565b6001600160a01b03909116808b52600260205260408b20549091359060ff1615612e90576103e88111612e785750906020602492604051938480926370a0823160e01b82523060048301525afa8015612e6d578a90612e37575b60019250612e308288613c4a565b5201612c81565b509060203d8111612e66575b612e4d81836139c3565b6020826000928101031261033b57509060019151612e22565b503d612e43565b6040513d8c823e3d90fd5b631051834f60e11b8b526004526103e860245260448afd5b6351104c5960e01b8b52600482905260248bfd5b63512509d360e11b8752600487fd5b6324d0d1fd60e01b8752600487fd5b63e2517d3f60e01b8652336004526000805160206147ee833981519152602452604486fd5b63f92ee8a960e01b8652600486fd5b60026001600160401b03919091161015905038612bb5565b503461033b578060031936011261033b576011546040516001600160a01b039091168152602090f35b503461033b578060031936011261033b576010546001600160a01b03163303612fef576000805160206147ae8339815191525460ff811615612fe05760ff19166000805160206147ae833981519152557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a16040514281527f107553d8191d85b405879cf752997865edd48d94e20bda4dd27223c94b31a7cc60203392a280f35b638dfc202b60e01b8252600482fd5b6349db3bd360e01b8152600490fd5b503461033b57602036600319011261033b576020906040906001600160a01b0361302661392e565b168152601683522054604051908152f35b503461033b57604036600319011261033b57613051613944565b336001600160a01b0382160361306d5761113e9060043561411a565b63334bd91960e11b8252600482fd5b503461033b57602036600319011261033b576020906040906001600160a01b036130a461392e565b168152600c83522054604051908152f35b503461033b57602036600319011261033b576020906040906001600160a01b036130dd61392e565b168152601783522054604051908152f35b503461033b57604036600319011261033b5761113e60043561310e613944565b9061311b61113482613b79565b6140d2565b503461033b5761312f36613969565b91909261313a613f12565b613142613f4e565b3381526009602052604081205443036135be57338152600a602052600360408220541015611f1057338152600a602052604081206131808154613b9a565b90555b6001600160a01b0382168082526002602052604082205490929060ff16613543575b828252600260205260ff604083205416156104665760ff6008541615613534578415610457578315611e6057828252600d602052604082205480861061351d5750828252600f6020526040822054801561350e578086116134f857508461320b91613f78565b670de0b6b3a76400008402848104670de0b6b3a7640000036134e4578282526003602052604082205461323d91613ab4565b90828152600560205260ff604082205416601281106134c4575b50828152600660205261327c612710613274604084205485613a8b565b048093613b6c565b938085106134ac575082815260076020528360408220541061348857828152600760205260408120548481106134795760008051602061482e8339815191526040826132c9888895613b6c565b8486526007602052808387205582519182526020820152a26001546040516318160ddd60e01b815290602090829060049082906001600160a01b03165afa908115611e0a578291613447575b5081546001600160a01b0316803b15611ca057826040518092633a52b90760e11b82528183816133498d3360048401613bc2565b03925af18015611cef57613432575b506001546040516318160ddd60e01b81529190602090839060049082906001600160a01b03165afa908115611cef5783916133fc575b6133989250613b6c565b8581036133e45750507f8caf04742286d017f9ac3924388e188c73e6e5094311c5e59a61a7ef86dda8bf611bcd6020956133d386338761404c565b604051918291339588429285613bdd565b635ab6e2db60e01b8252600486905260245260449150fd5b90506020823d60201161342a575b81613417602093836139c3565b810103126105fe5761339891519061338e565b3d915061340a565b9161344081600493946139c3565b9190613358565b90506020813d602011613471575b81613462602093836139c3565b810103126126d2575138613315565b3d9150613455565b6308aed4ef60e31b8252600482fd5b82815260076020526040812054635960d22160e01b82526004526024849052604490fd5b6371c4efed60e01b8252600485905260245260449150fd5b916134d760ff6117526134dd9495613ad4565b90613ab4565b9038613257565b634e487b7160e01b82526011600452602482fd5b625502a360e91b83526004869052602452604482fd5b636c6ff70d60e11b8352600483fd5b6361767b8560e01b83526004869052602452604482fd5b630df65d9f60e01b8252600482fd5b60405163313ce56760e01b815291939291602081600481865afa85918161359d575b506135795763105482c760e21b8552600485fd5b93919293838352600560205260ff806040852054169116908103611ec957506131a5565b6135b791925060203d6020116109c9576109ba81836139c3565b9038613565565b3381526009602052436040822055338152600a60205260016040822055613183565b503461033b57602036600319011261033b576020610f3c600435613b79565b503461033b57602036600319011261033b576020906040906001600160a01b0361362761392e565b168152600f83522054604051908152f35b503461033b57604036600319011261033b5761365261392e565b60105460243591906001600160a01b0316330361215a576001600160a01b031690811561214b5760406000805160206146ce8339815191529183855260126020528185205490848652601260205280838720558486526014602052828620438752602052828620548587526018602052838720558486526016602052438387205582519182526020820152a280f35b503461033b57602036600319011261033b576020906040906001600160a01b0361370961392e565b168152600683522054604051908152f35b503461033b578060031936011261033b576001546040516001600160a01b039091168152602090f35b503461033b57602036600319011261033b576020906040906001600160a01b0361376b61392e565b168152600d83522054604051908152f35b503461033b57602036600319011261033b5761379661395a565b6010546001600160a01b0316330361047957602060008051602061466e83398151915291151560ff196008541660ff821617600855604051908152a180f35b503461033b57602036600319011261033b5760043563ffffffff60e01b81168091036126d257602090635a05180f60e01b811490811561381b575b506040519015158152f35b637965db0b60e01b811491508115613835575b5082613810565b6301ffc9a760e01b1490508261382e565b503461033b57604036600319011261033b5761386061392e565b6001600160a01b0316808252600260205260408220546024359060ff161561177457670de0b6b3a7640000810290808204670de0b6b3a7640000149015171561391a57916138bc60409383835260036020528483205490613ab4565b91808252600560205260ff8483205416601281106138f1575b5061172a84836127109361173295526006602052205484613a8b565b846117329361390f61271094966134d760ff61175261172a97613ad4565b9593509350506138d5565b634e487b7160e01b83526011600452602483fd5b600435906001600160a01b03821682036105fe57565b602435906001600160a01b03821682036105fe57565b6004359081151582036105fe57565b60609060031901126105fe576004356001600160a01b03811681036105fe57906024359060443590565b9181601f840112156105fe578235916001600160401b0383116105fe576020808501948460051b0101116105fe57565b601f909101601f19168101906001600160401b038211908210176139e657604052565b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116139e657601f01601f191660200190565b919082519283825260005b848110613a43575050826000602080949584010152601f8019910116010190565b80602080928401015182828601015201613a22565b6084359060ff821682036105fe57565b60405190613a776040836139c3565b6005825264322e332e3360d81b6020830152565b81810292918115918404141715613a9e57565b634e487b7160e01b600052601160045260246000fd5b8115613abe570490565b634e487b7160e01b600052601260045260246000fd5b60ff166012039060ff8211613a9e57565b8015613b665760009060208110600116604e821060011617613b5e57600a916001915b60018111613b35575082600019048211613b2157500290565b634e487b7160e01b81526011600452602490fd5b92806000190481116134e45760018416613b55575b80029260011c613b08565b80920291613b4a565b9050600a0a90565b50600190565b91908203918211613a9e57565b60005260008051602061478e83398151915260205260016040600020015490565b6000198114613a9e5760010190565b908160209103126105fe575160ff811681036105fe5790565b6001600160a01b039091168152602081019190915260400190565b9094939260609260808301968352602083015260408201520152565b6001600160401b0381116139e65760051b60200190565b9190811015613c205760051b0190565b634e487b7160e01b600052603260045260246000fd5b356001600160a01b03811681036105fe5790565b8051821015613c205760209160051b010190565b6001600160a01b03168015613c9f57601080546001600160a01b0319811683179091556001600160a01b031660008051602061474e833981519152600080a3565b63e6c4247b60e01b60005260046000fd5b91908201809211613a9e57565b94919360e0969360ff929a99989561010088019b885260208801526040870152166060850152608084015260a083015260c08201520152565b6001600160a01b03811660008181526002602052604090205490919060ff16158015613de8575b8015613de0575b613dce5781600052600f6020526040600020548015908115613dd6575b50613dce57613d66926040918251948592839262f7fce960e01b845260048401613bc2565b0381305afa918215613dc257600092613d8e575b506000526007602052604060002054101590565b9091506040813d604011613dba575b81613daa604093836139c3565b810103126105fe57519038613d7a565b3d9150613d9d565b6040513d6000823e3d90fd5b505050600090565b9050831138613d41565b508215613d24565b5060ff6008541615613d1d565b6001546001600160a01b0391821691168103613e6a576020602491604051928380926370a0823160e01b82523060048301525afa908115613dc257600091613e3b575090565b90506020813d602011613e62575b81613e56602093836139c3565b810103126105fe575190565b3d9150613e49565b80600052600260205260ff60406000205416613e865750600090565b6040516370a0823160e01b815230600482015290602082602481845afa918215613dc257600092613ede575b506000526007602052604060002054808211600014613ed757613ed491613b6c565b90565b5050600090565b90916020823d602011613f0a575b81613ef9602093836139c3565b8101031261033b5750519038613eb2565b3d9150613eec565b60026000805160206147ce8339815191525414613f3d5760026000805160206147ce83398151915255565b633ee5aeb560e01b60005260046000fd5b60ff6000805160206147ae8339815191525416613f6757565b63d93c066560e01b60005260046000fd5b6001600160a01b0316600081815260136020526040902054801561404757816000526015602052604060002043600052602052613fbb6040600020549384613cb0565b92831061403657808260005260176020524360406000205414614018575b8311613ffc57506000526015602052604060002043600052602052604060002055565b925063029359d560e41b60005260045260245260445260646000fd5b5081600052601960205261403160406000205482613cb0565b613fd9565b63446c8cc960e01b60005260046000fd5b505050565b614081614086939261407360405194859263a9059cbb60e01b602085015260248401613bc2565b03601f1981018452836139c3565b6142ed565b565b600081815260008051602061478e8339815191526020908152604080832033845290915290205460ff16156140ba5750565b63e2517d3f60e01b6000523360045260245260446000fd5b6140dc8282614348565b91826140e757505090565b60009182526000805160206146ae8339815191526020526040909120614116916001600160a01b0316906144d0565b5090565b61412482826143ea565b918261412f57505090565b60009182526000805160206146ae8339815191526020526040909120614116916001600160a01b031690614539565b6001600160a01b03166000818152601260205260409020548015614047578160005260146020526040600020436000526020526141a16040600020549384613cb0565b928310614036578082600052601660205243604060002054146141fe575b83116141e257506000526014602052604060002043600052602052604060002055565b92506319a4e2a760e01b60005260045260245260445260646000fd5b5081600052601860205261421760406000205482613cb0565b6141bf565b6040516323b872dd60e01b60208201526001600160a01b039283166024820152929091166044830152606480830193909352918152614086916140816084836139c3565b60405163313ce56760e01b81529190602090839060049082906001600160a01b03165afa600092816142cc575b506142a357631eecbb6560e01b60005260046000fd5b60ff91821691168082036142b5575050565b631e43476360e11b60005260045260245260446000fd5b6142e691935060203d6020116109c9576109ba81836139c3565b913861428d565b906000602091828151910182855af115613dc2576000513d61433f57506001600160a01b0381163b155b61431e5750565b635274afe760e01b60009081526001600160a01b0391909116600452602490fd5b60011415614317565b600081815260008051602061478e833981519152602090815260408083206001600160a01b038616845290915290205460ff16613ed757600081815260008051602061478e833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19166001179055339291907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d9080a4600190565b600081815260008051602061478e833981519152602090815260408083206001600160a01b038616845290915290205460ff1615613ed757600081815260008051602061478e833981519152602090815260408083206001600160a01b0395909516808452949091528120805460ff19169055339291907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9080a4600190565b60ff60008051602061480e8339815191525460401c16156144a757565b631afcd79f60e31b60005260046000fd5b8054821015613c205760005260206000200190600090565b6001810190826000528160205260406000205415600014613dce578054600160401b8110156139e65761452461450d8260018794018555846144b8565b819391549060031b91821b91600019901b19161790565b90555491600052602052604060002055600190565b9060018201918160005282602052604060002054801515600014614603576000198101818111613a9e578254600019810191908211613a9e578181036145cc575b505050805480156145b657600019019061459482826144b8565b8154906000199060031b1b191690555560005260205260006040812055600190565b634e487b7160e01b600052603160045260246000fd5b6145ec6145dc61450d93866144b8565b90549060031b1c928392866144b8565b90556000528360205260406000205538808061457a565b50505050600090565b90614632575080511561462157602081519101fd5b63d6bda27560e01b60005260046000fd5b81511580614664575b614643575090565b639996b31560e01b60009081526001600160a01b0391909116600452602490fd5b50803b1561463b56fe2c0a5f5ab0ba371221bb3612c2d2f90d36566279309f526000c5b354efd1b0658c67aaac7f77de07240e5a9b36dfdccb2a89c438635abbb27a73142d2aa0f629c1f6fe24621ce81ec5827caf0253cadb74709b061630e6b55e8237170593200048b07fab687f450848f1df8a96db08fef7840f53415f18fdc2ec8e9f810f0930c7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d275027301df982f5215b4963a854cf9c73219df80cb6acd8f098189c9480c7bbc360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc17dc5b1290f7495d7f8cc68476e6941aaf510598fa925d0d2720edc8805a846c4460507c21097c15f6883572ebd157a9ee4b1d989a312314e93afd9d2ecd494002dd7bc7dec4dceedda775e58dd541e08a116c6c53815c0bd028192f7b626800cd5ed15c6e187e77e9aee88184c21f4f2182ab5827cb3b7e07fbedcd63f033009b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00a49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a006d129bd71f2401cbe77f49f546d7d5f58992faecfca6e51ba06b50b261e83331a164736f6c6343000822000a";
|
|
15719
15924
|
var isSuperArgs = (xs) => xs.length > 1;
|
|
15720
|
-
var SimplePSMV2__factory = class extends
|
|
15925
|
+
var SimplePSMV2__factory = class extends import_ethers14.ContractFactory {
|
|
15721
15926
|
constructor(...args) {
|
|
15722
15927
|
if (isSuperArgs(args)) {
|
|
15723
15928
|
super(...args);
|
|
@@ -15737,10 +15942,10 @@ var SimplePSMV2__factory = class extends import_ethers13.ContractFactory {
|
|
|
15737
15942
|
static bytecode = _bytecode;
|
|
15738
15943
|
static abi = _abi;
|
|
15739
15944
|
static createInterface() {
|
|
15740
|
-
return new
|
|
15945
|
+
return new import_ethers14.Interface(_abi);
|
|
15741
15946
|
}
|
|
15742
15947
|
static connect(address, runner) {
|
|
15743
|
-
return new
|
|
15948
|
+
return new import_ethers14.Contract(address, _abi, runner);
|
|
15744
15949
|
}
|
|
15745
15950
|
};
|
|
15746
15951
|
|
|
@@ -16328,7 +16533,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
16328
16533
|
*/
|
|
16329
16534
|
constructor(config) {
|
|
16330
16535
|
if (!config.provider && config.ethRpcUrl) {
|
|
16331
|
-
config.provider = new
|
|
16536
|
+
config.provider = new import_ethers15.JsonRpcProvider(config.ethRpcUrl);
|
|
16332
16537
|
}
|
|
16333
16538
|
this.config = config;
|
|
16334
16539
|
if (config.debug) {
|
|
@@ -16601,7 +16806,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
16601
16806
|
const network = await config.provider.getNetwork();
|
|
16602
16807
|
chainId = Number(network.chainId);
|
|
16603
16808
|
} else if (config.ethRpcUrl) {
|
|
16604
|
-
const tempProvider = new
|
|
16809
|
+
const tempProvider = new import_ethers15.JsonRpcProvider(
|
|
16605
16810
|
config.ethRpcUrl
|
|
16606
16811
|
);
|
|
16607
16812
|
const network = await tempProvider.getNetwork();
|
|
@@ -17137,7 +17342,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
17137
17342
|
}
|
|
17138
17343
|
const loanOps = this.loanOps();
|
|
17139
17344
|
const protocolConfig = await loanOps.getProtocolConfig();
|
|
17140
|
-
const requestAmountWei = (0,
|
|
17345
|
+
const requestAmountWei = (0, import_ethers15.parseEther)(
|
|
17141
17346
|
request.amount.toString()
|
|
17142
17347
|
);
|
|
17143
17348
|
const minLoanValueWei = BigInt(protocolConfig.minimumLoanValueWei);
|
|
@@ -17219,7 +17424,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
17219
17424
|
pkpNftAddress,
|
|
17220
17425
|
this.getChipotlePublicKeyFallback()
|
|
17221
17426
|
);
|
|
17222
|
-
pkpEthAddress = (0,
|
|
17427
|
+
pkpEthAddress = (0, import_ethers15.computeAddress)(pkpPublicKey);
|
|
17223
17428
|
pkpCache.set(request.positionId, {
|
|
17224
17429
|
publicKey: pkpPublicKey,
|
|
17225
17430
|
ethAddress: pkpEthAddress,
|
|
@@ -17548,8 +17753,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
17548
17753
|
throw new Error(`Position not found: ${request.positionId}`);
|
|
17549
17754
|
}
|
|
17550
17755
|
const currentDebt = position.ucdDebt.toString();
|
|
17551
|
-
const ucdDebtHash = (0,
|
|
17552
|
-
const contractHash = (0,
|
|
17756
|
+
const ucdDebtHash = (0, import_ethers15.keccak256)(import_ethers15.AbiCoder.defaultAbiCoder().encode(["uint256"], [currentDebt]));
|
|
17757
|
+
const contractHash = (0, import_ethers15.keccak256)(import_ethers15.AbiCoder.defaultAbiCoder().encode(
|
|
17553
17758
|
["address", "address", "address", "address"],
|
|
17554
17759
|
[
|
|
17555
17760
|
positionManagerAddress,
|
|
@@ -17618,7 +17823,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
17618
17823
|
const coreAbi = [
|
|
17619
17824
|
"function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
|
|
17620
17825
|
];
|
|
17621
|
-
const positionCore = new
|
|
17826
|
+
const positionCore = new import_ethers15.Contract(
|
|
17622
17827
|
coreAddress,
|
|
17623
17828
|
coreAbi,
|
|
17624
17829
|
this.getSignerOrThrow().provider
|
|
@@ -17626,8 +17831,8 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
17626
17831
|
const currentPosition = await positionCore["getPositionDetails"](
|
|
17627
17832
|
positionIdBytes32
|
|
17628
17833
|
);
|
|
17629
|
-
const currentDebtHash = (0,
|
|
17630
|
-
|
|
17834
|
+
const currentDebtHash = (0, import_ethers15.keccak256)(
|
|
17835
|
+
import_ethers15.AbiCoder.defaultAbiCoder().encode(
|
|
17631
17836
|
["uint256"],
|
|
17632
17837
|
[currentPosition.ucdDebt]
|
|
17633
17838
|
)
|
|
@@ -17674,7 +17879,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
17674
17879
|
"function getCurrentQuantum() view returns (uint256)",
|
|
17675
17880
|
"function isQuantumValid(bytes32,uint256) view returns (bool)"
|
|
17676
17881
|
];
|
|
17677
|
-
const registry = new
|
|
17882
|
+
const registry = new import_ethers15.Contract(
|
|
17678
17883
|
registryAddress,
|
|
17679
17884
|
registryAbi,
|
|
17680
17885
|
this.getSignerOrThrow().provider
|
|
@@ -17790,7 +17995,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
17790
17995
|
});
|
|
17791
17996
|
}
|
|
17792
17997
|
const signatureHexMint = finalSignature.startsWith("0x") ? finalSignature : "0x" + finalSignature;
|
|
17793
|
-
const mintIface = new
|
|
17998
|
+
const mintIface = new import_ethers15.Interface(positionManagerAbi);
|
|
17794
17999
|
const mintCalldata = mintIface.encodeFunctionData("mintUCD", [
|
|
17795
18000
|
positionIdBytes32,
|
|
17796
18001
|
validationResponse.mintAmount,
|
|
@@ -17826,7 +18031,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
17826
18031
|
if (viewsAddress) {
|
|
17827
18032
|
let diagnosis = null;
|
|
17828
18033
|
try {
|
|
17829
|
-
const views = new
|
|
18034
|
+
const views = new import_ethers15.Contract(
|
|
17830
18035
|
viewsAddress,
|
|
17831
18036
|
[
|
|
17832
18037
|
"function diagnoseMintUCD(bytes32,uint256,uint256,uint256,uint256,uint256,bytes32,bytes32,bytes32,uint256,bytes) view returns (string)"
|
|
@@ -17936,7 +18141,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
17936
18141
|
if (receipt.logs && receipt.logs.length > 0) {
|
|
17937
18142
|
for (const receiptLog of receipt.logs) {
|
|
17938
18143
|
if (receiptLog.topics && receiptLog.topics[0] === "0x08c379a0") {
|
|
17939
|
-
const iface = new
|
|
18144
|
+
const iface = new import_ethers15.Interface([
|
|
17940
18145
|
"error Error(string)"
|
|
17941
18146
|
]);
|
|
17942
18147
|
const decoded = iface.decodeErrorResult("Error", receiptLog.data);
|
|
@@ -17953,7 +18158,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
17953
18158
|
const minimalAbi = [
|
|
17954
18159
|
"event UCDMintedWithAuthorization(bytes32 indexed positionId, address indexed borrower, uint256 mintAmount, uint256 mintFee, uint256 newDebt, uint256 newCollateral, uint256 btcPrice, uint256 quantumTimestamp, bytes32 authorizedSpendsHash)"
|
|
17955
18160
|
];
|
|
17956
|
-
const iface = new
|
|
18161
|
+
const iface = new import_ethers15.Interface(minimalAbi);
|
|
17957
18162
|
for (const receiptLog of receipt.logs) {
|
|
17958
18163
|
const parsed = (() => {
|
|
17959
18164
|
const logIface = iface;
|
|
@@ -18140,7 +18345,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
18140
18345
|
pkpNftAddress,
|
|
18141
18346
|
this.getChipotlePublicKeyFallback()
|
|
18142
18347
|
);
|
|
18143
|
-
const pkpEthAddress = (0,
|
|
18348
|
+
const pkpEthAddress = (0, import_ethers15.computeAddress)(pkpPublicKey);
|
|
18144
18349
|
pkpData = {
|
|
18145
18350
|
publicKey: pkpPublicKey,
|
|
18146
18351
|
ethAddress: pkpEthAddress,
|
|
@@ -18542,7 +18747,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
18542
18747
|
}
|
|
18543
18748
|
const loanOpsForUcd = loanOpsForUcdResult.value;
|
|
18544
18749
|
const ucdTokenAddress = await loanOpsForUcd.ucdToken();
|
|
18545
|
-
const ucdToken = new
|
|
18750
|
+
const ucdToken = new import_ethers15.Contract(
|
|
18546
18751
|
ucdTokenAddress,
|
|
18547
18752
|
[
|
|
18548
18753
|
"function balanceOf(address) view returns (uint256)",
|
|
@@ -18558,9 +18763,9 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
18558
18763
|
if (ucdBalance < debtWei) {
|
|
18559
18764
|
return {
|
|
18560
18765
|
success: false,
|
|
18561
|
-
error: `Insufficient UCD balance for liquidation: ${(0,
|
|
18766
|
+
error: `Insufficient UCD balance for liquidation: ${(0, import_ethers15.formatEther)(
|
|
18562
18767
|
ucdBalance
|
|
18563
|
-
)} UCD (need ${(0,
|
|
18768
|
+
)} UCD (need ${(0, import_ethers15.formatEther)(debtWei)} UCD)`,
|
|
18564
18769
|
positionId: request.positionId,
|
|
18565
18770
|
wasLiquidated: false
|
|
18566
18771
|
};
|
|
@@ -18569,7 +18774,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
18569
18774
|
if (request.skipUcdApproval) {
|
|
18570
18775
|
return {
|
|
18571
18776
|
success: false,
|
|
18572
|
-
error: `Insufficient UCD allowance for UCDController: need at least ${(0,
|
|
18777
|
+
error: `Insufficient UCD allowance for UCDController: need at least ${(0, import_ethers15.formatEther)(
|
|
18573
18778
|
debtWei
|
|
18574
18779
|
)} UCD, or omit skipUcdApproval to let the SDK submit approve`,
|
|
18575
18780
|
positionId: request.positionId,
|
|
@@ -19076,7 +19281,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
19076
19281
|
if (typeof signatureBytes === "string" && signatureBytes.startsWith("{")) {
|
|
19077
19282
|
try {
|
|
19078
19283
|
const parsed = JSON.parse(signatureBytes);
|
|
19079
|
-
signatureBytes = parsed.signature ?? (parsed.r && parsed.s && parsed.v ?
|
|
19284
|
+
signatureBytes = parsed.signature ?? (parsed.r && parsed.s && parsed.v ? import_ethers15.Signature.from({
|
|
19080
19285
|
r: parsed.r,
|
|
19081
19286
|
s: parsed.s,
|
|
19082
19287
|
v: parsed.v
|
|
@@ -19087,7 +19292,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
19087
19292
|
if (!signatureBytes.startsWith("0x")) {
|
|
19088
19293
|
signatureBytes = "0x" + signatureBytes;
|
|
19089
19294
|
}
|
|
19090
|
-
const extendIface = new
|
|
19295
|
+
const extendIface = new import_ethers15.Interface([
|
|
19091
19296
|
"function extendPosition(bytes32 positionId, uint256 selectedTerm, uint256 quantumTimestamp, uint256 btcPrice, uint256 availableBTCBalance, uint256 proRataRenewalFee, bytes calldata extensionValidatorSignature) external returns (bool)"
|
|
19092
19297
|
]);
|
|
19093
19298
|
const extendCalldata = extendIface.encodeFunctionData("extendPosition", [
|
|
@@ -19637,7 +19842,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
19637
19842
|
` Converting payment amount: ${request.paymentAmount} (type: ${typeof request.paymentAmount})`
|
|
19638
19843
|
);
|
|
19639
19844
|
}
|
|
19640
|
-
const paymentAmountWei = (0,
|
|
19845
|
+
const paymentAmountWei = (0, import_ethers15.parseEther)(
|
|
19641
19846
|
request.paymentAmount.toString()
|
|
19642
19847
|
);
|
|
19643
19848
|
if (this.config.debug) {
|
|
@@ -19699,7 +19904,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
19699
19904
|
};
|
|
19700
19905
|
}
|
|
19701
19906
|
const ucdTokenAddress = await loanOps.ucdToken();
|
|
19702
|
-
const ucdToken = new
|
|
19907
|
+
const ucdToken = new import_ethers15.Contract(
|
|
19703
19908
|
ucdTokenAddress,
|
|
19704
19909
|
[
|
|
19705
19910
|
"function balanceOf(address) view returns (uint256)",
|
|
@@ -19714,16 +19919,16 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
19714
19919
|
ucdToken["allowance"](signerAddress, positionManagerAddress)
|
|
19715
19920
|
]);
|
|
19716
19921
|
if (this.config.debug) {
|
|
19717
|
-
log.info(` UCD Balance: ${(0,
|
|
19922
|
+
log.info(` UCD Balance: ${(0, import_ethers15.formatEther)(balance)} UCD`);
|
|
19718
19923
|
log.info(
|
|
19719
|
-
` UCD Allowance: ${(0,
|
|
19924
|
+
` UCD Allowance: ${(0, import_ethers15.formatEther)(allowance)} UCD`
|
|
19720
19925
|
);
|
|
19721
19926
|
log.info(` Required: ${request.paymentAmount} UCD`);
|
|
19722
19927
|
}
|
|
19723
19928
|
if (balance < paymentAmountWei) {
|
|
19724
19929
|
return {
|
|
19725
19930
|
success: false,
|
|
19726
|
-
error: `Insufficient UCD balance: ${(0,
|
|
19931
|
+
error: `Insufficient UCD balance: ${(0, import_ethers15.formatEther)(
|
|
19727
19932
|
balance
|
|
19728
19933
|
)} UCD (need ${request.paymentAmount} UCD)`
|
|
19729
19934
|
};
|
|
@@ -19992,7 +20197,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
19992
20197
|
const paymentSigner = this.getSignerOrThrow();
|
|
19993
20198
|
const paymentFrom = await paymentSigner.getAddress();
|
|
19994
20199
|
const paymentProvider = contractManager.getProvider();
|
|
19995
|
-
const paymentIface = new
|
|
20200
|
+
const paymentIface = new import_ethers15.Interface([
|
|
19996
20201
|
"function makePayment(bytes32 positionId, uint256 paymentAmount, uint256 quantumTimestamp, uint256 btcPrice, bytes calldata paymentValidatorSignature) external returns (bool)"
|
|
19997
20202
|
]);
|
|
19998
20203
|
const paymentCalldata = paymentIface.encodeFunctionData("makePayment", [
|
|
@@ -20309,7 +20514,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
20309
20514
|
const pkpId = position.pkpId;
|
|
20310
20515
|
if (litValidatorAddr && pkpId) {
|
|
20311
20516
|
try {
|
|
20312
|
-
const litValidator = new
|
|
20517
|
+
const litValidator = new import_ethers15.Contract(
|
|
20313
20518
|
litValidatorAddr,
|
|
20314
20519
|
["function pkpOwners(bytes32) view returns (address)"],
|
|
20315
20520
|
this.getProviderOrThrow()
|
|
@@ -20317,7 +20522,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
20317
20522
|
const owner = await litValidator.pkpOwners(
|
|
20318
20523
|
pkpId
|
|
20319
20524
|
);
|
|
20320
|
-
if (owner && owner !==
|
|
20525
|
+
if (owner && owner !== import_ethers15.ZeroAddress) {
|
|
20321
20526
|
controller = owner;
|
|
20322
20527
|
}
|
|
20323
20528
|
} catch {
|
|
@@ -20369,7 +20574,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
20369
20574
|
pkpNftAddress,
|
|
20370
20575
|
this.getChipotlePublicKeyFallback()
|
|
20371
20576
|
);
|
|
20372
|
-
pkpEthAddress = (0,
|
|
20577
|
+
pkpEthAddress = (0, import_ethers15.computeAddress)(pkpPublicKey);
|
|
20373
20578
|
pkpCache.set(positionId, {
|
|
20374
20579
|
publicKey: pkpPublicKey,
|
|
20375
20580
|
ethAddress: pkpEthAddress,
|
|
@@ -20732,7 +20937,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
20732
20937
|
utxoVout: withdrawalParams.utxoVout
|
|
20733
20938
|
});
|
|
20734
20939
|
}
|
|
20735
|
-
const withdrawIface = new
|
|
20940
|
+
const withdrawIface = new import_ethers15.Interface([
|
|
20736
20941
|
"function withdrawBTC((bytes32 positionId, bytes32 actionHash, bytes32 authorizedSpendsHash, bytes32 ucdDebtHash, bytes32 contractBundleHash, string withdrawalAddress, uint256 totalDeduction, uint256 newCollateral, uint256 quantumTimestamp, uint256 btcPrice, string utxoTxid, uint32 utxoVout) params, bytes withdrawalValidatorSignature, bytes btcSpendAuthSignature) external returns (bool)"
|
|
20737
20942
|
]);
|
|
20738
20943
|
const withdrawCalldata = withdrawIface.encodeFunctionData("withdrawBTC", [
|
|
@@ -20924,7 +21129,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
20924
21129
|
}
|
|
20925
21130
|
const pkpId = positionDetails.pkpId;
|
|
20926
21131
|
const vaultAddress = positionDetails.vaultAddress;
|
|
20927
|
-
if (!pkpId || pkpId ===
|
|
21132
|
+
if (!pkpId || pkpId === import_ethers15.ZeroHash) {
|
|
20928
21133
|
return { success: false, error: "Position has no PKP" };
|
|
20929
21134
|
}
|
|
20930
21135
|
if (!vaultAddress) {
|
|
@@ -20944,7 +21149,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
20944
21149
|
if (!publicKey) {
|
|
20945
21150
|
return { success: false, error: "Failed to resolve PKP public key" };
|
|
20946
21151
|
}
|
|
20947
|
-
const chipotlePkpAddress = (0,
|
|
21152
|
+
const chipotlePkpAddress = (0, import_ethers15.computeAddress)(publicKey);
|
|
20948
21153
|
const STANDALONE_CHAIN_NAMES = {
|
|
20949
21154
|
1: "ethereum",
|
|
20950
21155
|
11155111: "sepolia",
|
|
@@ -21294,7 +21499,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
21294
21499
|
const btcSpendAuthorizerAbi = [
|
|
21295
21500
|
"function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
|
|
21296
21501
|
];
|
|
21297
|
-
const btcSpendAuthorizer = new
|
|
21502
|
+
const btcSpendAuthorizer = new import_ethers15.Contract(
|
|
21298
21503
|
btcSpendAuthorizerAddress,
|
|
21299
21504
|
btcSpendAuthorizerAbi,
|
|
21300
21505
|
this.getProviderOrThrow()
|
|
@@ -21362,7 +21567,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
21362
21567
|
* been broadcast to the Bitcoin network. An empty array means no pending withdrawals.
|
|
21363
21568
|
*
|
|
21364
21569
|
* @param positionId - Position identifier
|
|
21365
|
-
* @returns Array of pending withdrawals, each including a pre-computed utxoKey
|
|
21570
|
+
* @returns Array of pending withdrawals, each including a pre-computed utxoKey (the key recoverStaleSpend and the admin clearing path operate on)
|
|
21366
21571
|
*/
|
|
21367
21572
|
async getPendingWithdrawals(positionId) {
|
|
21368
21573
|
this.ensureInitialized();
|
|
@@ -21380,7 +21585,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
21380
21585
|
const abi = [
|
|
21381
21586
|
"function getAuthorizedSpends(bytes32) view returns (tuple(string txid, uint32 vout, uint256 satoshis, string targetAddress, uint256 targetAmount, uint256 authorizedAt)[])"
|
|
21382
21587
|
];
|
|
21383
|
-
const contract = new
|
|
21588
|
+
const contract = new import_ethers15.Contract(
|
|
21384
21589
|
btcSpendAuthorizerAddress,
|
|
21385
21590
|
abi,
|
|
21386
21591
|
this.getProviderOrThrow()
|
|
@@ -21394,24 +21599,58 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
21394
21599
|
targetAddress: spend.targetAddress,
|
|
21395
21600
|
targetAmount: Number(spend.targetAmount),
|
|
21396
21601
|
authorizedAt: Number(spend.authorizedAt),
|
|
21397
|
-
utxoKey: (0,
|
|
21602
|
+
utxoKey: (0, import_ethers15.solidityPackedKeccak256)(
|
|
21398
21603
|
["string", "uint32"],
|
|
21399
21604
|
[spend.txid, Number(spend.vout)]
|
|
21400
21605
|
)
|
|
21401
21606
|
}));
|
|
21402
21607
|
}
|
|
21403
21608
|
/**
|
|
21404
|
-
*
|
|
21405
|
-
*
|
|
21406
|
-
*
|
|
21407
|
-
*
|
|
21408
|
-
*
|
|
21609
|
+
* Reconcile every pending withdrawal against BITCOIN truth (incident
|
|
21610
|
+
* 2026-07-22): `getPendingWithdrawals` only reflects on-chain
|
|
21611
|
+
* authorizations, and the contract can never know whether the Phase-2 BTC
|
|
21612
|
+
* broadcast happened. Callers MUST use the returned `status` to decide what
|
|
21613
|
+
* to offer:
|
|
21614
|
+
* - EXECUTABLE → offer Execute (the only status that may).
|
|
21615
|
+
* - EXECUTED → auto-clear; `spendingTxid` is the completion proof —
|
|
21616
|
+
* feed it to recoverStaleSpend to clear the reservation.
|
|
21617
|
+
* - SPENT_MISMATCH → unexecutable; recoverStaleSpend with the spending txid
|
|
21618
|
+
* as invalidator clears the reservation.
|
|
21619
|
+
* - CORRUPT → authorization contradicts the chain (e.g. declared
|
|
21620
|
+
* satoshis ≠ real output value); Execute can only die at
|
|
21621
|
+
* the signer guard, and no borrower-side cancel exists
|
|
21622
|
+
* (audit #62210) — clearing needs the AdminModule
|
|
21623
|
+
* cancelStaleSpendByAdmin operator override.
|
|
21624
|
+
* - UNFUNDED → funding tx unknown/unconfirmed; wait.
|
|
21409
21625
|
*
|
|
21410
|
-
* @param
|
|
21411
|
-
*
|
|
21412
|
-
*
|
|
21413
|
-
* @returns Transaction hash of the cancellation EVM transaction
|
|
21626
|
+
* @param opts.esploraBaseUrl Esplora API base (e.g. the api proxy
|
|
21627
|
+
* `/v1/proxy/esplora/<network>`). Falls back to
|
|
21628
|
+
* `config.bitcoinProviders[0].url`; throws when neither is configured.
|
|
21414
21629
|
*/
|
|
21630
|
+
async reconcilePendingWithdrawals(positionId, opts) {
|
|
21631
|
+
this.ensureInitialized();
|
|
21632
|
+
const esploraBaseUrl = opts?.esploraBaseUrl ?? this.config.bitcoinProviders?.[0]?.url;
|
|
21633
|
+
if (!esploraBaseUrl) {
|
|
21634
|
+
throw new SDKError({
|
|
21635
|
+
code: "SDK_ESPLORA_NOT_CONFIGURED",
|
|
21636
|
+
message: "reconcilePendingWithdrawals requires opts.esploraBaseUrl or config.bitcoinProviders[0].url",
|
|
21637
|
+
category: "CONFIGURATION" /* CONFIGURATION */,
|
|
21638
|
+
severity: "HIGH" /* HIGH */,
|
|
21639
|
+
originalError: new Error("esplora base URL not configured")
|
|
21640
|
+
});
|
|
21641
|
+
}
|
|
21642
|
+
const spends = await this.getPendingWithdrawals(positionId);
|
|
21643
|
+
return Promise.all(
|
|
21644
|
+
spends.map((spend) => reconcileAuthorizedSpend(spend, esploraBaseUrl))
|
|
21645
|
+
);
|
|
21646
|
+
}
|
|
21647
|
+
// NOTE: there is deliberately no cancelPendingWithdrawal. Borrower-callable
|
|
21648
|
+
// cleanup was permanently disabled by audit #62210 (markSpentByOwner /
|
|
21649
|
+
// cancelStaleSpendByOwner revert with BorrowerBTCSpendMutationDisabled — a
|
|
21650
|
+
// borrower cancel could be replayed to mint UCD against the same UTXO).
|
|
21651
|
+
// Reservations clear via recoverStaleSpend below (trustless attestation once
|
|
21652
|
+
// the UTXO is provably consumed) or the AdminModule-timelocked
|
|
21653
|
+
// cancelStaleSpendByAdmin operator override.
|
|
21415
21654
|
/**
|
|
21416
21655
|
* Recover (clear) a stale BTC reservation via LIT-attested proof.
|
|
21417
21656
|
*
|
|
@@ -21533,7 +21772,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
21533
21772
|
error: attRes.error ?? attRes.reason ?? `LIT recovery attestation rejected${attRes.failedStep ? ` at step ${attRes.failedStep}` : ""}`
|
|
21534
21773
|
};
|
|
21535
21774
|
}
|
|
21536
|
-
const btcSpendAuthorizer = new
|
|
21775
|
+
const btcSpendAuthorizer = new import_ethers15.Contract(
|
|
21537
21776
|
btcSpendAuthorizerAddress,
|
|
21538
21777
|
[
|
|
21539
21778
|
"function cancelStaleSpendWithProof(bytes32 positionId, bytes32 utxoKey, uint256 authorizedAt, string calldata invalidatorTxid, uint256 attestationTimestamp, bytes calldata litSignature) external"
|
|
@@ -21563,6 +21802,256 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
21563
21802
|
};
|
|
21564
21803
|
}
|
|
21565
21804
|
}
|
|
21805
|
+
/**
|
|
21806
|
+
* Sign + broadcast the PKP vault→vault self-spend that invalidates one
|
|
21807
|
+
* stuck authorized outpoint (btc-utxo-invalidator 1.0.0). Once the returned
|
|
21808
|
+
* `invalidatorTxid` reaches >=6 Bitcoin confirmations, `recoverStaleSpend`
|
|
21809
|
+
* clears the on-chain reservation — the trustless replacement for the
|
|
21810
|
+
* AdminModule cancelStaleSpendByAdmin path on unspent stuck/corrupt
|
|
21811
|
+
* reservations (incident 2026-07-22). Requires the borrower (or position
|
|
21812
|
+
* delegate) signer; the signature is scoped to exactly this outpoint.
|
|
21813
|
+
*/
|
|
21814
|
+
async invalidateStaleSpend(params) {
|
|
21815
|
+
this.ensureInitialized();
|
|
21816
|
+
const chainId = this.config.chainId ?? this.config.networkOverride?.chainId;
|
|
21817
|
+
if (!chainId) {
|
|
21818
|
+
return {
|
|
21819
|
+
success: false,
|
|
21820
|
+
failedStep: "config",
|
|
21821
|
+
error: "chainId required for invalidateStaleSpend"
|
|
21822
|
+
};
|
|
21823
|
+
}
|
|
21824
|
+
const signer = this.getSignerOrThrow();
|
|
21825
|
+
const envelope = await buildInvalidateStaleSpendEnvelope({
|
|
21826
|
+
positionId: params.positionId,
|
|
21827
|
+
utxoTxid: params.utxoTxid,
|
|
21828
|
+
utxoVout: params.utxoVout,
|
|
21829
|
+
chainId,
|
|
21830
|
+
signer
|
|
21831
|
+
});
|
|
21832
|
+
if (this.config.mode === "service" && this.config.serviceEndpoint) {
|
|
21833
|
+
const headers = {
|
|
21834
|
+
"Content-Type": "application/json",
|
|
21835
|
+
...await this.getAuthHeader()
|
|
21836
|
+
};
|
|
21837
|
+
const resp = await fetch(
|
|
21838
|
+
`${this.config.serviceEndpoint}/api/lit/stale-spend/invalidate`,
|
|
21839
|
+
{
|
|
21840
|
+
method: "POST",
|
|
21841
|
+
headers,
|
|
21842
|
+
body: JSON.stringify({
|
|
21843
|
+
positionId: this.toBytes32(params.positionId),
|
|
21844
|
+
utxoTxid: params.utxoTxid,
|
|
21845
|
+
utxoVout: params.utxoVout,
|
|
21846
|
+
chainId,
|
|
21847
|
+
auth: {
|
|
21848
|
+
timestamp: envelope.timestamp,
|
|
21849
|
+
action: envelope.action,
|
|
21850
|
+
signature: envelope.signature
|
|
21851
|
+
}
|
|
21852
|
+
})
|
|
21853
|
+
}
|
|
21854
|
+
);
|
|
21855
|
+
const json = await resp.json();
|
|
21856
|
+
return json.data ?? {
|
|
21857
|
+
success: false,
|
|
21858
|
+
error: json.error ?? "stale-spend invalidate request failed"
|
|
21859
|
+
};
|
|
21860
|
+
}
|
|
21861
|
+
const rpcUrl = params.rpcUrl ?? this.config.ethRpcUrl;
|
|
21862
|
+
if (!rpcUrl) {
|
|
21863
|
+
return {
|
|
21864
|
+
success: false,
|
|
21865
|
+
failedStep: "config",
|
|
21866
|
+
error: "ethRpcUrl required for invalidateStaleSpend \u2014 set DiamondHandsSDKConfig.ethRpcUrl or pass rpcUrl"
|
|
21867
|
+
};
|
|
21868
|
+
}
|
|
21869
|
+
const positionDetails = await this.getPositionDetailsView(
|
|
21870
|
+
params.positionId
|
|
21871
|
+
);
|
|
21872
|
+
if (!positionDetails?.pkpId || positionDetails.pkpId === import_ethers15.ZeroHash) {
|
|
21873
|
+
return { success: false, error: "Position has no PKP" };
|
|
21874
|
+
}
|
|
21875
|
+
const pkpCache = this.cacheManager.getCache("pkp-data", {
|
|
21876
|
+
maxSize: 500,
|
|
21877
|
+
ttlMs: 24 * 60 * 60 * 1e3
|
|
21878
|
+
});
|
|
21879
|
+
let publicKey = pkpCache.get(params.positionId)?.publicKey;
|
|
21880
|
+
if (!publicKey) {
|
|
21881
|
+
const derived = await this.litOps.deriveDiamondHandsLoanPkpPublicKey({
|
|
21882
|
+
pkpId: positionDetails.pkpId
|
|
21883
|
+
});
|
|
21884
|
+
publicKey = derived.publicKey;
|
|
21885
|
+
}
|
|
21886
|
+
if (!publicKey) {
|
|
21887
|
+
return { success: false, error: "Failed to resolve PKP public key" };
|
|
21888
|
+
}
|
|
21889
|
+
const chipotlePkpAddress = (0, import_ethers15.computeAddress)(publicKey);
|
|
21890
|
+
const dc = this.config.contractAddresses || {};
|
|
21891
|
+
const chainName = chainId === 1 ? "ethereum" : chainId === 11155111 ? "sepolia" : chainId === 1337 || chainId === 31337 ? "hardhat" : void 0;
|
|
21892
|
+
if (!chainName) {
|
|
21893
|
+
return {
|
|
21894
|
+
success: false,
|
|
21895
|
+
error: `Unsupported chainId ${chainId} for invalidateStaleSpend (supported: 1, 11155111, 1337, 31337)`
|
|
21896
|
+
};
|
|
21897
|
+
}
|
|
21898
|
+
const signResult = await this.litOps.signBtcUtxoInvalidator({
|
|
21899
|
+
auth: {
|
|
21900
|
+
positionId: this.toBytes32(params.positionId),
|
|
21901
|
+
utxoTxid: params.utxoTxid,
|
|
21902
|
+
utxoVout: params.utxoVout,
|
|
21903
|
+
timestamp: envelope.timestamp,
|
|
21904
|
+
chainId,
|
|
21905
|
+
action: envelope.action,
|
|
21906
|
+
signature: envelope.signature
|
|
21907
|
+
},
|
|
21908
|
+
publicKey,
|
|
21909
|
+
pkpId: chipotlePkpAddress,
|
|
21910
|
+
chain: chainName,
|
|
21911
|
+
rpcUrl,
|
|
21912
|
+
...this.config.bitcoinProviders?.[0]?.url && (chainId === 1337 || chainId === 31337) ? { devBitcoinProviderUrl: this.config.bitcoinProviders[0].url } : {},
|
|
21913
|
+
contractAddresses: {
|
|
21914
|
+
PositionManager: dc.positionManager ?? "",
|
|
21915
|
+
BTCSpendAuthorizer: dc.btcSpendAuthorizer ?? "",
|
|
21916
|
+
...dc.bitcoinProviderRegistry ? { BitcoinProviderRegistry: dc.bitcoinProviderRegistry } : {},
|
|
21917
|
+
...dc.positionDelegateRegistry ? { PositionDelegateRegistry: dc.positionDelegateRegistry } : {}
|
|
21918
|
+
}
|
|
21919
|
+
});
|
|
21920
|
+
if (!signResult.success) {
|
|
21921
|
+
return {
|
|
21922
|
+
success: false,
|
|
21923
|
+
error: signResult.error ?? "btc-utxo-invalidator signing failed",
|
|
21924
|
+
failedStep: signResult.failedStep
|
|
21925
|
+
};
|
|
21926
|
+
}
|
|
21927
|
+
if (signResult.alreadySpent && typeof signResult.alreadySpent === "object") {
|
|
21928
|
+
return {
|
|
21929
|
+
success: true,
|
|
21930
|
+
alreadySpent: { spendingTxid: signResult.alreadySpent.spendingTxid }
|
|
21931
|
+
};
|
|
21932
|
+
}
|
|
21933
|
+
if (!signResult.signatures?.length || !signResult.utxo || !signResult.pkpBtcAddress || typeof signResult.invalidatorAmount !== "number") {
|
|
21934
|
+
return {
|
|
21935
|
+
success: false,
|
|
21936
|
+
error: "btc-utxo-invalidator returned incomplete data (signatures/utxo/pkpBtcAddress/invalidatorAmount)"
|
|
21937
|
+
};
|
|
21938
|
+
}
|
|
21939
|
+
const broadcastUrl = this.config.bitcoinProviders?.[0]?.url;
|
|
21940
|
+
if (!broadcastUrl) {
|
|
21941
|
+
return {
|
|
21942
|
+
success: false,
|
|
21943
|
+
error: "invalidateStaleSpend broadcast requires config.bitcoinProviders[0].url (esplora base)"
|
|
21944
|
+
};
|
|
21945
|
+
}
|
|
21946
|
+
const { txid: invalidatorTxid } = await (0, import_dh_lit_ops.broadcastSignedBitcoinTransaction)({
|
|
21947
|
+
signatures: signResult.signatures,
|
|
21948
|
+
utxos: [signResult.utxo],
|
|
21949
|
+
pkpPublicKey: signResult.pkpPublicKey ?? publicKey,
|
|
21950
|
+
destination: signResult.pkpBtcAddress,
|
|
21951
|
+
userReceivesAmount: signResult.invalidatorAmount,
|
|
21952
|
+
changeAmount: 0,
|
|
21953
|
+
pkpBtcAddress: signResult.pkpBtcAddress,
|
|
21954
|
+
bitcoinNetwork: chainId === 1 ? "mainnet" : "regtest",
|
|
21955
|
+
bitcoinRpcUrl: broadcastUrl
|
|
21956
|
+
});
|
|
21957
|
+
return {
|
|
21958
|
+
success: true,
|
|
21959
|
+
invalidatorTxid,
|
|
21960
|
+
invalidatorAmount: signResult.invalidatorAmount,
|
|
21961
|
+
networkFee: signResult.networkFee,
|
|
21962
|
+
valueMismatch: signResult.valueMismatch
|
|
21963
|
+
};
|
|
21964
|
+
}
|
|
21965
|
+
/**
|
|
21966
|
+
* Resumable, stateless clearing state machine for one stuck reservation —
|
|
21967
|
+
* Bitcoin itself is the state store, so every call either advances the flow
|
|
21968
|
+
* one step or reports where it stands (survives reloads and the multi-day
|
|
21969
|
+
* 6-confirmation wait; no internal polling).
|
|
21970
|
+
*
|
|
21971
|
+
* (a) reservation gone → phase "cleared"
|
|
21972
|
+
* (b) outpoint spent, >=6 confs → recoverStaleSpend → "cleared"/"failed"
|
|
21973
|
+
* outpoint spent, <6 confs → "awaiting-confirmations" (x/6)
|
|
21974
|
+
* (c) outpoint unspent → invalidateStaleSpend → "invalidator-broadcast"
|
|
21975
|
+
*/
|
|
21976
|
+
async clearStuckReservation(params) {
|
|
21977
|
+
this.ensureInitialized();
|
|
21978
|
+
const REQUIRED_CONFS = 6;
|
|
21979
|
+
const esploraBaseUrl = params.esploraBaseUrl ?? this.config.bitcoinProviders?.[0]?.url;
|
|
21980
|
+
const reconciled = await this.reconcilePendingWithdrawals(
|
|
21981
|
+
params.positionId,
|
|
21982
|
+
esploraBaseUrl ? { esploraBaseUrl } : void 0
|
|
21983
|
+
);
|
|
21984
|
+
const row = reconciled.find(
|
|
21985
|
+
(r) => r.spend.txid.toLowerCase() === params.utxoTxid.toLowerCase() && r.spend.vout === params.utxoVout
|
|
21986
|
+
);
|
|
21987
|
+
if (!row) {
|
|
21988
|
+
return { phase: "cleared" };
|
|
21989
|
+
}
|
|
21990
|
+
if (row.spendingTxid && esploraBaseUrl) {
|
|
21991
|
+
const base = esploraBaseUrl.replace(/\/+$/, "");
|
|
21992
|
+
const txRes = await fetch(`${base}/tx/${row.spendingTxid}`);
|
|
21993
|
+
const tipRes = await fetch(`${base}/blocks/tip/height`);
|
|
21994
|
+
let confirmations = 0;
|
|
21995
|
+
if (txRes.ok && tipRes.ok) {
|
|
21996
|
+
const tx = await txRes.json();
|
|
21997
|
+
const tip = Number(await tipRes.text());
|
|
21998
|
+
if (tx.status?.confirmed && typeof tx.status.block_height === "number" && Number.isFinite(tip)) {
|
|
21999
|
+
confirmations = Math.max(0, tip - tx.status.block_height + 1);
|
|
22000
|
+
}
|
|
22001
|
+
}
|
|
22002
|
+
if (confirmations < REQUIRED_CONFS) {
|
|
22003
|
+
return {
|
|
22004
|
+
phase: "awaiting-confirmations",
|
|
22005
|
+
invalidatorTxid: row.spendingTxid,
|
|
22006
|
+
confirmations,
|
|
22007
|
+
required: REQUIRED_CONFS
|
|
22008
|
+
};
|
|
22009
|
+
}
|
|
22010
|
+
const recovery = await this.recoverStaleSpend({
|
|
22011
|
+
positionId: params.positionId,
|
|
22012
|
+
utxoTxid: params.utxoTxid,
|
|
22013
|
+
utxoVout: params.utxoVout,
|
|
22014
|
+
invalidatorTxid: row.spendingTxid
|
|
22015
|
+
});
|
|
22016
|
+
if (recovery.success) {
|
|
22017
|
+
return {
|
|
22018
|
+
phase: "cleared",
|
|
22019
|
+
invalidatorTxid: row.spendingTxid,
|
|
22020
|
+
transactionHash: recovery.transactionHash,
|
|
22021
|
+
classification: recovery.classification
|
|
22022
|
+
};
|
|
22023
|
+
}
|
|
22024
|
+
return {
|
|
22025
|
+
phase: "failed",
|
|
22026
|
+
invalidatorTxid: row.spendingTxid,
|
|
22027
|
+
error: recovery.error ?? "stale-spend recovery failed"
|
|
22028
|
+
};
|
|
22029
|
+
}
|
|
22030
|
+
const invalidation = await this.invalidateStaleSpend({
|
|
22031
|
+
positionId: params.positionId,
|
|
22032
|
+
utxoTxid: params.utxoTxid,
|
|
22033
|
+
utxoVout: params.utxoVout
|
|
22034
|
+
});
|
|
22035
|
+
if (!invalidation.success) {
|
|
22036
|
+
return {
|
|
22037
|
+
phase: "failed",
|
|
22038
|
+
error: invalidation.error ?? "invalidator signing/broadcast failed"
|
|
22039
|
+
};
|
|
22040
|
+
}
|
|
22041
|
+
if (invalidation.alreadySpent) {
|
|
22042
|
+
return {
|
|
22043
|
+
phase: "awaiting-confirmations",
|
|
22044
|
+
invalidatorTxid: invalidation.alreadySpent.spendingTxid,
|
|
22045
|
+
confirmations: 0,
|
|
22046
|
+
required: REQUIRED_CONFS
|
|
22047
|
+
};
|
|
22048
|
+
}
|
|
22049
|
+
return {
|
|
22050
|
+
phase: "invalidator-broadcast",
|
|
22051
|
+
invalidatorTxid: invalidation.invalidatorTxid,
|
|
22052
|
+
valueMismatch: invalidation.valueMismatch
|
|
22053
|
+
};
|
|
22054
|
+
}
|
|
21566
22055
|
/**
|
|
21567
22056
|
* Withdraw BTC and execute transfer (Complete Flow)
|
|
21568
22057
|
*
|
|
@@ -21973,10 +22462,10 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
21973
22462
|
"function allowance(address owner, address spender) view returns (uint256)",
|
|
21974
22463
|
"function approve(address spender, uint256 amount) returns (bool)"
|
|
21975
22464
|
];
|
|
21976
|
-
const stablecoin = new
|
|
22465
|
+
const stablecoin = new import_ethers15.Contract(params.stablecoinAddress, erc20Abi, params.signer);
|
|
21977
22466
|
const allowance = await stablecoin.allowance(signerAddress, psmAddress);
|
|
21978
22467
|
if (allowance < params.amountWei) {
|
|
21979
|
-
const approveTx = await stablecoin.approve(psmAddress,
|
|
22468
|
+
const approveTx = await stablecoin.approve(psmAddress, import_ethers15.MaxUint256);
|
|
21980
22469
|
await approveTx.wait();
|
|
21981
22470
|
}
|
|
21982
22471
|
const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
|
|
@@ -22011,10 +22500,10 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22011
22500
|
"function allowance(address owner, address spender) view returns (uint256)",
|
|
22012
22501
|
"function approve(address spender, uint256 amount) returns (bool)"
|
|
22013
22502
|
];
|
|
22014
|
-
const ucdToken = new
|
|
22503
|
+
const ucdToken = new import_ethers15.Contract(ucdAddress, erc20Abi, params.signer);
|
|
22015
22504
|
const allowance = await ucdToken.allowance(signerAddress, ucdControllerAddress);
|
|
22016
22505
|
if (allowance < params.ucdAmountWei) {
|
|
22017
|
-
const approveTx = await ucdToken.approve(ucdControllerAddress,
|
|
22506
|
+
const approveTx = await ucdToken.approve(ucdControllerAddress, import_ethers15.MaxUint256);
|
|
22018
22507
|
await approveTx.wait();
|
|
22019
22508
|
}
|
|
22020
22509
|
const psm = SimplePSMV2__factory.connect(psmAddress, params.signer);
|
|
@@ -22226,7 +22715,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22226
22715
|
const maxUcdWhole = BigInt(result[3].toString());
|
|
22227
22716
|
return success({
|
|
22228
22717
|
liquidationThreshold: result[0].toString(),
|
|
22229
|
-
minimumLoanValueUcd: (0,
|
|
22718
|
+
minimumLoanValueUcd: (0, import_ethers15.formatUnits)(result[2], 18),
|
|
22230
22719
|
minimumLoanValueWei: result[2].toString(),
|
|
22231
22720
|
maxSingleLoanValueUcd: maxUcdWhole.toString(),
|
|
22232
22721
|
maxSingleLoanValueWei: (maxUcdWhole * 10n ** 18n).toString()
|
|
@@ -22263,7 +22752,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22263
22752
|
const balanceWei = await provider.getBalance(address);
|
|
22264
22753
|
return success({
|
|
22265
22754
|
balanceWei: balanceWei.toString(),
|
|
22266
|
-
balanceEth: (0,
|
|
22755
|
+
balanceEth: (0, import_ethers15.formatEther)(balanceWei)
|
|
22267
22756
|
});
|
|
22268
22757
|
} catch (error) {
|
|
22269
22758
|
return failure(new SDKError({
|
|
@@ -22653,7 +23142,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22653
23142
|
* Convert decimal position ID to bytes32 format
|
|
22654
23143
|
*/
|
|
22655
23144
|
toBytes32(value) {
|
|
22656
|
-
return (0,
|
|
23145
|
+
return (0, import_ethers15.zeroPadValue)((0, import_ethers15.toBeHex)(BigInt(value)), 32);
|
|
22657
23146
|
}
|
|
22658
23147
|
/**
|
|
22659
23148
|
* Check if an error indicates a technical failure vs business logic rejection
|
|
@@ -22694,7 +23183,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22694
23183
|
const coreModuleAbi = [
|
|
22695
23184
|
"function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
|
|
22696
23185
|
];
|
|
22697
|
-
const coreModule = new
|
|
23186
|
+
const coreModule = new import_ethers15.Contract(
|
|
22698
23187
|
coreModuleAddress,
|
|
22699
23188
|
coreModuleAbi,
|
|
22700
23189
|
provider
|
|
@@ -22761,7 +23250,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22761
23250
|
const corePositionAbi = [
|
|
22762
23251
|
"function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, uint8 status, uint40 previousExpiryAt, uint16 totalTerm))"
|
|
22763
23252
|
];
|
|
22764
|
-
const corePositionContract = new
|
|
23253
|
+
const corePositionContract = new import_ethers15.Contract(
|
|
22765
23254
|
coreAddress,
|
|
22766
23255
|
corePositionAbi,
|
|
22767
23256
|
provider
|
|
@@ -22772,7 +23261,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22772
23261
|
positionIdBytes32
|
|
22773
23262
|
);
|
|
22774
23263
|
const positionIdFromCore = corePosition?.positionId || corePosition?.[0] || null;
|
|
22775
|
-
if (positionIdFromCore && positionIdFromCore !==
|
|
23264
|
+
if (positionIdFromCore && positionIdFromCore !== import_ethers15.ZeroHash && positionIdFromCore !== "0x0000000000000000000000000000000000000000000000000000000000000000") {
|
|
22776
23265
|
if (this.config.debug) {
|
|
22777
23266
|
log.info("Position exists in core contract", {
|
|
22778
23267
|
positionId,
|
|
@@ -22840,7 +23329,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22840
23329
|
throw new Error("loanOperationsManager address not configured");
|
|
22841
23330
|
}
|
|
22842
23331
|
const runner = this.config.contractSigner || this.getProviderOrThrow();
|
|
22843
|
-
const contract = new
|
|
23332
|
+
const contract = new import_ethers15.Contract(
|
|
22844
23333
|
addr.loanOperationsManager,
|
|
22845
23334
|
[
|
|
22846
23335
|
"function getProtocolConfig() external view returns (uint256 liquidationThreshold, uint256 minimumLoanValueUcd, uint256 minimumLoanValueWei, uint256 maxSingleLoanValueUcd)"
|
|
@@ -22853,7 +23342,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22853
23342
|
const maxUcdWhole = BigInt(result[3].toString());
|
|
22854
23343
|
return {
|
|
22855
23344
|
liquidationThreshold: result[0].toString(),
|
|
22856
|
-
minimumLoanValueUcd: (0,
|
|
23345
|
+
minimumLoanValueUcd: (0, import_ethers15.formatUnits)(result[2], 18),
|
|
22857
23346
|
minimumLoanValueWei: result[2].toString(),
|
|
22858
23347
|
maxSingleLoanValueUcd: maxUcdWhole.toString(),
|
|
22859
23348
|
maxSingleLoanValueWei: (maxUcdWhole * 10n ** 18n).toString()
|
|
@@ -22871,8 +23360,8 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22871
23360
|
const MIN_REVEAL_DELAY = 60;
|
|
22872
23361
|
const MAX_RANDOM_DELAY = 240;
|
|
22873
23362
|
const entropyInput = positionId + quantumTimestamp.toString();
|
|
22874
|
-
const hash = (0,
|
|
22875
|
-
(0,
|
|
23363
|
+
const hash = (0, import_ethers15.keccak256)(
|
|
23364
|
+
(0, import_ethers15.toUtf8Bytes)(entropyInput)
|
|
22876
23365
|
);
|
|
22877
23366
|
const randomValue = BigInt(hash);
|
|
22878
23367
|
const randomDelay = Number(randomValue % BigInt(MAX_RANDOM_DELAY));
|
|
@@ -22897,12 +23386,12 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22897
23386
|
const rawPositionId = /^0x/i.test(params.positionId.trim()) ? params.positionId.trim().slice(2) : params.positionId.trim();
|
|
22898
23387
|
const canonicalPositionId = "0x" + rawPositionId.padStart(64, "0").toLowerCase();
|
|
22899
23388
|
const intentTimestamp = Math.floor(Date.now() / 1e3);
|
|
22900
|
-
const intentActionHash = (0,
|
|
22901
|
-
const intentHash = (0,
|
|
23389
|
+
const intentActionHash = (0, import_ethers15.keccak256)((0, import_ethers15.toUtf8Bytes)("liquidate-position"));
|
|
23390
|
+
const intentHash = (0, import_ethers15.solidityPackedKeccak256)(
|
|
22902
23391
|
["bytes32", "uint256", "uint256", "address", "bytes32"],
|
|
22903
23392
|
[canonicalPositionId, intentTimestamp, chainId, intentSigner, intentActionHash]
|
|
22904
23393
|
);
|
|
22905
|
-
const intentSignature = await signer.signMessage((0,
|
|
23394
|
+
const intentSignature = await signer.signMessage((0, import_ethers15.getBytes)(intentHash));
|
|
22906
23395
|
const response = await fetch(endpoint, {
|
|
22907
23396
|
method: "POST",
|
|
22908
23397
|
headers: { "Content-Type": "application/json" },
|
|
@@ -22954,7 +23443,7 @@ Message: ${causeMessage}${quantumContext}${mintDebtDiagnostics}`
|
|
|
22954
23443
|
const vrfSeedRaw = await lmResult.value["vrfSeeds"](positionId);
|
|
22955
23444
|
const vrfSeed = BigInt(vrfSeedRaw.toString());
|
|
22956
23445
|
if (vrfSeed !== 0n) {
|
|
22957
|
-
const finalEntropy = (0,
|
|
23446
|
+
const finalEntropy = (0, import_ethers15.solidityPackedKeccak256)(
|
|
22958
23447
|
["uint256", "uint256", "bytes32"],
|
|
22959
23448
|
[vrfSeed, BigInt(quantumTimestamp.toString()), positionId]
|
|
22960
23449
|
);
|
|
@@ -23232,14 +23721,14 @@ var EventHelpers = {
|
|
|
23232
23721
|
};
|
|
23233
23722
|
|
|
23234
23723
|
// src/utils/position-delegate.utils.ts
|
|
23235
|
-
var
|
|
23724
|
+
var import_ethers16 = require("ethers");
|
|
23236
23725
|
var POSITION_DELEGATE_REGISTRY_ABI = [
|
|
23237
23726
|
"function positionDelegate(bytes32 positionId) view returns (address)",
|
|
23238
23727
|
"function setPositionDelegate(bytes32 positionId, address newDelegate) external",
|
|
23239
23728
|
"event PositionDelegateUpdated(bytes32 indexed positionId, address indexed oldDelegate, address indexed newDelegate)"
|
|
23240
23729
|
];
|
|
23241
23730
|
async function setPositionDelegate(positionId, delegate, signer, registryAddress) {
|
|
23242
|
-
const registry = new
|
|
23731
|
+
const registry = new import_ethers16.Contract(
|
|
23243
23732
|
registryAddress,
|
|
23244
23733
|
POSITION_DELEGATE_REGISTRY_ABI,
|
|
23245
23734
|
signer
|
|
@@ -23247,7 +23736,7 @@ async function setPositionDelegate(positionId, delegate, signer, registryAddress
|
|
|
23247
23736
|
return registry["setPositionDelegate"](positionId, delegate);
|
|
23248
23737
|
}
|
|
23249
23738
|
async function getPositionDelegate(positionId, provider, registryAddress) {
|
|
23250
|
-
const registry = new
|
|
23739
|
+
const registry = new import_ethers16.Contract(
|
|
23251
23740
|
registryAddress,
|
|
23252
23741
|
POSITION_DELEGATE_REGISTRY_ABI,
|
|
23253
23742
|
provider
|
|
@@ -23276,6 +23765,7 @@ async function getPositionDelegate(positionId, provider, registryAddress) {
|
|
|
23276
23765
|
PKPManager,
|
|
23277
23766
|
PaymentType,
|
|
23278
23767
|
PositionStatus,
|
|
23768
|
+
RECOVERY_INVALIDATE_ACTION,
|
|
23279
23769
|
SDKError,
|
|
23280
23770
|
SDK_DEFAULTS,
|
|
23281
23771
|
SEPOLIA_CONTRACTS,
|
|
@@ -23288,6 +23778,8 @@ async function getPositionDelegate(positionId, provider, registryAddress) {
|
|
|
23288
23778
|
assertProtocolNotPaused,
|
|
23289
23779
|
assertSafeServiceEndpoint,
|
|
23290
23780
|
buildBtcExecuteEnvelope,
|
|
23781
|
+
buildInvalidateMessageHash,
|
|
23782
|
+
buildInvalidateStaleSpendEnvelope,
|
|
23291
23783
|
collectFailures,
|
|
23292
23784
|
collectSuccesses,
|
|
23293
23785
|
combine,
|
|
@@ -23298,6 +23790,7 @@ async function getPositionDelegate(positionId, provider, registryAddress) {
|
|
|
23298
23790
|
createLoanQuery,
|
|
23299
23791
|
createPKPManager,
|
|
23300
23792
|
createWithdrawalAddressModule,
|
|
23793
|
+
defaultHttpGetJson,
|
|
23301
23794
|
failure,
|
|
23302
23795
|
fetchProtocolPauseStatus,
|
|
23303
23796
|
firstSuccess,
|
|
@@ -23321,6 +23814,7 @@ async function getPositionDelegate(positionId, provider, registryAddress) {
|
|
|
23321
23814
|
mapError,
|
|
23322
23815
|
match,
|
|
23323
23816
|
numericToPositionStatus,
|
|
23817
|
+
reconcileAuthorizedSpend,
|
|
23324
23818
|
setPositionDelegate,
|
|
23325
23819
|
success,
|
|
23326
23820
|
toPromise,
|