@gvnrdao/dh-sdk 0.0.205 → 0.0.207
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +688 -585
- package/dist/index.mjs +688 -585
- package/dist/interfaces/chunks/config.i.d.ts +0 -5
- package/dist/modules/bitcoin/bitcoin-operations.module.d.ts +2 -10
- package/dist/modules/cache/cache-manager.module.d.ts +200 -41
- package/dist/modules/diamond-hands-sdk.d.ts +11 -14
- package/dist/modules/loan/loan-query.module.d.ts +3 -5
- package/dist/modules/pkp/pkp-manager.module.d.ts +1 -5
- package/dist/utils/mint-authorization.utils.d.ts +11 -4
- package/package.json +2 -3
- package/browser/dist/397.browser.js +0 -2
- package/browser/dist/397.browser.js.LICENSE.txt +0 -1
- package/browser/dist/833.browser.js +0 -2
- package/browser/dist/833.browser.js.LICENSE.txt +0 -1
- package/browser/dist/browser.js +0 -2
- package/browser/dist/browser.js.LICENSE.txt +0 -23
package/dist/index.mjs
CHANGED
|
@@ -12968,68 +12968,66 @@ var init_deployment_addresses = __esm({
|
|
|
12968
12968
|
LOCALHOST_DEPLOYMENT = {
|
|
12969
12969
|
network: "localhost",
|
|
12970
12970
|
chainId: 31337,
|
|
12971
|
-
timestamp: "2026-
|
|
12971
|
+
timestamp: "2026-03-23T15:33:34.068Z",
|
|
12972
12972
|
deployer: "",
|
|
12973
12973
|
contracts: {
|
|
12974
|
-
MessageHashBuilder: "
|
|
12975
|
-
UpgradeValidator: "
|
|
12974
|
+
MessageHashBuilder: "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
|
|
12975
|
+
UpgradeValidator: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
|
|
12976
12976
|
UCDToken: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
|
|
12977
12977
|
UCDController: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
|
|
12978
|
-
PositionManagerCoreModule: "
|
|
12979
|
-
TermManagerModule: "
|
|
12980
|
-
LoanOperationsManagerModule: "
|
|
12978
|
+
PositionManagerCoreModule: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
|
|
12979
|
+
TermManagerModule: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
|
|
12980
|
+
LoanOperationsManagerModule: "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
|
|
12981
12981
|
BTCSpendAuthorizer: "0x59b670e9fA9D0A427751Af201D676719a970857b",
|
|
12982
12982
|
CollateralManagerModule: "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
|
|
12983
12983
|
LiquidationManagerModule: "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
|
|
12984
|
-
CircuitBreakerModule: "
|
|
12984
|
+
CircuitBreakerModule: "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
|
|
12985
12985
|
AdminModule: "0xc5a5C42992dECbae36851359345FE25997F5C42d",
|
|
12986
|
-
PositionManagerViews: "
|
|
12987
|
-
PositionManager: "
|
|
12988
|
-
OperationAuthorizationRegistry: "
|
|
12989
|
-
PKPValidation: "
|
|
12986
|
+
PositionManagerViews: "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
|
|
12987
|
+
PositionManager: "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
|
|
12988
|
+
OperationAuthorizationRegistry: "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0",
|
|
12989
|
+
PKPValidation: "0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc"
|
|
12990
12990
|
},
|
|
12991
12991
|
latestEnv: {
|
|
12992
12992
|
UCD_TOKEN: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
|
|
12993
12993
|
UCD_CONTROLLER: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
|
|
12994
|
-
POSITION_MANAGER: "
|
|
12995
|
-
PKP_VALIDATION_REGISTRY: "
|
|
12996
|
-
PKP_VALIDATION_CID_V1: "
|
|
12997
|
-
|
|
12998
|
-
|
|
12999
|
-
|
|
13000
|
-
UCD_MINT_VALIDATOR_ADDRESS: "0xC6E57a5d65e43910Fe70667C97D193FAF6dDF598",
|
|
12994
|
+
POSITION_MANAGER: "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
|
|
12995
|
+
PKP_VALIDATION_REGISTRY: "0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc",
|
|
12996
|
+
PKP_VALIDATION_CID_V1: "QmfHJKA4RnW7RepsdLmrDwKjVTzPXB2K3qMTco3JNPDexm",
|
|
12997
|
+
PKP_ETH_ADDRESS: "0x9624C46073E1d1F5AB975c67Fc899536d599bb57",
|
|
12998
|
+
OPERATION_AUTHORIZATION_REGISTRY: "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0",
|
|
12999
|
+
UCD_MINT_VALIDATOR_ADDRESS: "0x80f81afb9e6dF27afCD752ad46cD286e705e42be",
|
|
13001
13000
|
UCD_MINT_VALIDATOR_VERSION: 1,
|
|
13002
|
-
BTC_WITHDRAWAL_VALIDATOR_ADDRESS: "
|
|
13001
|
+
BTC_WITHDRAWAL_VALIDATOR_ADDRESS: "0xa751ad81E1CAe61d6cF5Cf64839Fe8D28A1372Df",
|
|
13003
13002
|
BTC_WITHDRAWAL_VALIDATOR_VERSION: 1,
|
|
13004
|
-
UPDATE_BALANCE_VALIDATOR_ADDRESS: "
|
|
13003
|
+
UPDATE_BALANCE_VALIDATOR_ADDRESS: "0x8A40C22B03348bc10df9ae0dc54346b4AE8e909c",
|
|
13005
13004
|
UPDATE_BALANCE_VALIDATOR_VERSION: 1,
|
|
13006
|
-
PROCESS_PAYMENT_VALIDATOR_ADDRESS: "
|
|
13005
|
+
PROCESS_PAYMENT_VALIDATOR_ADDRESS: "0x28f50E07532d3aF677b8E0bcF220422d159b0dd6",
|
|
13007
13006
|
PROCESS_PAYMENT_VALIDATOR_VERSION: 1,
|
|
13008
|
-
EXTEND_POSITION_VALIDATOR_ADDRESS: "
|
|
13007
|
+
EXTEND_POSITION_VALIDATOR_ADDRESS: "0xc7aC43F2F907123465449575e853f5D0229898e1",
|
|
13009
13008
|
EXTEND_POSITION_VALIDATOR_VERSION: 1,
|
|
13010
|
-
POSITION_MANAGER_CORE_MODULE: "
|
|
13011
|
-
LOAN_OPERATIONS_MANAGER_MODULE: "
|
|
13012
|
-
TERM_MANAGER_MODULE: "
|
|
13013
|
-
COMMUNITY_MANAGER_MODULE: ""
|
|
13009
|
+
POSITION_MANAGER_CORE_MODULE: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
|
|
13010
|
+
LOAN_OPERATIONS_MANAGER_MODULE: "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
|
|
13011
|
+
TERM_MANAGER_MODULE: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82"
|
|
13014
13012
|
}
|
|
13015
13013
|
};
|
|
13016
13014
|
LOCALHOST_CONTRACTS = {
|
|
13017
|
-
MessageHashBuilder: "
|
|
13018
|
-
UpgradeValidator: "
|
|
13015
|
+
MessageHashBuilder: "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
|
|
13016
|
+
UpgradeValidator: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
|
|
13019
13017
|
UCDToken: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
|
|
13020
13018
|
UCDController: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
|
|
13021
|
-
PositionManagerCoreModule: "
|
|
13022
|
-
TermManagerModule: "
|
|
13023
|
-
LoanOperationsManagerModule: "
|
|
13019
|
+
PositionManagerCoreModule: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
|
|
13020
|
+
TermManagerModule: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
|
|
13021
|
+
LoanOperationsManagerModule: "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
|
|
13024
13022
|
BTCSpendAuthorizer: "0x59b670e9fA9D0A427751Af201D676719a970857b",
|
|
13025
13023
|
CollateralManagerModule: "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
|
|
13026
13024
|
LiquidationManagerModule: "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
|
|
13027
|
-
CircuitBreakerModule: "
|
|
13025
|
+
CircuitBreakerModule: "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
|
|
13028
13026
|
AdminModule: "0xc5a5C42992dECbae36851359345FE25997F5C42d",
|
|
13029
|
-
PositionManagerViews: "
|
|
13030
|
-
PositionManager: "
|
|
13031
|
-
OperationAuthorizationRegistry: "
|
|
13032
|
-
PKPValidation: "
|
|
13027
|
+
PositionManagerViews: "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
|
|
13028
|
+
PositionManager: "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
|
|
13029
|
+
OperationAuthorizationRegistry: "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0",
|
|
13030
|
+
PKPValidation: "0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc"
|
|
13033
13031
|
};
|
|
13034
13032
|
ALL_DEPLOYMENTS = {
|
|
13035
13033
|
sepolia: SEPOLIA_DEPLOYMENT,
|
|
@@ -29493,8 +29491,6 @@ function validateQuantumTiming(signedTimestamp, _bufferSeconds = 30) {
|
|
|
29493
29491
|
var PKP_NFT_ABI = [
|
|
29494
29492
|
"function getPubkey(uint256 tokenId) external view returns (bytes memory)"
|
|
29495
29493
|
];
|
|
29496
|
-
var CHIPOTLE_RPC_URL = "https://yellowstone-rpc.litprotocol.com";
|
|
29497
|
-
var CHIPOTLE_CHAIN_ID = 175188;
|
|
29498
29494
|
async function generateMintAuthorization(positionId, amount, chainId, signerOrPrecomputed) {
|
|
29499
29495
|
if (typeof signerOrPrecomputed === "object" && "signature" in signerOrPrecomputed && !("signMessage" in signerOrPrecomputed)) {
|
|
29500
29496
|
const { timestamp: timestamp2, signature: signature3 } = signerOrPrecomputed;
|
|
@@ -29594,18 +29590,14 @@ async function generatePaymentAuthorization(positionId, amount, chainId, signer)
|
|
|
29594
29590
|
};
|
|
29595
29591
|
}
|
|
29596
29592
|
async function getPKPPublicKeyFromTokenId(pkpTokenId, provider, pkpNftContractAddress) {
|
|
29597
|
-
const
|
|
29598
|
-
|
|
29599
|
-
|
|
29600
|
-
|
|
29601
|
-
|
|
29602
|
-
|
|
29603
|
-
|
|
29604
|
-
|
|
29605
|
-
litChainProvider = new ethers_exports.providers.JsonRpcProvider(targetRpc);
|
|
29606
|
-
}
|
|
29607
|
-
} else {
|
|
29608
|
-
litChainProvider = new ethers_exports.providers.JsonRpcProvider(targetRpc);
|
|
29593
|
+
const rawHex = pkpTokenId.startsWith("0x") ? pkpTokenId.slice(2) : pkpTokenId;
|
|
29594
|
+
if (rawHex.length === 64 && rawHex.startsWith("000000000000000000000000") && rawHex !== "0".repeat(64)) {
|
|
29595
|
+
throw new Error(
|
|
29596
|
+
`pkpId ${pkpTokenId} is a Chipotle wallet address (ABI-encoded ETH address). Chipotle PKPs are not NFTs and have no on-chain public key lookup. Ensure the PKP public key is populated in cache during position creation.`
|
|
29597
|
+
);
|
|
29598
|
+
}
|
|
29599
|
+
if (!provider) {
|
|
29600
|
+
throw new Error(`provider is required for getPKPPublicKeyFromTokenId`);
|
|
29609
29601
|
}
|
|
29610
29602
|
if (!pkpNftContractAddress) {
|
|
29611
29603
|
throw new Error(
|
|
@@ -29615,7 +29607,7 @@ async function getPKPPublicKeyFromTokenId(pkpTokenId, provider, pkpNftContractAd
|
|
|
29615
29607
|
const pkpNft = new ethers_exports.Contract(
|
|
29616
29608
|
pkpNftContractAddress,
|
|
29617
29609
|
PKP_NFT_ABI,
|
|
29618
|
-
|
|
29610
|
+
provider
|
|
29619
29611
|
);
|
|
29620
29612
|
const tokenIdBN = ethers_exports.BigNumber.from(pkpTokenId);
|
|
29621
29613
|
const pubkeyBytes = await pkpNft["getPubkey"](tokenIdBN);
|
|
@@ -30220,106 +30212,333 @@ function createContractManager(config) {
|
|
|
30220
30212
|
}
|
|
30221
30213
|
|
|
30222
30214
|
// src/modules/cache/cache-manager.module.ts
|
|
30223
|
-
var
|
|
30224
|
-
cache
|
|
30215
|
+
var LRUCache = class {
|
|
30216
|
+
cache;
|
|
30225
30217
|
maxSize;
|
|
30226
30218
|
ttlMs;
|
|
30227
|
-
|
|
30228
|
-
|
|
30229
|
-
|
|
30219
|
+
debug;
|
|
30220
|
+
name;
|
|
30221
|
+
// Statistics
|
|
30222
|
+
stats = {
|
|
30223
|
+
hits: 0,
|
|
30224
|
+
misses: 0,
|
|
30225
|
+
evictions: 0
|
|
30226
|
+
};
|
|
30227
|
+
constructor(config = {}) {
|
|
30228
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
30229
|
+
this.maxSize = config.maxSize || 1e3;
|
|
30230
|
+
this.ttlMs = config.ttlMs || 6e4;
|
|
30231
|
+
this.debug = config.debug || false;
|
|
30232
|
+
this.name = config.name || "Cache";
|
|
30233
|
+
if (this.debug) {
|
|
30234
|
+
console.log(
|
|
30235
|
+
`\u{1F4BE} [${this.name}] Initialized: maxSize=${this.maxSize}, ttl=${this.ttlMs}ms`
|
|
30236
|
+
);
|
|
30237
|
+
}
|
|
30230
30238
|
}
|
|
30231
30239
|
/**
|
|
30232
30240
|
* Get value from cache
|
|
30241
|
+
*
|
|
30242
|
+
* Returns null if:
|
|
30243
|
+
* - Key not found
|
|
30244
|
+
* - Entry has expired
|
|
30245
|
+
*
|
|
30246
|
+
* @param key - Cache key
|
|
30247
|
+
* @returns Cached value or null
|
|
30233
30248
|
*/
|
|
30234
30249
|
get(key2) {
|
|
30235
30250
|
const entry = this.cache.get(key2);
|
|
30236
30251
|
if (!entry) {
|
|
30237
|
-
|
|
30252
|
+
this.stats.misses++;
|
|
30253
|
+
if (this.debug) {
|
|
30254
|
+
console.log(`\u274C [${this.name}] Cache MISS: ${String(key2)}`);
|
|
30255
|
+
}
|
|
30256
|
+
return null;
|
|
30238
30257
|
}
|
|
30239
|
-
|
|
30240
|
-
if (now2 - entry.timestamp > entry.ttl) {
|
|
30258
|
+
if (this.isExpired(entry)) {
|
|
30241
30259
|
this.cache.delete(key2);
|
|
30242
|
-
|
|
30260
|
+
this.stats.misses++;
|
|
30261
|
+
if (this.debug) {
|
|
30262
|
+
const age = Date.now() - entry.timestamp;
|
|
30263
|
+
console.log(`\u23F0 [${this.name}] Cache EXPIRED: ${String(key2)} (age: ${age}ms)`);
|
|
30264
|
+
}
|
|
30265
|
+
return null;
|
|
30266
|
+
}
|
|
30267
|
+
entry.hits++;
|
|
30268
|
+
entry.lastAccessed = Date.now();
|
|
30269
|
+
this.cache.set(key2, entry);
|
|
30270
|
+
this.stats.hits++;
|
|
30271
|
+
if (this.debug) {
|
|
30272
|
+
const age = Date.now() - entry.timestamp;
|
|
30273
|
+
console.log(
|
|
30274
|
+
`\u2705 [${this.name}] Cache HIT: ${String(key2)} (age: ${age}ms, hits: ${entry.hits})`
|
|
30275
|
+
);
|
|
30243
30276
|
}
|
|
30244
30277
|
return entry.value;
|
|
30245
30278
|
}
|
|
30279
|
+
/**
|
|
30280
|
+
* Get value from cache with Result wrapper
|
|
30281
|
+
*
|
|
30282
|
+
* Useful when you want to distinguish between "not found" and "expired"
|
|
30283
|
+
*/
|
|
30284
|
+
getResult(key2) {
|
|
30285
|
+
const value = this.get(key2);
|
|
30286
|
+
if (value === null) {
|
|
30287
|
+
return failure(
|
|
30288
|
+
new SDKError({
|
|
30289
|
+
message: `Cache miss for key: ${String(key2)}`,
|
|
30290
|
+
category: "CACHE" /* CACHE */,
|
|
30291
|
+
severity: "LOW" /* LOW */,
|
|
30292
|
+
originalError: new Error("Cache miss")
|
|
30293
|
+
})
|
|
30294
|
+
);
|
|
30295
|
+
}
|
|
30296
|
+
return success(value);
|
|
30297
|
+
}
|
|
30246
30298
|
/**
|
|
30247
30299
|
* Set value in cache
|
|
30300
|
+
*
|
|
30301
|
+
* If cache is full, evicts the least recently used entry
|
|
30302
|
+
*
|
|
30303
|
+
* @param key - Cache key
|
|
30304
|
+
* @param value - Value to cache
|
|
30305
|
+
* @param ttl - Optional custom TTL for this entry (ms)
|
|
30248
30306
|
*/
|
|
30249
30307
|
set(key2, value, ttl) {
|
|
30250
30308
|
if (this.cache.size >= this.maxSize && !this.cache.has(key2)) {
|
|
30251
|
-
|
|
30252
|
-
if (firstKey) {
|
|
30253
|
-
this.cache.delete(firstKey);
|
|
30254
|
-
}
|
|
30309
|
+
this.evictLRU();
|
|
30255
30310
|
}
|
|
30256
|
-
|
|
30311
|
+
const entry = {
|
|
30257
30312
|
value,
|
|
30258
30313
|
timestamp: Date.now(),
|
|
30259
|
-
|
|
30260
|
-
|
|
30314
|
+
hits: 0,
|
|
30315
|
+
lastAccessed: Date.now()
|
|
30316
|
+
};
|
|
30317
|
+
this.cache.set(key2, entry);
|
|
30318
|
+
if (this.debug) {
|
|
30319
|
+
const effectiveTtl = ttl || this.ttlMs;
|
|
30320
|
+
console.log(
|
|
30321
|
+
`\u{1F4BE} [${this.name}] Cache SET: ${String(key2)} (ttl: ${effectiveTtl}ms, size: ${this.cache.size}/${this.maxSize})`
|
|
30322
|
+
);
|
|
30323
|
+
}
|
|
30261
30324
|
}
|
|
30262
30325
|
/**
|
|
30263
|
-
*
|
|
30326
|
+
* Set value in cache with Result wrapper
|
|
30327
|
+
*/
|
|
30328
|
+
setResult(key2, value, ttl) {
|
|
30329
|
+
try {
|
|
30330
|
+
this.set(key2, value, ttl);
|
|
30331
|
+
return success(void 0);
|
|
30332
|
+
} catch (error) {
|
|
30333
|
+
return failure(
|
|
30334
|
+
new SDKError({
|
|
30335
|
+
message: `Failed to set cache value for key: ${String(key2)}`,
|
|
30336
|
+
category: "CACHE" /* CACHE */,
|
|
30337
|
+
severity: "MEDIUM" /* MEDIUM */,
|
|
30338
|
+
originalError: error instanceof Error ? error : new Error(String(error))
|
|
30339
|
+
})
|
|
30340
|
+
);
|
|
30341
|
+
}
|
|
30342
|
+
}
|
|
30343
|
+
/**
|
|
30344
|
+
* Check if key exists in cache (without affecting stats)
|
|
30264
30345
|
*/
|
|
30265
30346
|
has(key2) {
|
|
30266
|
-
|
|
30347
|
+
const entry = this.cache.get(key2);
|
|
30348
|
+
return entry !== void 0 && !this.isExpired(entry);
|
|
30267
30349
|
}
|
|
30268
30350
|
/**
|
|
30269
|
-
* Delete key from cache
|
|
30351
|
+
* Delete specific key from cache
|
|
30270
30352
|
*/
|
|
30271
30353
|
delete(key2) {
|
|
30272
|
-
|
|
30354
|
+
const deleted = this.cache.delete(key2);
|
|
30355
|
+
if (deleted && this.debug) {
|
|
30356
|
+
console.log(`\u{1F5D1}\uFE0F [${this.name}] Cache DELETE: ${String(key2)}`);
|
|
30357
|
+
}
|
|
30358
|
+
return deleted;
|
|
30273
30359
|
}
|
|
30274
30360
|
/**
|
|
30275
|
-
* Clear
|
|
30361
|
+
* Clear entire cache
|
|
30276
30362
|
*/
|
|
30277
30363
|
clear() {
|
|
30364
|
+
const previousSize = this.cache.size;
|
|
30278
30365
|
this.cache.clear();
|
|
30366
|
+
this.stats = {
|
|
30367
|
+
hits: 0,
|
|
30368
|
+
misses: 0,
|
|
30369
|
+
evictions: 0
|
|
30370
|
+
};
|
|
30371
|
+
if (this.debug) {
|
|
30372
|
+
console.log(`\u{1F9F9} [${this.name}] Cache CLEARED: removed ${previousSize} entries`);
|
|
30373
|
+
}
|
|
30374
|
+
}
|
|
30375
|
+
/**
|
|
30376
|
+
* Get current cache size
|
|
30377
|
+
*/
|
|
30378
|
+
size() {
|
|
30379
|
+
return this.cache.size;
|
|
30380
|
+
}
|
|
30381
|
+
/**
|
|
30382
|
+
* Get cache statistics
|
|
30383
|
+
*/
|
|
30384
|
+
getStats() {
|
|
30385
|
+
const entries = Array.from(this.cache.values());
|
|
30386
|
+
const timestamps = entries.map((e) => e.timestamp);
|
|
30387
|
+
const total = this.stats.hits + this.stats.misses;
|
|
30388
|
+
const hitRate = total === 0 ? 0 : this.stats.hits / total * 100;
|
|
30389
|
+
return {
|
|
30390
|
+
size: this.cache.size,
|
|
30391
|
+
hits: this.stats.hits,
|
|
30392
|
+
misses: this.stats.misses,
|
|
30393
|
+
evictions: this.stats.evictions,
|
|
30394
|
+
oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : 0,
|
|
30395
|
+
newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : 0,
|
|
30396
|
+
hitRate
|
|
30397
|
+
};
|
|
30398
|
+
}
|
|
30399
|
+
/**
|
|
30400
|
+
* Get hit rate percentage
|
|
30401
|
+
*/
|
|
30402
|
+
getHitRate() {
|
|
30403
|
+
const total = this.stats.hits + this.stats.misses;
|
|
30404
|
+
return total === 0 ? 0 : this.stats.hits / total * 100;
|
|
30405
|
+
}
|
|
30406
|
+
/**
|
|
30407
|
+
* Get all cached keys (for debugging)
|
|
30408
|
+
*/
|
|
30409
|
+
getKeys() {
|
|
30410
|
+
return Array.from(this.cache.keys());
|
|
30411
|
+
}
|
|
30412
|
+
/**
|
|
30413
|
+
* Get all cached values (for debugging)
|
|
30414
|
+
*/
|
|
30415
|
+
getValues() {
|
|
30416
|
+
return Array.from(this.cache.values()).map((entry) => entry.value);
|
|
30417
|
+
}
|
|
30418
|
+
/**
|
|
30419
|
+
* Get all cache entries with metadata (for debugging)
|
|
30420
|
+
*/
|
|
30421
|
+
getEntries() {
|
|
30422
|
+
return Array.from(this.cache.entries()).map(([key2, entry]) => ({
|
|
30423
|
+
key: key2,
|
|
30424
|
+
value: entry.value,
|
|
30425
|
+
metadata: {
|
|
30426
|
+
timestamp: entry.timestamp,
|
|
30427
|
+
hits: entry.hits,
|
|
30428
|
+
lastAccessed: entry.lastAccessed
|
|
30429
|
+
}
|
|
30430
|
+
}));
|
|
30279
30431
|
}
|
|
30280
30432
|
/**
|
|
30281
|
-
* Clean expired entries
|
|
30433
|
+
* Clean up expired entries
|
|
30434
|
+
*
|
|
30435
|
+
* Useful for periodic maintenance
|
|
30436
|
+
*
|
|
30437
|
+
* @returns Number of entries cleaned
|
|
30282
30438
|
*/
|
|
30283
30439
|
cleanExpired() {
|
|
30284
30440
|
const now2 = Date.now();
|
|
30285
|
-
let
|
|
30441
|
+
let cleanedCount = 0;
|
|
30286
30442
|
for (const [key2, entry] of this.cache.entries()) {
|
|
30287
|
-
if (now2 - entry.timestamp >
|
|
30443
|
+
if (now2 - entry.timestamp > this.ttlMs) {
|
|
30288
30444
|
this.cache.delete(key2);
|
|
30289
|
-
|
|
30445
|
+
cleanedCount++;
|
|
30290
30446
|
}
|
|
30291
30447
|
}
|
|
30292
|
-
|
|
30448
|
+
if (cleanedCount > 0 && this.debug) {
|
|
30449
|
+
console.log(`\u{1F9F9} [${this.name}] Cleaned ${cleanedCount} expired entries`);
|
|
30450
|
+
}
|
|
30451
|
+
return cleanedCount;
|
|
30293
30452
|
}
|
|
30294
30453
|
/**
|
|
30295
|
-
*
|
|
30454
|
+
* Check if cache entry is expired
|
|
30296
30455
|
*/
|
|
30297
|
-
|
|
30298
|
-
return
|
|
30299
|
-
|
|
30300
|
-
|
|
30301
|
-
|
|
30302
|
-
|
|
30456
|
+
isExpired(entry) {
|
|
30457
|
+
return Date.now() - entry.timestamp > this.ttlMs;
|
|
30458
|
+
}
|
|
30459
|
+
/**
|
|
30460
|
+
* Evict least recently used entry
|
|
30461
|
+
*/
|
|
30462
|
+
evictLRU() {
|
|
30463
|
+
let oldestKey = null;
|
|
30464
|
+
let oldestAccess = Infinity;
|
|
30465
|
+
for (const [key2, entry] of this.cache.entries()) {
|
|
30466
|
+
if (entry.lastAccessed < oldestAccess) {
|
|
30467
|
+
oldestAccess = entry.lastAccessed;
|
|
30468
|
+
oldestKey = key2;
|
|
30469
|
+
}
|
|
30470
|
+
}
|
|
30471
|
+
if (oldestKey !== null) {
|
|
30472
|
+
this.cache.delete(oldestKey);
|
|
30473
|
+
this.stats.evictions++;
|
|
30474
|
+
if (this.debug) {
|
|
30475
|
+
const timeSinceAccess = Date.now() - oldestAccess;
|
|
30476
|
+
console.log(
|
|
30477
|
+
`\u267B\uFE0F [${this.name}] Cache EVICT (LRU): ${String(oldestKey)} (last accessed: ${timeSinceAccess}ms ago)`
|
|
30478
|
+
);
|
|
30479
|
+
}
|
|
30480
|
+
}
|
|
30481
|
+
}
|
|
30482
|
+
/**
|
|
30483
|
+
* Get or compute value
|
|
30484
|
+
*
|
|
30485
|
+
* If key exists in cache, returns cached value.
|
|
30486
|
+
* Otherwise, computes value using provided function and caches it.
|
|
30487
|
+
*
|
|
30488
|
+
* @param key - Cache key
|
|
30489
|
+
* @param compute - Function to compute value if not in cache
|
|
30490
|
+
* @param ttl - Optional custom TTL for this entry
|
|
30491
|
+
* @returns Cached or computed value
|
|
30492
|
+
*/
|
|
30493
|
+
async getOrCompute(key2, compute, ttl) {
|
|
30494
|
+
const cached = this.get(key2);
|
|
30495
|
+
if (cached !== null) {
|
|
30496
|
+
return cached;
|
|
30497
|
+
}
|
|
30498
|
+
const value = await compute();
|
|
30499
|
+
this.set(key2, value, ttl);
|
|
30500
|
+
return value;
|
|
30501
|
+
}
|
|
30502
|
+
/**
|
|
30503
|
+
* Get or compute value with Result wrapper
|
|
30504
|
+
*/
|
|
30505
|
+
async getOrComputeResult(key2, compute, ttl) {
|
|
30506
|
+
const cached = this.get(key2);
|
|
30507
|
+
if (cached !== null) {
|
|
30508
|
+
return success(cached);
|
|
30509
|
+
}
|
|
30510
|
+
const result = await compute();
|
|
30511
|
+
if (result.success) {
|
|
30512
|
+
this.set(key2, result.value, ttl);
|
|
30513
|
+
}
|
|
30514
|
+
return result;
|
|
30303
30515
|
}
|
|
30304
30516
|
};
|
|
30305
30517
|
var CacheManager = class {
|
|
30306
30518
|
caches = /* @__PURE__ */ new Map();
|
|
30307
|
-
|
|
30308
|
-
constructor(
|
|
30309
|
-
this.
|
|
30519
|
+
globalConfig;
|
|
30520
|
+
constructor(globalConfig = {}) {
|
|
30521
|
+
this.globalConfig = globalConfig;
|
|
30310
30522
|
}
|
|
30311
30523
|
/**
|
|
30312
|
-
*
|
|
30524
|
+
* Create or get a named cache
|
|
30525
|
+
*
|
|
30526
|
+
* @param name - Unique cache name
|
|
30527
|
+
* @param config - Optional cache-specific configuration
|
|
30528
|
+
* @returns LRU cache instance
|
|
30313
30529
|
*/
|
|
30314
30530
|
getCache(name, config) {
|
|
30315
|
-
|
|
30316
|
-
|
|
30531
|
+
const existingCache = this.caches.get(name);
|
|
30532
|
+
if (existingCache) {
|
|
30533
|
+
return existingCache;
|
|
30317
30534
|
}
|
|
30318
|
-
const
|
|
30535
|
+
const mergedConfig = {
|
|
30536
|
+
...this.globalConfig,
|
|
30537
|
+
...config,
|
|
30538
|
+
name
|
|
30539
|
+
};
|
|
30540
|
+
const cache = new LRUCache(mergedConfig);
|
|
30319
30541
|
this.caches.set(name, cache);
|
|
30320
|
-
if (this.debug) {
|
|
30321
|
-
console.log(`[CacheManager] Created cache: ${name}`, config);
|
|
30322
|
-
}
|
|
30323
30542
|
return cache;
|
|
30324
30543
|
}
|
|
30325
30544
|
/**
|
|
@@ -30334,11 +30553,11 @@ var CacheManager = class {
|
|
|
30334
30553
|
* Clean expired entries from all caches
|
|
30335
30554
|
*/
|
|
30336
30555
|
cleanAllExpired() {
|
|
30337
|
-
let
|
|
30556
|
+
let totalCleaned = 0;
|
|
30338
30557
|
for (const cache of this.caches.values()) {
|
|
30339
|
-
|
|
30558
|
+
totalCleaned += cache.cleanExpired();
|
|
30340
30559
|
}
|
|
30341
|
-
return
|
|
30560
|
+
return totalCleaned;
|
|
30342
30561
|
}
|
|
30343
30562
|
/**
|
|
30344
30563
|
* Get statistics for all caches
|
|
@@ -30351,11 +30570,16 @@ var CacheManager = class {
|
|
|
30351
30570
|
return stats;
|
|
30352
30571
|
}
|
|
30353
30572
|
/**
|
|
30354
|
-
*
|
|
30573
|
+
* Get list of all cache names
|
|
30355
30574
|
*/
|
|
30356
|
-
|
|
30357
|
-
this.
|
|
30358
|
-
|
|
30575
|
+
getCacheNames() {
|
|
30576
|
+
return Array.from(this.caches.keys());
|
|
30577
|
+
}
|
|
30578
|
+
/**
|
|
30579
|
+
* Delete a named cache
|
|
30580
|
+
*/
|
|
30581
|
+
deleteCache(name) {
|
|
30582
|
+
return this.caches.delete(name);
|
|
30359
30583
|
}
|
|
30360
30584
|
};
|
|
30361
30585
|
function createCacheManager(config) {
|
|
@@ -31634,6 +31858,23 @@ function createLoanCreator(config) {
|
|
|
31634
31858
|
}
|
|
31635
31859
|
|
|
31636
31860
|
// src/modules/loan/loan-query.module.ts
|
|
31861
|
+
var POSITION_CORE_ABI = [
|
|
31862
|
+
"function getPositionDetails(bytes32) view returns (tuple(bytes32 positionId, bytes32 pkpId, uint256 ucdDebt, string vaultAddress, address borrower, uint40 createdAt, uint40 lastUpdated, uint16 selectedTerm, uint40 expiryAt, bool isActive, uint8 status))"
|
|
31863
|
+
];
|
|
31864
|
+
function normalizePkpId(pkpId) {
|
|
31865
|
+
const raw = pkpId.startsWith("0x") ? pkpId.slice(2) : pkpId;
|
|
31866
|
+
if (raw.length === 64 && raw.startsWith("000000000000000000000000") && raw !== "0".repeat(64)) {
|
|
31867
|
+
return `0x${raw.slice(24)}`;
|
|
31868
|
+
}
|
|
31869
|
+
return pkpId;
|
|
31870
|
+
}
|
|
31871
|
+
function padPkpIdForSubgraph(pkpId) {
|
|
31872
|
+
const raw = pkpId.startsWith("0x") ? pkpId.slice(2) : pkpId;
|
|
31873
|
+
if (raw.length === 40) {
|
|
31874
|
+
return `0x${"0".repeat(24)}${raw}`;
|
|
31875
|
+
}
|
|
31876
|
+
return pkpId;
|
|
31877
|
+
}
|
|
31637
31878
|
var LoanQuery = class {
|
|
31638
31879
|
config;
|
|
31639
31880
|
defaultPageSize;
|
|
@@ -31662,7 +31903,7 @@ var LoanQuery = class {
|
|
|
31662
31903
|
const borrowerCreatedAt = typeof rawLoan.borrower === "object" && rawLoan.borrower?.createdAt ? Number(rawLoan.borrower.createdAt) : 0;
|
|
31663
31904
|
const loanData = {
|
|
31664
31905
|
id: rawLoan.id,
|
|
31665
|
-
pkpId: rawLoan.pkpId,
|
|
31906
|
+
pkpId: normalizePkpId(rawLoan.pkpId),
|
|
31666
31907
|
borrower: {
|
|
31667
31908
|
createdAt: borrowerCreatedAt,
|
|
31668
31909
|
id: borrowerId
|
|
@@ -31708,6 +31949,7 @@ var LoanQuery = class {
|
|
|
31708
31949
|
* @returns Loan data
|
|
31709
31950
|
*/
|
|
31710
31951
|
async getLoanByPkpId(pkpId, enrichBalance = false) {
|
|
31952
|
+
pkpId = padPkpIdForSubgraph(pkpId);
|
|
31711
31953
|
if (this.config.debug) {
|
|
31712
31954
|
log.info("\u{1F50D} Querying loan by PKP ID", { pkpId, enrichBalance });
|
|
31713
31955
|
}
|
|
@@ -31730,7 +31972,7 @@ var LoanQuery = class {
|
|
|
31730
31972
|
const borrowerCreatedAt = typeof rawLoan.borrower === "object" && rawLoan.borrower?.createdAt ? Number(rawLoan.borrower.createdAt) : 0;
|
|
31731
31973
|
const loanData = {
|
|
31732
31974
|
id: rawLoan.id,
|
|
31733
|
-
pkpId: rawLoan.pkpId,
|
|
31975
|
+
pkpId: normalizePkpId(rawLoan.pkpId),
|
|
31734
31976
|
borrower: {
|
|
31735
31977
|
createdAt: borrowerCreatedAt,
|
|
31736
31978
|
id: borrowerId
|
|
@@ -31909,10 +32151,30 @@ var LoanQuery = class {
|
|
|
31909
32151
|
await Promise.all(
|
|
31910
32152
|
batch.map(async (loan) => {
|
|
31911
32153
|
try {
|
|
31912
|
-
const
|
|
31913
|
-
|
|
31914
|
-
|
|
31915
|
-
|
|
32154
|
+
const rawId = loan.pkpId?.startsWith("0x") ? loan.pkpId.slice(2) : loan.pkpId;
|
|
32155
|
+
const isChipotlePkpId = typeof rawId === "string" && rawId.length === 40 && !rawId.toLowerCase().startsWith("04");
|
|
32156
|
+
if (isChipotlePkpId) {
|
|
32157
|
+
if (this.config.positionManagerCoreAddress && this.config.provider) {
|
|
32158
|
+
const pmContract = new ethers_exports.Contract(
|
|
32159
|
+
this.config.positionManagerCoreAddress,
|
|
32160
|
+
POSITION_CORE_ABI,
|
|
32161
|
+
this.config.provider
|
|
32162
|
+
);
|
|
32163
|
+
const pos = await pmContract["getPositionDetails"](loan.id);
|
|
32164
|
+
const vaultAddr = pos.vaultAddress ?? pos[3] ?? "";
|
|
32165
|
+
if (vaultAddr) {
|
|
32166
|
+
loan.collateral.vaultAddress = vaultAddr;
|
|
32167
|
+
if (this.config.debug) {
|
|
32168
|
+
log.info(`\u2705 Vault address from contract for loan ${loan.id}`, { vaultAddr });
|
|
32169
|
+
}
|
|
32170
|
+
}
|
|
32171
|
+
} else if (this.config.debug) {
|
|
32172
|
+
log.warn(`\u26A0\uFE0F Chipotle pkpId for loan ${loan.id} but no positionManagerCoreAddress configured`);
|
|
32173
|
+
}
|
|
32174
|
+
return;
|
|
32175
|
+
}
|
|
32176
|
+
const isUncompressedPubKey = typeof rawId === "string" && rawId.length === 130 && rawId.toLowerCase().startsWith("04");
|
|
32177
|
+
const pkpPublicKey = isUncompressedPubKey ? loan.pkpId.startsWith("0x") ? loan.pkpId : `0x${loan.pkpId}` : await getPKPPublicKeyFromTokenId(loan.pkpId, this.config.provider);
|
|
31916
32178
|
const addressesResult = await this.config.bitcoinOperations.deriveAddresses(pkpPublicKey);
|
|
31917
32179
|
if (addressesResult.success) {
|
|
31918
32180
|
loan.collateral.vaultAddress = addressesResult.value;
|
|
@@ -33348,6 +33610,13 @@ var GraphClient = class {
|
|
|
33348
33610
|
var THE_GRAPH_MAX_BATCH_SIZE = 1e3;
|
|
33349
33611
|
|
|
33350
33612
|
// src/graphs/diamond-hands.ts
|
|
33613
|
+
function normalizePkpId2(pkpId) {
|
|
33614
|
+
const raw = pkpId.startsWith("0x") ? pkpId.slice(2) : pkpId;
|
|
33615
|
+
if (raw.length === 64 && raw.startsWith("000000000000000000000000") && raw !== "0".repeat(64)) {
|
|
33616
|
+
return `0x${raw.slice(24)}`;
|
|
33617
|
+
}
|
|
33618
|
+
return pkpId;
|
|
33619
|
+
}
|
|
33351
33620
|
var DiamondHandsGraph = class {
|
|
33352
33621
|
client;
|
|
33353
33622
|
defaultPageSize;
|
|
@@ -33370,7 +33639,7 @@ var DiamondHandsGraph = class {
|
|
|
33370
33639
|
const ucdDebt = graphPosition.ucdDebt ? Number(graphPosition.ucdDebt) : 0;
|
|
33371
33640
|
return {
|
|
33372
33641
|
id: graphPosition.id,
|
|
33373
|
-
pkpId: graphPosition.pkpId,
|
|
33642
|
+
pkpId: normalizePkpId2(graphPosition.pkpId),
|
|
33374
33643
|
borrower: {
|
|
33375
33644
|
createdAt: graphPosition.borrower?.createdAt ? Number(graphPosition.borrower.createdAt) : 0,
|
|
33376
33645
|
id: graphPosition.borrower?.id || graphPosition.borrower
|
|
@@ -34632,39 +34901,6 @@ try {
|
|
|
34632
34901
|
} catch (error) {
|
|
34633
34902
|
console.warn("Telegram bot API not available:", error instanceof Error ? error.message : String(error));
|
|
34634
34903
|
}
|
|
34635
|
-
async function sendTelegramMessage(chatId, chatToken, message, threadId) {
|
|
34636
|
-
try {
|
|
34637
|
-
if (typeof window !== "undefined") {
|
|
34638
|
-
if (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1") {
|
|
34639
|
-
console.log("[Browser] Telegram messaging not available - skipping notification");
|
|
34640
|
-
}
|
|
34641
|
-
return;
|
|
34642
|
-
}
|
|
34643
|
-
if (!TelegramBot) {
|
|
34644
|
-
console.warn("Telegram bot API not available in this environment");
|
|
34645
|
-
return;
|
|
34646
|
-
}
|
|
34647
|
-
const bot = new TelegramBot(chatToken, { polling: false });
|
|
34648
|
-
const options = {
|
|
34649
|
-
disable_web_page_preview: true
|
|
34650
|
-
};
|
|
34651
|
-
if (threadId !== void 0) {
|
|
34652
|
-
options.message_thread_id = threadId;
|
|
34653
|
-
}
|
|
34654
|
-
console.log("\u{1F4F1} Sending Telegram message...");
|
|
34655
|
-
console.log(` Chat ID: ${chatId}`);
|
|
34656
|
-
console.log(` Thread ID: ${threadId || "none"}`);
|
|
34657
|
-
console.log(` Message: ${message}`);
|
|
34658
|
-
const result = await bot.sendMessage(chatId, message, options);
|
|
34659
|
-
console.log("\u2705 Telegram message sent successfully!");
|
|
34660
|
-
console.log(` Message ID: ${result.message_id}`);
|
|
34661
|
-
} catch (error) {
|
|
34662
|
-
console.error("\u274C Failed to send Telegram message:", error);
|
|
34663
|
-
if (error instanceof Error) {
|
|
34664
|
-
console.error(` Error message: ${error.message}`);
|
|
34665
|
-
}
|
|
34666
|
-
}
|
|
34667
|
-
}
|
|
34668
34904
|
function formatMintMessage(mintAmount, loanId, txHash) {
|
|
34669
34905
|
return `${mintAmount} UCD was minted for loan id: ${loanId} Tx: https://sepolia.etherscan.io/tx/${txHash}`;
|
|
34670
34906
|
}
|
|
@@ -34983,6 +35219,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
34983
35219
|
network: config.litNetwork || DEFAULT_LIT_NETWORK,
|
|
34984
35220
|
signer: config.mode === "standalone" ? config.litOpsSigner : void 0,
|
|
34985
35221
|
serviceEndpoint: isServiceModeConfig(config) ? config.serviceEndpoint : void 0,
|
|
35222
|
+
serviceAuthToken: isServiceModeConfig(config) ? config.serviceAuthToken : void 0,
|
|
34986
35223
|
debug: config.debug,
|
|
34987
35224
|
litNodeConnectTimeoutMs: config.litNodeConnectTimeoutMs
|
|
34988
35225
|
// TODO Round 2: Add litActionExecution config when added to config.i.ts interface
|
|
@@ -35040,19 +35277,21 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35040
35277
|
);
|
|
35041
35278
|
}
|
|
35042
35279
|
this.pkpManager = pkpManagerResult.value;
|
|
35043
|
-
const
|
|
35280
|
+
const serviceMode = isServiceModeConfig(config);
|
|
35281
|
+
const graphEndpoint = serviceMode ? `${config.serviceEndpoint}/api/lit/graph/query` : config.subgraphs?.diamondHandsUrl;
|
|
35044
35282
|
if (!graphEndpoint) {
|
|
35045
35283
|
throw new Error(
|
|
35046
35284
|
"Diamond Hands subgraph URL is required. Please provide config.subgraphs.diamondHandsUrl"
|
|
35047
35285
|
);
|
|
35048
35286
|
}
|
|
35287
|
+
const graphHeaders = serviceMode && config.serviceAuthToken ? { Authorization: `Bearer ${config.serviceAuthToken}` } : config.graphApiKey ? { Authorization: `Bearer ${config.graphApiKey}` } : void 0;
|
|
35049
35288
|
this.graphClient = new DiamondHandsGraph(
|
|
35050
35289
|
{
|
|
35051
35290
|
endpoint: graphEndpoint,
|
|
35052
35291
|
requestTimeoutMs: config.graphOptions?.requestTimeoutMs,
|
|
35053
35292
|
maxRetries: config.graphOptions?.maxRetries,
|
|
35054
35293
|
defaultPageSize: config.graphOptions?.pageSize,
|
|
35055
|
-
headers:
|
|
35294
|
+
headers: graphHeaders
|
|
35056
35295
|
},
|
|
35057
35296
|
this.bitcoinOperations
|
|
35058
35297
|
);
|
|
@@ -35060,6 +35299,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35060
35299
|
graphClient: this.graphClient,
|
|
35061
35300
|
bitcoinOperations: this.bitcoinOperations,
|
|
35062
35301
|
provider: config.provider,
|
|
35302
|
+
positionManagerCoreAddress: config.contractAddresses?.positionManagerCore,
|
|
35063
35303
|
cache: this.cacheManager.getCache("loan-data", {
|
|
35064
35304
|
maxSize: 200,
|
|
35065
35305
|
ttlMs: 3e4
|
|
@@ -35451,6 +35691,30 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35451
35691
|
/**
|
|
35452
35692
|
* Check if SDK is ready for operations
|
|
35453
35693
|
*/
|
|
35694
|
+
async _relayNotification(message) {
|
|
35695
|
+
if (this.config.mode !== "service")
|
|
35696
|
+
return;
|
|
35697
|
+
const endpoint = this.config.serviceEndpoint;
|
|
35698
|
+
if (!endpoint)
|
|
35699
|
+
return;
|
|
35700
|
+
const token = this.config.serviceAuthToken;
|
|
35701
|
+
try {
|
|
35702
|
+
await fetch(`${endpoint}/api/lit/notifications/send`, {
|
|
35703
|
+
method: "POST",
|
|
35704
|
+
headers: {
|
|
35705
|
+
"Content-Type": "application/json",
|
|
35706
|
+
...token ? { Authorization: `Bearer ${token}` } : {}
|
|
35707
|
+
},
|
|
35708
|
+
body: JSON.stringify({ message })
|
|
35709
|
+
});
|
|
35710
|
+
} catch (err) {
|
|
35711
|
+
if (this.config.debug) {
|
|
35712
|
+
log.warn("Notification relay failed", {
|
|
35713
|
+
error: err instanceof Error ? err.message : String(err)
|
|
35714
|
+
});
|
|
35715
|
+
}
|
|
35716
|
+
}
|
|
35717
|
+
}
|
|
35454
35718
|
checkInitialized() {
|
|
35455
35719
|
if (!this.isInitialized) {
|
|
35456
35720
|
return failure(
|
|
@@ -35526,7 +35790,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35526
35790
|
return failure(initCheck.error);
|
|
35527
35791
|
}
|
|
35528
35792
|
const result = await this.loanCreator.createLoan(request);
|
|
35529
|
-
if (result.success &&
|
|
35793
|
+
if (result.success && result.value.positionId) {
|
|
35530
35794
|
try {
|
|
35531
35795
|
const message = formatLoanCreationMessage(
|
|
35532
35796
|
result.value.positionId,
|
|
@@ -35538,12 +35802,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35538
35802
|
"\u{1F4F1} Attempting to send loan creation Telegram message..."
|
|
35539
35803
|
);
|
|
35540
35804
|
}
|
|
35541
|
-
await
|
|
35542
|
-
this.config.telegram.chatId,
|
|
35543
|
-
this.config.telegram.chatToken,
|
|
35544
|
-
message,
|
|
35545
|
-
this.config.telegram.threadId
|
|
35546
|
-
);
|
|
35805
|
+
await this._relayNotification(message);
|
|
35547
35806
|
if (this.config.debug) {
|
|
35548
35807
|
console.log("\u2705 Loan creation Telegram message sent successfully");
|
|
35549
35808
|
}
|
|
@@ -36717,7 +36976,7 @@ Error data: ${errorData || "none"}`
|
|
|
36717
36976
|
amountMintedUCD: Number(amountMinted) / 10 ** 18
|
|
36718
36977
|
};
|
|
36719
36978
|
try {
|
|
36720
|
-
if (
|
|
36979
|
+
if (result.transactionHash) {
|
|
36721
36980
|
const mintAmount = result.amountMintedUCD || request.amount;
|
|
36722
36981
|
const loanId = result.positionId || request.positionId;
|
|
36723
36982
|
const message = formatMintMessage(
|
|
@@ -36725,12 +36984,7 @@ Error data: ${errorData || "none"}`
|
|
|
36725
36984
|
loanId,
|
|
36726
36985
|
result.transactionHash
|
|
36727
36986
|
);
|
|
36728
|
-
await
|
|
36729
|
-
this.config.telegram.chatId,
|
|
36730
|
-
this.config.telegram.chatToken,
|
|
36731
|
-
message,
|
|
36732
|
-
this.config.telegram.threadId
|
|
36733
|
-
);
|
|
36987
|
+
await this._relayNotification(message);
|
|
36734
36988
|
}
|
|
36735
36989
|
} catch (err) {
|
|
36736
36990
|
}
|
|
@@ -36992,39 +37246,32 @@ Error data: ${errorData || "none"}`
|
|
|
36992
37246
|
}
|
|
36993
37247
|
if (!shouldLiquidate) {
|
|
36994
37248
|
try {
|
|
36995
|
-
if (this.config.
|
|
36996
|
-
|
|
36997
|
-
|
|
36998
|
-
|
|
36999
|
-
|
|
37000
|
-
|
|
37001
|
-
|
|
37002
|
-
|
|
37003
|
-
|
|
37004
|
-
|
|
37005
|
-
|
|
37006
|
-
|
|
37007
|
-
|
|
37008
|
-
|
|
37009
|
-
|
|
37010
|
-
|
|
37011
|
-
|
|
37012
|
-
|
|
37013
|
-
|
|
37014
|
-
|
|
37015
|
-
|
|
37016
|
-
|
|
37017
|
-
|
|
37018
|
-
|
|
37019
|
-
|
|
37020
|
-
message,
|
|
37021
|
-
this.config.telegram.threadId
|
|
37249
|
+
if (this.config.debug) {
|
|
37250
|
+
log.info(`\u{1F4F1} Sending liquidation skipped Telegram message...`);
|
|
37251
|
+
}
|
|
37252
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37253
|
+
const btcPrice2 = litActionResult.btcPrice || "0";
|
|
37254
|
+
const btcVaultBalance = litActionResult.btcAmountSats || positionDetails.btcVaultBalance || "0";
|
|
37255
|
+
const usdPricePerBTC = Number(btcPrice2) / 1e8;
|
|
37256
|
+
const btcAmount = Number(btcVaultBalance) / 1e8;
|
|
37257
|
+
const btcValueUSD = btcAmount * usdPricePerBTC;
|
|
37258
|
+
const debtUSD = Number(debt) / 1e18;
|
|
37259
|
+
const ratio = debtUSD > 0 ? (btcValueUSD / debtUSD * 100).toFixed(2) : "0.00";
|
|
37260
|
+
const message = formatLiquidationSkippedMessage(
|
|
37261
|
+
request.positionId,
|
|
37262
|
+
ratio,
|
|
37263
|
+
`${liquidationThreshold / 100}`,
|
|
37264
|
+
// Convert to percentage
|
|
37265
|
+
positionDetails.vaultAddress || "unknown",
|
|
37266
|
+
btcVaultBalance,
|
|
37267
|
+
debt,
|
|
37268
|
+
btcPrice2
|
|
37269
|
+
);
|
|
37270
|
+
await this._relayNotification(message);
|
|
37271
|
+
if (this.config.debug) {
|
|
37272
|
+
log.info(
|
|
37273
|
+
`\u2705 Liquidation skipped Telegram message sent successfully`
|
|
37022
37274
|
);
|
|
37023
|
-
if (this.config.debug) {
|
|
37024
|
-
log.info(
|
|
37025
|
-
`\u2705 Liquidation skipped Telegram message sent successfully`
|
|
37026
|
-
);
|
|
37027
|
-
}
|
|
37028
37275
|
}
|
|
37029
37276
|
} catch (telegramError) {
|
|
37030
37277
|
if (this.config.debug) {
|
|
@@ -37079,32 +37326,25 @@ Error data: ${errorData || "none"}`
|
|
|
37079
37326
|
});
|
|
37080
37327
|
}
|
|
37081
37328
|
try {
|
|
37082
|
-
if (this.config.
|
|
37083
|
-
|
|
37084
|
-
|
|
37085
|
-
|
|
37086
|
-
|
|
37087
|
-
|
|
37088
|
-
|
|
37089
|
-
|
|
37090
|
-
|
|
37091
|
-
|
|
37092
|
-
|
|
37093
|
-
|
|
37094
|
-
|
|
37095
|
-
|
|
37096
|
-
|
|
37097
|
-
|
|
37098
|
-
|
|
37099
|
-
|
|
37100
|
-
message,
|
|
37101
|
-
this.config.telegram.threadId
|
|
37329
|
+
if (this.config.debug) {
|
|
37330
|
+
log.info(`\u{1F4F1} Sending LIT action rejection Telegram message...`);
|
|
37331
|
+
}
|
|
37332
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37333
|
+
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37334
|
+
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37335
|
+
const message = formatLiquidationFailureMessage(
|
|
37336
|
+
request.positionId,
|
|
37337
|
+
`LIT Action rejected liquidation: ${litActionResult.reason || litActionResult.error || "Unknown error"}`,
|
|
37338
|
+
positionDetails.vaultAddress || "unknown",
|
|
37339
|
+
btcVaultBalance,
|
|
37340
|
+
debt,
|
|
37341
|
+
btcPrice2
|
|
37342
|
+
);
|
|
37343
|
+
await this._relayNotification(message);
|
|
37344
|
+
if (this.config.debug) {
|
|
37345
|
+
log.info(
|
|
37346
|
+
`\u2705 LIT action rejection Telegram message sent successfully`
|
|
37102
37347
|
);
|
|
37103
|
-
if (this.config.debug) {
|
|
37104
|
-
log.info(
|
|
37105
|
-
`\u2705 LIT action rejection Telegram message sent successfully`
|
|
37106
|
-
);
|
|
37107
|
-
}
|
|
37108
37348
|
}
|
|
37109
37349
|
} catch (telegramError) {
|
|
37110
37350
|
if (this.config.debug) {
|
|
@@ -37126,32 +37366,25 @@ Error data: ${errorData || "none"}`
|
|
|
37126
37366
|
);
|
|
37127
37367
|
}
|
|
37128
37368
|
try {
|
|
37129
|
-
if (this.config.
|
|
37130
|
-
|
|
37131
|
-
|
|
37132
|
-
|
|
37133
|
-
|
|
37134
|
-
|
|
37135
|
-
|
|
37136
|
-
|
|
37137
|
-
|
|
37138
|
-
|
|
37139
|
-
|
|
37140
|
-
|
|
37141
|
-
|
|
37142
|
-
|
|
37143
|
-
|
|
37144
|
-
|
|
37145
|
-
|
|
37146
|
-
|
|
37147
|
-
message,
|
|
37148
|
-
this.config.telegram.threadId
|
|
37369
|
+
if (this.config.debug) {
|
|
37370
|
+
log.info(`\u{1F4F1} Sending forced liquidation Telegram message...`);
|
|
37371
|
+
}
|
|
37372
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37373
|
+
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37374
|
+
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37375
|
+
const message = formatLiquidationFailureMessage(
|
|
37376
|
+
request.positionId,
|
|
37377
|
+
`FORCED LIQUIDATION: LIT Action rejected but forceContractCall=true - proceeding with liquidation`,
|
|
37378
|
+
positionDetails.vaultAddress || "unknown",
|
|
37379
|
+
btcVaultBalance,
|
|
37380
|
+
debt,
|
|
37381
|
+
btcPrice2
|
|
37382
|
+
);
|
|
37383
|
+
await this._relayNotification(message);
|
|
37384
|
+
if (this.config.debug) {
|
|
37385
|
+
log.info(
|
|
37386
|
+
`\u2705 Forced liquidation Telegram message sent successfully`
|
|
37149
37387
|
);
|
|
37150
|
-
if (this.config.debug) {
|
|
37151
|
-
log.info(
|
|
37152
|
-
`\u2705 Forced liquidation Telegram message sent successfully`
|
|
37153
|
-
);
|
|
37154
|
-
}
|
|
37155
37388
|
}
|
|
37156
37389
|
} catch (telegramError) {
|
|
37157
37390
|
if (this.config.debug) {
|
|
@@ -37184,34 +37417,27 @@ Error data: ${errorData || "none"}`
|
|
|
37184
37417
|
);
|
|
37185
37418
|
}
|
|
37186
37419
|
try {
|
|
37187
|
-
if (this.config.
|
|
37188
|
-
|
|
37189
|
-
|
|
37190
|
-
`\u{1F4F1} Sending forced liquidation without signature Telegram message...`
|
|
37191
|
-
);
|
|
37192
|
-
}
|
|
37193
|
-
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37194
|
-
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37195
|
-
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37196
|
-
const message = formatLiquidationFailureMessage(
|
|
37197
|
-
request.positionId,
|
|
37198
|
-
"FORCED LIQUIDATION: LIT Action did not provide signature but forceContractCall=true - proceeding without signature",
|
|
37199
|
-
positionDetails.vaultAddress || "unknown",
|
|
37200
|
-
btcVaultBalance,
|
|
37201
|
-
debt,
|
|
37202
|
-
btcPrice2
|
|
37420
|
+
if (this.config.debug) {
|
|
37421
|
+
log.info(
|
|
37422
|
+
`\u{1F4F1} Sending forced liquidation without signature Telegram message...`
|
|
37203
37423
|
);
|
|
37204
|
-
|
|
37205
|
-
|
|
37206
|
-
|
|
37207
|
-
|
|
37208
|
-
|
|
37424
|
+
}
|
|
37425
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37426
|
+
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37427
|
+
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37428
|
+
const message = formatLiquidationFailureMessage(
|
|
37429
|
+
request.positionId,
|
|
37430
|
+
"FORCED LIQUIDATION: LIT Action did not provide signature but forceContractCall=true - proceeding without signature",
|
|
37431
|
+
positionDetails.vaultAddress || "unknown",
|
|
37432
|
+
btcVaultBalance,
|
|
37433
|
+
debt,
|
|
37434
|
+
btcPrice2
|
|
37435
|
+
);
|
|
37436
|
+
await this._relayNotification(message);
|
|
37437
|
+
if (this.config.debug) {
|
|
37438
|
+
log.info(
|
|
37439
|
+
`\u2705 Forced liquidation without signature Telegram message sent successfully`
|
|
37209
37440
|
);
|
|
37210
|
-
if (this.config.debug) {
|
|
37211
|
-
log.info(
|
|
37212
|
-
`\u2705 Forced liquidation without signature Telegram message sent successfully`
|
|
37213
|
-
);
|
|
37214
|
-
}
|
|
37215
37441
|
}
|
|
37216
37442
|
} catch (telegramError) {
|
|
37217
37443
|
if (this.config.debug) {
|
|
@@ -37225,32 +37451,25 @@ Error data: ${errorData || "none"}`
|
|
|
37225
37451
|
}
|
|
37226
37452
|
} else {
|
|
37227
37453
|
try {
|
|
37228
|
-
if (this.config.
|
|
37229
|
-
|
|
37230
|
-
|
|
37231
|
-
|
|
37232
|
-
|
|
37233
|
-
|
|
37234
|
-
|
|
37235
|
-
|
|
37236
|
-
|
|
37237
|
-
|
|
37238
|
-
|
|
37239
|
-
|
|
37240
|
-
|
|
37241
|
-
|
|
37242
|
-
|
|
37243
|
-
|
|
37244
|
-
|
|
37245
|
-
|
|
37246
|
-
message,
|
|
37247
|
-
this.config.telegram.threadId
|
|
37454
|
+
if (this.config.debug) {
|
|
37455
|
+
log.info(`\u{1F4F1} Sending missing signature Telegram message...`);
|
|
37456
|
+
}
|
|
37457
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37458
|
+
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37459
|
+
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37460
|
+
const message = formatLiquidationFailureMessage(
|
|
37461
|
+
request.positionId,
|
|
37462
|
+
"LIT Action did not provide required signature for liquidation",
|
|
37463
|
+
positionDetails.vaultAddress || "unknown",
|
|
37464
|
+
btcVaultBalance,
|
|
37465
|
+
debt,
|
|
37466
|
+
btcPrice2
|
|
37467
|
+
);
|
|
37468
|
+
await this._relayNotification(message);
|
|
37469
|
+
if (this.config.debug) {
|
|
37470
|
+
log.info(
|
|
37471
|
+
`\u2705 Missing signature Telegram message sent successfully`
|
|
37248
37472
|
);
|
|
37249
|
-
if (this.config.debug) {
|
|
37250
|
-
log.info(
|
|
37251
|
-
`\u2705 Missing signature Telegram message sent successfully`
|
|
37252
|
-
);
|
|
37253
|
-
}
|
|
37254
37473
|
}
|
|
37255
37474
|
} catch (telegramError) {
|
|
37256
37475
|
if (this.config.debug) {
|
|
@@ -37489,34 +37708,27 @@ Error data: ${errorData || "none"}`
|
|
|
37489
37708
|
});
|
|
37490
37709
|
}
|
|
37491
37710
|
try {
|
|
37492
|
-
if (this.config.
|
|
37493
|
-
|
|
37494
|
-
|
|
37495
|
-
|
|
37496
|
-
|
|
37497
|
-
|
|
37498
|
-
|
|
37499
|
-
|
|
37500
|
-
|
|
37501
|
-
|
|
37502
|
-
|
|
37503
|
-
|
|
37504
|
-
|
|
37505
|
-
|
|
37506
|
-
|
|
37507
|
-
|
|
37508
|
-
|
|
37509
|
-
|
|
37510
|
-
|
|
37511
|
-
|
|
37512
|
-
message,
|
|
37513
|
-
this.config.telegram.threadId
|
|
37711
|
+
if (this.config.debug) {
|
|
37712
|
+
log.info(`\u{1F4F1} Sending liquidation success Telegram message...`);
|
|
37713
|
+
}
|
|
37714
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37715
|
+
const btcPrice2 = litActionResult.btcPrice || "0";
|
|
37716
|
+
const ratio = debt !== "0" ? (Number(positionDetails.btcVaultBalance || "0") * Number(btcPrice2) / Number(debt) * 100 / 1e8).toFixed(2) : "0.00";
|
|
37717
|
+
const message = formatLiquidationSuccessMessage(
|
|
37718
|
+
request.positionId,
|
|
37719
|
+
ratio,
|
|
37720
|
+
`${liquidationThreshold / 100}`,
|
|
37721
|
+
// Convert to percentage
|
|
37722
|
+
positionDetails.btcVault || "unknown",
|
|
37723
|
+
positionDetails.btcVaultBalance || "0",
|
|
37724
|
+
debt,
|
|
37725
|
+
btcPrice2
|
|
37726
|
+
);
|
|
37727
|
+
await this._relayNotification(message);
|
|
37728
|
+
if (this.config.debug) {
|
|
37729
|
+
log.info(
|
|
37730
|
+
`\u2705 Liquidation success Telegram message sent successfully`
|
|
37514
37731
|
);
|
|
37515
|
-
if (this.config.debug) {
|
|
37516
|
-
log.info(
|
|
37517
|
-
`\u2705 Liquidation success Telegram message sent successfully`
|
|
37518
|
-
);
|
|
37519
|
-
}
|
|
37520
37732
|
}
|
|
37521
37733
|
} catch (telegramError) {
|
|
37522
37734
|
if (this.config.debug) {
|
|
@@ -37548,31 +37760,24 @@ Error data: ${errorData || "none"}`
|
|
|
37548
37760
|
transaction: contractError.transaction
|
|
37549
37761
|
});
|
|
37550
37762
|
try {
|
|
37551
|
-
if (this.config.
|
|
37552
|
-
|
|
37553
|
-
|
|
37554
|
-
|
|
37555
|
-
|
|
37556
|
-
|
|
37557
|
-
|
|
37558
|
-
|
|
37559
|
-
|
|
37560
|
-
|
|
37561
|
-
|
|
37562
|
-
|
|
37563
|
-
|
|
37564
|
-
|
|
37565
|
-
|
|
37566
|
-
|
|
37567
|
-
|
|
37568
|
-
message,
|
|
37569
|
-
this.config.telegram.threadId
|
|
37763
|
+
if (this.config.debug) {
|
|
37764
|
+
log.info(`\u{1F4F1} Sending liquidation failure Telegram message...`);
|
|
37765
|
+
}
|
|
37766
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37767
|
+
const btcPrice2 = litActionResult.btcPrice || "0";
|
|
37768
|
+
const message = formatLiquidationFailureMessage(
|
|
37769
|
+
request.positionId,
|
|
37770
|
+
contractError.message || "Unknown contract error",
|
|
37771
|
+
positionDetails.btcVault || "unknown",
|
|
37772
|
+
positionDetails.btcVaultBalance || "0",
|
|
37773
|
+
debt,
|
|
37774
|
+
btcPrice2
|
|
37775
|
+
);
|
|
37776
|
+
await this._relayNotification(message);
|
|
37777
|
+
if (this.config.debug) {
|
|
37778
|
+
log.info(
|
|
37779
|
+
`\u2705 Liquidation failure Telegram message sent successfully`
|
|
37570
37780
|
);
|
|
37571
|
-
if (this.config.debug) {
|
|
37572
|
-
log.info(
|
|
37573
|
-
`\u2705 Liquidation failure Telegram message sent successfully`
|
|
37574
|
-
);
|
|
37575
|
-
}
|
|
37576
37781
|
}
|
|
37577
37782
|
} catch (telegramError) {
|
|
37578
37783
|
if (this.config.debug) {
|
|
@@ -37722,26 +37927,19 @@ Error data: ${errorData || "none"}`
|
|
|
37722
37927
|
)} (${potentialNewExpiry}), max allowed: ${formatDate(
|
|
37723
37928
|
maxAllowedTimestamp
|
|
37724
37929
|
)} (${maxAllowedTimestamp})`;
|
|
37725
|
-
|
|
37726
|
-
|
|
37727
|
-
|
|
37728
|
-
|
|
37729
|
-
|
|
37730
|
-
|
|
37731
|
-
|
|
37732
|
-
|
|
37733
|
-
|
|
37734
|
-
|
|
37930
|
+
try {
|
|
37931
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(
|
|
37932
|
+
_positionId,
|
|
37933
|
+
`Loan could not be renewed: ${errorMessage}`
|
|
37934
|
+
));
|
|
37935
|
+
} catch (e) {
|
|
37936
|
+
if (this.config.debug) {
|
|
37937
|
+
log.warn(
|
|
37938
|
+
"Failed to send Telegram notification for renewal rule violation",
|
|
37939
|
+
{
|
|
37940
|
+
error: e instanceof Error ? e.message : String(e)
|
|
37941
|
+
}
|
|
37735
37942
|
);
|
|
37736
|
-
} catch (e) {
|
|
37737
|
-
if (this.config.debug) {
|
|
37738
|
-
log.warn(
|
|
37739
|
-
"Failed to send Telegram notification for renewal rule violation",
|
|
37740
|
-
{
|
|
37741
|
-
error: e instanceof Error ? e.message : String(e)
|
|
37742
|
-
}
|
|
37743
|
-
);
|
|
37744
|
-
}
|
|
37745
37943
|
}
|
|
37746
37944
|
}
|
|
37747
37945
|
throw new Error(errorMessage);
|
|
@@ -37793,19 +37991,12 @@ Error data: ${errorData || "none"}`
|
|
|
37793
37991
|
error: errorMessage
|
|
37794
37992
|
});
|
|
37795
37993
|
}
|
|
37796
|
-
|
|
37797
|
-
|
|
37798
|
-
|
|
37799
|
-
|
|
37800
|
-
|
|
37801
|
-
|
|
37802
|
-
_positionId,
|
|
37803
|
-
`LIT Action failed: ${errorMessage}`
|
|
37804
|
-
),
|
|
37805
|
-
this.config.telegram.threadId
|
|
37806
|
-
);
|
|
37807
|
-
} catch (e) {
|
|
37808
|
-
}
|
|
37994
|
+
try {
|
|
37995
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(
|
|
37996
|
+
_positionId,
|
|
37997
|
+
`LIT Action failed: ${errorMessage}`
|
|
37998
|
+
));
|
|
37999
|
+
} catch (e) {
|
|
37809
38000
|
}
|
|
37810
38001
|
throw litError;
|
|
37811
38002
|
}
|
|
@@ -37815,31 +38006,17 @@ Error data: ${errorData || "none"}`
|
|
|
37815
38006
|
if (!litActionResult.approved) {
|
|
37816
38007
|
const reason = litActionResult.reason ?? litActionResult.error ?? "Extension not approved";
|
|
37817
38008
|
const errorMessage = `Extension not approved: ${reason}`;
|
|
37818
|
-
|
|
37819
|
-
|
|
37820
|
-
|
|
37821
|
-
this.config.telegram.chatId,
|
|
37822
|
-
this.config.telegram.chatToken,
|
|
37823
|
-
formatLoanRenewalFailureMessage(_positionId, errorMessage),
|
|
37824
|
-
this.config.telegram.threadId
|
|
37825
|
-
);
|
|
37826
|
-
} catch (e) {
|
|
37827
|
-
}
|
|
38009
|
+
try {
|
|
38010
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(_positionId, errorMessage));
|
|
38011
|
+
} catch (e) {
|
|
37828
38012
|
}
|
|
37829
38013
|
throw new Error(errorMessage);
|
|
37830
38014
|
}
|
|
37831
38015
|
if (!litActionResult.signature || litActionResult.btcPrice === void 0 || litActionResult.btcPrice === null || litActionResult.availableBTCBalance === void 0 || litActionResult.availableBTCBalance === null || (litActionResult.quantumTimestamp === void 0 || litActionResult.quantumTimestamp === null) || litActionResult.proRataRenewalFee === void 0 || litActionResult.proRataRenewalFee === null) {
|
|
37832
38016
|
const errorMessage = "LIT Action result missing required fields: signature, btcPrice, availableBTCBalance, quantumTimestamp, proRataRenewalFee";
|
|
37833
|
-
|
|
37834
|
-
|
|
37835
|
-
|
|
37836
|
-
this.config.telegram.chatId,
|
|
37837
|
-
this.config.telegram.chatToken,
|
|
37838
|
-
formatLoanRenewalFailureMessage(_positionId, errorMessage),
|
|
37839
|
-
this.config.telegram.threadId
|
|
37840
|
-
);
|
|
37841
|
-
} catch (e) {
|
|
37842
|
-
}
|
|
38017
|
+
try {
|
|
38018
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(_positionId, errorMessage));
|
|
38019
|
+
} catch (e) {
|
|
37843
38020
|
}
|
|
37844
38021
|
throw new Error(errorMessage);
|
|
37845
38022
|
}
|
|
@@ -37926,66 +38103,38 @@ Error data: ${errorData || "none"}`
|
|
|
37926
38103
|
{ hash: txWithProvider.hash, error: errorMessage }
|
|
37927
38104
|
);
|
|
37928
38105
|
}
|
|
37929
|
-
|
|
37930
|
-
|
|
37931
|
-
|
|
37932
|
-
|
|
37933
|
-
|
|
37934
|
-
|
|
37935
|
-
_positionId,
|
|
37936
|
-
`Transaction confirmation failed: ${errorMessage}`
|
|
37937
|
-
),
|
|
37938
|
-
this.config.telegram.threadId
|
|
37939
|
-
);
|
|
37940
|
-
} catch (e) {
|
|
37941
|
-
}
|
|
38106
|
+
try {
|
|
38107
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(
|
|
38108
|
+
_positionId,
|
|
38109
|
+
`Transaction confirmation failed: ${errorMessage}`
|
|
38110
|
+
));
|
|
38111
|
+
} catch (e) {
|
|
37942
38112
|
}
|
|
37943
38113
|
throw waitError;
|
|
37944
38114
|
}
|
|
37945
38115
|
if (!receipt) {
|
|
37946
38116
|
const error = "Transaction receipt is null - transaction may have failed";
|
|
37947
|
-
|
|
37948
|
-
|
|
37949
|
-
|
|
37950
|
-
this.config.telegram.chatId,
|
|
37951
|
-
this.config.telegram.chatToken,
|
|
37952
|
-
formatLoanRenewalFailureMessage(_positionId, error),
|
|
37953
|
-
this.config.telegram.threadId
|
|
37954
|
-
);
|
|
37955
|
-
} catch (e) {
|
|
37956
|
-
}
|
|
38117
|
+
try {
|
|
38118
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(_positionId, error));
|
|
38119
|
+
} catch (e) {
|
|
37957
38120
|
}
|
|
37958
38121
|
throw new Error(error);
|
|
37959
38122
|
}
|
|
37960
38123
|
if (receipt.status === 0) {
|
|
37961
38124
|
const error = `Transaction reverted (tx: ${receipt.transactionHash})`;
|
|
37962
|
-
|
|
37963
|
-
|
|
37964
|
-
|
|
37965
|
-
this.config.telegram.chatId,
|
|
37966
|
-
this.config.telegram.chatToken,
|
|
37967
|
-
formatLoanRenewalFailureMessage(_positionId, error),
|
|
37968
|
-
this.config.telegram.threadId
|
|
37969
|
-
);
|
|
37970
|
-
} catch (e) {
|
|
37971
|
-
}
|
|
38125
|
+
try {
|
|
38126
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(_positionId, error));
|
|
38127
|
+
} catch (e) {
|
|
37972
38128
|
}
|
|
37973
38129
|
throw new Error(error);
|
|
37974
38130
|
}
|
|
37975
|
-
|
|
37976
|
-
|
|
37977
|
-
|
|
37978
|
-
|
|
37979
|
-
|
|
37980
|
-
|
|
37981
|
-
|
|
37982
|
-
);
|
|
37983
|
-
} catch (e) {
|
|
37984
|
-
if (this.config.debug) {
|
|
37985
|
-
log.warn("Failed to send Telegram notification for extension", {
|
|
37986
|
-
error: e instanceof Error ? e.message : String(e)
|
|
37987
|
-
});
|
|
37988
|
-
}
|
|
38131
|
+
try {
|
|
38132
|
+
await this._relayNotification(formatLoanRenewalMessage(_positionId, receipt.transactionHash));
|
|
38133
|
+
} catch (e) {
|
|
38134
|
+
if (this.config.debug) {
|
|
38135
|
+
log.warn("Failed to send Telegram notification for extension", {
|
|
38136
|
+
error: e instanceof Error ? e.message : String(e)
|
|
38137
|
+
});
|
|
37989
38138
|
}
|
|
37990
38139
|
}
|
|
37991
38140
|
return receipt;
|
|
@@ -38099,16 +38248,9 @@ Error data: ${errorData || "none"}`
|
|
|
38099
38248
|
const initCheck = this.checkInitialized();
|
|
38100
38249
|
if (!initCheck.success) {
|
|
38101
38250
|
const error = `SDK not initialized: ${initCheck.error.message}`;
|
|
38102
|
-
|
|
38103
|
-
|
|
38104
|
-
|
|
38105
|
-
this.config.telegram.chatId,
|
|
38106
|
-
this.config.telegram.chatToken,
|
|
38107
|
-
formatBalanceConfirmationFailureMessage(positionId),
|
|
38108
|
-
this.config.telegram.threadId
|
|
38109
|
-
);
|
|
38110
|
-
} catch (e) {
|
|
38111
|
-
}
|
|
38251
|
+
try {
|
|
38252
|
+
await this._relayNotification(formatBalanceConfirmationFailureMessage(positionId));
|
|
38253
|
+
} catch (e) {
|
|
38112
38254
|
}
|
|
38113
38255
|
return {
|
|
38114
38256
|
success: false,
|
|
@@ -38248,21 +38390,14 @@ Error data: ${errorData || "none"}`
|
|
|
38248
38390
|
gasUsed: receipt.gasUsed.toString()
|
|
38249
38391
|
});
|
|
38250
38392
|
}
|
|
38251
|
-
|
|
38252
|
-
|
|
38253
|
-
|
|
38254
|
-
|
|
38255
|
-
|
|
38256
|
-
|
|
38257
|
-
message
|
|
38258
|
-
|
|
38259
|
-
);
|
|
38260
|
-
} catch (telegramError) {
|
|
38261
|
-
if (this.config.debug) {
|
|
38262
|
-
log.warn("\u26A0\uFE0F Failed to send Telegram notification", {
|
|
38263
|
-
error: telegramError instanceof Error ? telegramError.message : String(telegramError)
|
|
38264
|
-
});
|
|
38265
|
-
}
|
|
38393
|
+
try {
|
|
38394
|
+
const message = formatBalanceConfirmationMessage(positionId);
|
|
38395
|
+
await this._relayNotification(message);
|
|
38396
|
+
} catch (telegramError) {
|
|
38397
|
+
if (this.config.debug) {
|
|
38398
|
+
log.warn("\u26A0\uFE0F Failed to send Telegram notification", {
|
|
38399
|
+
error: telegramError instanceof Error ? telegramError.message : String(telegramError)
|
|
38400
|
+
});
|
|
38266
38401
|
}
|
|
38267
38402
|
}
|
|
38268
38403
|
return {
|
|
@@ -38285,17 +38420,10 @@ Error data: ${errorData || "none"}`
|
|
|
38285
38420
|
positionId
|
|
38286
38421
|
});
|
|
38287
38422
|
}
|
|
38288
|
-
|
|
38289
|
-
|
|
38290
|
-
|
|
38291
|
-
|
|
38292
|
-
this.config.telegram.chatId,
|
|
38293
|
-
this.config.telegram.chatToken,
|
|
38294
|
-
message,
|
|
38295
|
-
this.config.telegram.threadId
|
|
38296
|
-
);
|
|
38297
|
-
} catch (telegramError) {
|
|
38298
|
-
}
|
|
38423
|
+
try {
|
|
38424
|
+
const message = formatBalanceConfirmationFailureMessage(positionId);
|
|
38425
|
+
await this._relayNotification(message);
|
|
38426
|
+
} catch (telegramError) {
|
|
38299
38427
|
}
|
|
38300
38428
|
return {
|
|
38301
38429
|
success: false,
|
|
@@ -38844,17 +38972,12 @@ Error data: ${errorData || "none"}`
|
|
|
38844
38972
|
}
|
|
38845
38973
|
if (receipt.status === 0) {
|
|
38846
38974
|
try {
|
|
38847
|
-
if (
|
|
38975
|
+
if (tx.hash) {
|
|
38848
38976
|
const message = formatPartialPaymentFailureMessage(
|
|
38849
38977
|
request.paymentAmount,
|
|
38850
38978
|
request.positionId
|
|
38851
38979
|
);
|
|
38852
|
-
await
|
|
38853
|
-
this.config.telegram.chatId,
|
|
38854
|
-
this.config.telegram.chatToken,
|
|
38855
|
-
message,
|
|
38856
|
-
this.config.telegram.threadId
|
|
38857
|
-
);
|
|
38980
|
+
await this._relayNotification(message);
|
|
38858
38981
|
}
|
|
38859
38982
|
} catch (telegramError) {
|
|
38860
38983
|
if (this.config.debug) {
|
|
@@ -38876,18 +38999,13 @@ Error data: ${errorData || "none"}`
|
|
|
38876
38999
|
log.info(`\u2705 Transaction confirmed in block ${receipt.blockNumber}`);
|
|
38877
39000
|
}
|
|
38878
39001
|
try {
|
|
38879
|
-
if (
|
|
39002
|
+
if (tx.hash) {
|
|
38880
39003
|
const message = formatPartialPaymentMessage(
|
|
38881
39004
|
request.paymentAmount,
|
|
38882
39005
|
request.positionId,
|
|
38883
39006
|
tx.hash
|
|
38884
39007
|
);
|
|
38885
|
-
await
|
|
38886
|
-
this.config.telegram.chatId,
|
|
38887
|
-
this.config.telegram.chatToken,
|
|
38888
|
-
message,
|
|
38889
|
-
this.config.telegram.threadId
|
|
38890
|
-
);
|
|
39008
|
+
await this._relayNotification(message);
|
|
38891
39009
|
}
|
|
38892
39010
|
} catch (telegramError) {
|
|
38893
39011
|
if (this.config.debug) {
|
|
@@ -38941,19 +39059,12 @@ Error data: ${errorData || "none"}`
|
|
|
38941
39059
|
});
|
|
38942
39060
|
}
|
|
38943
39061
|
try {
|
|
38944
|
-
|
|
38945
|
-
|
|
38946
|
-
|
|
38947
|
-
|
|
38948
|
-
|
|
38949
|
-
|
|
38950
|
-
await sendTelegramMessage(
|
|
38951
|
-
this.config.telegram.chatId,
|
|
38952
|
-
this.config.telegram.chatToken,
|
|
38953
|
-
message,
|
|
38954
|
-
this.config.telegram.threadId
|
|
38955
|
-
);
|
|
38956
|
-
}
|
|
39062
|
+
const message = formatPartialPaymentFailureMessage(
|
|
39063
|
+
request.paymentAmount,
|
|
39064
|
+
request.positionId,
|
|
39065
|
+
transactionHash
|
|
39066
|
+
);
|
|
39067
|
+
await this._relayNotification(message);
|
|
38957
39068
|
} catch (telegramError) {
|
|
38958
39069
|
if (this.config.debug) {
|
|
38959
39070
|
log.warn("\u26A0\uFE0F Failed to send Telegram failure notification", {
|
|
@@ -39269,22 +39380,15 @@ Error data: ${errorData || "none"}`
|
|
|
39269
39380
|
});
|
|
39270
39381
|
}
|
|
39271
39382
|
try {
|
|
39272
|
-
|
|
39273
|
-
|
|
39274
|
-
|
|
39275
|
-
|
|
39276
|
-
|
|
39277
|
-
|
|
39278
|
-
|
|
39279
|
-
|
|
39280
|
-
|
|
39281
|
-
await sendTelegramMessage(
|
|
39282
|
-
this.config.telegram.chatId,
|
|
39283
|
-
this.config.telegram.chatToken,
|
|
39284
|
-
message,
|
|
39285
|
-
this.config.telegram.threadId
|
|
39286
|
-
);
|
|
39287
|
-
}
|
|
39383
|
+
const position2 = await this.getPosition(positionId);
|
|
39384
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39385
|
+
const message = formatBTCWithdrawalFailureMessage(
|
|
39386
|
+
btcAmount,
|
|
39387
|
+
position2?.vaultAddress || "unknown",
|
|
39388
|
+
withdrawalAddress,
|
|
39389
|
+
positionId
|
|
39390
|
+
);
|
|
39391
|
+
await this._relayNotification(message);
|
|
39288
39392
|
} catch (telegramError) {
|
|
39289
39393
|
console.error(
|
|
39290
39394
|
"Telegram notification failed:",
|
|
@@ -39316,22 +39420,15 @@ Error data: ${errorData || "none"}`
|
|
|
39316
39420
|
});
|
|
39317
39421
|
}
|
|
39318
39422
|
try {
|
|
39319
|
-
|
|
39320
|
-
|
|
39321
|
-
|
|
39322
|
-
|
|
39323
|
-
|
|
39324
|
-
|
|
39325
|
-
|
|
39326
|
-
|
|
39327
|
-
|
|
39328
|
-
await sendTelegramMessage(
|
|
39329
|
-
this.config.telegram.chatId,
|
|
39330
|
-
this.config.telegram.chatToken,
|
|
39331
|
-
message,
|
|
39332
|
-
this.config.telegram.threadId
|
|
39333
|
-
);
|
|
39334
|
-
}
|
|
39423
|
+
const position = await this.getPosition(positionId);
|
|
39424
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39425
|
+
const message = formatBTCWithdrawalFailureMessage(
|
|
39426
|
+
btcAmount,
|
|
39427
|
+
position?.vaultAddress || "unknown",
|
|
39428
|
+
withdrawalAddress,
|
|
39429
|
+
positionId
|
|
39430
|
+
);
|
|
39431
|
+
await this._relayNotification(message);
|
|
39335
39432
|
} catch (telegramError) {
|
|
39336
39433
|
console.error(
|
|
39337
39434
|
"Telegram notification failed:",
|
|
@@ -39485,22 +39582,15 @@ Error data: ${errorData || "none"}`
|
|
|
39485
39582
|
});
|
|
39486
39583
|
}
|
|
39487
39584
|
try {
|
|
39488
|
-
|
|
39489
|
-
|
|
39490
|
-
|
|
39491
|
-
|
|
39492
|
-
|
|
39493
|
-
|
|
39494
|
-
|
|
39495
|
-
|
|
39496
|
-
|
|
39497
|
-
await sendTelegramMessage(
|
|
39498
|
-
this.config.telegram.chatId,
|
|
39499
|
-
this.config.telegram.chatToken,
|
|
39500
|
-
message,
|
|
39501
|
-
this.config.telegram.threadId
|
|
39502
|
-
);
|
|
39503
|
-
}
|
|
39585
|
+
const position = await this.getPosition(positionId);
|
|
39586
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39587
|
+
const message = formatBTCWithdrawalFailureMessage(
|
|
39588
|
+
btcAmount,
|
|
39589
|
+
position?.vaultAddress || "unknown",
|
|
39590
|
+
withdrawalAddress,
|
|
39591
|
+
positionId
|
|
39592
|
+
);
|
|
39593
|
+
await this._relayNotification(message);
|
|
39504
39594
|
} catch (telegramError) {
|
|
39505
39595
|
console.error(
|
|
39506
39596
|
"Telegram notification failed:",
|
|
@@ -39540,22 +39630,15 @@ Error data: ${errorData || "none"}`
|
|
|
39540
39630
|
});
|
|
39541
39631
|
}
|
|
39542
39632
|
try {
|
|
39543
|
-
|
|
39544
|
-
|
|
39545
|
-
|
|
39546
|
-
|
|
39547
|
-
|
|
39548
|
-
|
|
39549
|
-
|
|
39550
|
-
|
|
39551
|
-
|
|
39552
|
-
await sendTelegramMessage(
|
|
39553
|
-
this.config.telegram.chatId,
|
|
39554
|
-
this.config.telegram.chatToken,
|
|
39555
|
-
message,
|
|
39556
|
-
this.config.telegram.threadId
|
|
39557
|
-
);
|
|
39558
|
-
}
|
|
39633
|
+
const position = await this.getPosition(positionId);
|
|
39634
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39635
|
+
const message = formatBTCWithdrawalSuccessMessage(
|
|
39636
|
+
btcAmount,
|
|
39637
|
+
position?.vaultAddress || "unknown",
|
|
39638
|
+
validationResponse.destinationAddress,
|
|
39639
|
+
positionId
|
|
39640
|
+
);
|
|
39641
|
+
await this._relayNotification(message);
|
|
39559
39642
|
} catch (telegramError) {
|
|
39560
39643
|
console.error(
|
|
39561
39644
|
"Telegram notification failed:",
|
|
@@ -39581,22 +39664,15 @@ Error data: ${errorData || "none"}`
|
|
|
39581
39664
|
});
|
|
39582
39665
|
}
|
|
39583
39666
|
try {
|
|
39584
|
-
|
|
39585
|
-
|
|
39586
|
-
|
|
39587
|
-
|
|
39588
|
-
|
|
39589
|
-
|
|
39590
|
-
|
|
39591
|
-
|
|
39592
|
-
|
|
39593
|
-
await sendTelegramMessage(
|
|
39594
|
-
this.config.telegram.chatId,
|
|
39595
|
-
this.config.telegram.chatToken,
|
|
39596
|
-
message,
|
|
39597
|
-
this.config.telegram.threadId
|
|
39598
|
-
);
|
|
39599
|
-
}
|
|
39667
|
+
const position = await this.getPosition(positionId);
|
|
39668
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39669
|
+
const message = formatBTCWithdrawalFailureMessage(
|
|
39670
|
+
btcAmount,
|
|
39671
|
+
position?.vaultAddress || "unknown",
|
|
39672
|
+
withdrawalAddress,
|
|
39673
|
+
positionId
|
|
39674
|
+
);
|
|
39675
|
+
await this._relayNotification(message);
|
|
39600
39676
|
} catch (telegramError) {
|
|
39601
39677
|
console.error(
|
|
39602
39678
|
"Telegram notification failed:",
|
|
@@ -39660,7 +39736,34 @@ Error data: ${errorData || "none"}`
|
|
|
39660
39736
|
const bitcoinNetwork = this.getBitcoinNetwork();
|
|
39661
39737
|
const mode = chainId === 1337 || chainId === 31337 || bitcoinNetwork === "regtest" ? "dev" : "prod";
|
|
39662
39738
|
const bitcoin = await import("bitcoinjs-lib");
|
|
39663
|
-
const
|
|
39739
|
+
const encodeBitcoinVarInt = (value) => {
|
|
39740
|
+
if (value < 253) {
|
|
39741
|
+
return Buffer.from([value]);
|
|
39742
|
+
}
|
|
39743
|
+
if (value <= 65535) {
|
|
39744
|
+
const buf2 = Buffer.allocUnsafe(3);
|
|
39745
|
+
buf2[0] = 253;
|
|
39746
|
+
buf2.writeUInt16LE(value, 1);
|
|
39747
|
+
return buf2;
|
|
39748
|
+
}
|
|
39749
|
+
if (value <= 4294967295) {
|
|
39750
|
+
const buf2 = Buffer.allocUnsafe(5);
|
|
39751
|
+
buf2[0] = 254;
|
|
39752
|
+
buf2.writeUInt32LE(value, 1);
|
|
39753
|
+
return buf2;
|
|
39754
|
+
}
|
|
39755
|
+
const buf = Buffer.allocUnsafe(9);
|
|
39756
|
+
buf[0] = 255;
|
|
39757
|
+
buf.writeBigUInt64LE(BigInt(value), 1);
|
|
39758
|
+
return buf;
|
|
39759
|
+
};
|
|
39760
|
+
const witnessStackToScriptWitness = (witness) => {
|
|
39761
|
+
const serializedChunks = [encodeBitcoinVarInt(witness.length)];
|
|
39762
|
+
for (const item of witness) {
|
|
39763
|
+
serializedChunks.push(encodeBitcoinVarInt(item.length), item);
|
|
39764
|
+
}
|
|
39765
|
+
return Buffer.concat(serializedChunks);
|
|
39766
|
+
};
|
|
39664
39767
|
const networks2 = bitcoinNetwork === "mainnet" ? bitcoin.networks.bitcoin : bitcoinNetwork === "regtest" ? bitcoin.networks.regtest : bitcoin.networks.testnet;
|
|
39665
39768
|
if (this.config.debug) {
|
|
39666
39769
|
log.info("\u{1F4CB} Network configuration", {
|
|
@@ -41475,7 +41578,7 @@ export {
|
|
|
41475
41578
|
ErrorSeverity,
|
|
41476
41579
|
EventHelpers,
|
|
41477
41580
|
LOCALHOST_CONTRACTS,
|
|
41478
|
-
|
|
41581
|
+
LRUCache,
|
|
41479
41582
|
LoanCreator,
|
|
41480
41583
|
LoanQuery,
|
|
41481
41584
|
LoanStatus,
|