@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.js
CHANGED
|
@@ -12962,68 +12962,66 @@ var init_deployment_addresses = __esm({
|
|
|
12962
12962
|
LOCALHOST_DEPLOYMENT = {
|
|
12963
12963
|
network: "localhost",
|
|
12964
12964
|
chainId: 31337,
|
|
12965
|
-
timestamp: "2026-
|
|
12965
|
+
timestamp: "2026-03-23T15:33:34.068Z",
|
|
12966
12966
|
deployer: "",
|
|
12967
12967
|
contracts: {
|
|
12968
|
-
MessageHashBuilder: "
|
|
12969
|
-
UpgradeValidator: "
|
|
12968
|
+
MessageHashBuilder: "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
|
|
12969
|
+
UpgradeValidator: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
|
|
12970
12970
|
UCDToken: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
|
|
12971
12971
|
UCDController: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
|
|
12972
|
-
PositionManagerCoreModule: "
|
|
12973
|
-
TermManagerModule: "
|
|
12974
|
-
LoanOperationsManagerModule: "
|
|
12972
|
+
PositionManagerCoreModule: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
|
|
12973
|
+
TermManagerModule: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
|
|
12974
|
+
LoanOperationsManagerModule: "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
|
|
12975
12975
|
BTCSpendAuthorizer: "0x59b670e9fA9D0A427751Af201D676719a970857b",
|
|
12976
12976
|
CollateralManagerModule: "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
|
|
12977
12977
|
LiquidationManagerModule: "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
|
|
12978
|
-
CircuitBreakerModule: "
|
|
12978
|
+
CircuitBreakerModule: "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
|
|
12979
12979
|
AdminModule: "0xc5a5C42992dECbae36851359345FE25997F5C42d",
|
|
12980
|
-
PositionManagerViews: "
|
|
12981
|
-
PositionManager: "
|
|
12982
|
-
OperationAuthorizationRegistry: "
|
|
12983
|
-
PKPValidation: "
|
|
12980
|
+
PositionManagerViews: "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
|
|
12981
|
+
PositionManager: "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
|
|
12982
|
+
OperationAuthorizationRegistry: "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0",
|
|
12983
|
+
PKPValidation: "0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc"
|
|
12984
12984
|
},
|
|
12985
12985
|
latestEnv: {
|
|
12986
12986
|
UCD_TOKEN: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
|
|
12987
12987
|
UCD_CONTROLLER: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
|
|
12988
|
-
POSITION_MANAGER: "
|
|
12989
|
-
PKP_VALIDATION_REGISTRY: "
|
|
12990
|
-
PKP_VALIDATION_CID_V1: "
|
|
12991
|
-
|
|
12992
|
-
|
|
12993
|
-
|
|
12994
|
-
UCD_MINT_VALIDATOR_ADDRESS: "0xC6E57a5d65e43910Fe70667C97D193FAF6dDF598",
|
|
12988
|
+
POSITION_MANAGER: "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
|
|
12989
|
+
PKP_VALIDATION_REGISTRY: "0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc",
|
|
12990
|
+
PKP_VALIDATION_CID_V1: "QmfHJKA4RnW7RepsdLmrDwKjVTzPXB2K3qMTco3JNPDexm",
|
|
12991
|
+
PKP_ETH_ADDRESS: "0x9624C46073E1d1F5AB975c67Fc899536d599bb57",
|
|
12992
|
+
OPERATION_AUTHORIZATION_REGISTRY: "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0",
|
|
12993
|
+
UCD_MINT_VALIDATOR_ADDRESS: "0x80f81afb9e6dF27afCD752ad46cD286e705e42be",
|
|
12995
12994
|
UCD_MINT_VALIDATOR_VERSION: 1,
|
|
12996
|
-
BTC_WITHDRAWAL_VALIDATOR_ADDRESS: "
|
|
12995
|
+
BTC_WITHDRAWAL_VALIDATOR_ADDRESS: "0xa751ad81E1CAe61d6cF5Cf64839Fe8D28A1372Df",
|
|
12997
12996
|
BTC_WITHDRAWAL_VALIDATOR_VERSION: 1,
|
|
12998
|
-
UPDATE_BALANCE_VALIDATOR_ADDRESS: "
|
|
12997
|
+
UPDATE_BALANCE_VALIDATOR_ADDRESS: "0x8A40C22B03348bc10df9ae0dc54346b4AE8e909c",
|
|
12999
12998
|
UPDATE_BALANCE_VALIDATOR_VERSION: 1,
|
|
13000
|
-
PROCESS_PAYMENT_VALIDATOR_ADDRESS: "
|
|
12999
|
+
PROCESS_PAYMENT_VALIDATOR_ADDRESS: "0x28f50E07532d3aF677b8E0bcF220422d159b0dd6",
|
|
13001
13000
|
PROCESS_PAYMENT_VALIDATOR_VERSION: 1,
|
|
13002
|
-
EXTEND_POSITION_VALIDATOR_ADDRESS: "
|
|
13001
|
+
EXTEND_POSITION_VALIDATOR_ADDRESS: "0xc7aC43F2F907123465449575e853f5D0229898e1",
|
|
13003
13002
|
EXTEND_POSITION_VALIDATOR_VERSION: 1,
|
|
13004
|
-
POSITION_MANAGER_CORE_MODULE: "
|
|
13005
|
-
LOAN_OPERATIONS_MANAGER_MODULE: "
|
|
13006
|
-
TERM_MANAGER_MODULE: "
|
|
13007
|
-
COMMUNITY_MANAGER_MODULE: ""
|
|
13003
|
+
POSITION_MANAGER_CORE_MODULE: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
|
|
13004
|
+
LOAN_OPERATIONS_MANAGER_MODULE: "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
|
|
13005
|
+
TERM_MANAGER_MODULE: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82"
|
|
13008
13006
|
}
|
|
13009
13007
|
};
|
|
13010
13008
|
LOCALHOST_CONTRACTS = {
|
|
13011
|
-
MessageHashBuilder: "
|
|
13012
|
-
UpgradeValidator: "
|
|
13009
|
+
MessageHashBuilder: "0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E",
|
|
13010
|
+
UpgradeValidator: "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318",
|
|
13013
13011
|
UCDToken: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
|
|
13014
13012
|
UCDController: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
|
|
13015
|
-
PositionManagerCoreModule: "
|
|
13016
|
-
TermManagerModule: "
|
|
13017
|
-
LoanOperationsManagerModule: "
|
|
13013
|
+
PositionManagerCoreModule: "0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e",
|
|
13014
|
+
TermManagerModule: "0x0DCd1Bf9A1b36cE34237eEaFef220932846BCD82",
|
|
13015
|
+
LoanOperationsManagerModule: "0x68B1D87F95878fE05B998F19b66F4baba5De1aed",
|
|
13018
13016
|
BTCSpendAuthorizer: "0x59b670e9fA9D0A427751Af201D676719a970857b",
|
|
13019
13017
|
CollateralManagerModule: "0xa85233C63b9Ee964Add6F2cffe00Fd84eb32338f",
|
|
13020
13018
|
LiquidationManagerModule: "0x7a2088a1bFc9d81c55368AE168C2C02570cB814F",
|
|
13021
|
-
CircuitBreakerModule: "
|
|
13019
|
+
CircuitBreakerModule: "0x0B306BF915C4d645ff596e518fAf3F9669b97016",
|
|
13022
13020
|
AdminModule: "0xc5a5C42992dECbae36851359345FE25997F5C42d",
|
|
13023
|
-
PositionManagerViews: "
|
|
13024
|
-
PositionManager: "
|
|
13025
|
-
OperationAuthorizationRegistry: "
|
|
13026
|
-
PKPValidation: "
|
|
13021
|
+
PositionManagerViews: "0x959922bE3CAee4b8Cd9a407cc3ac1C251C2007B1",
|
|
13022
|
+
PositionManager: "0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB",
|
|
13023
|
+
OperationAuthorizationRegistry: "0x7969c5eD335650692Bc04293B07F5BF2e7A673C0",
|
|
13024
|
+
PKPValidation: "0xcbEAF3BDe82155F56486Fb5a1072cb8baAf547cc"
|
|
13027
13025
|
};
|
|
13028
13026
|
ALL_DEPLOYMENTS = {
|
|
13029
13027
|
sepolia: SEPOLIA_DEPLOYMENT,
|
|
@@ -13349,7 +13347,7 @@ __export(src_exports, {
|
|
|
13349
13347
|
ErrorSeverity: () => ErrorSeverity,
|
|
13350
13348
|
EventHelpers: () => EventHelpers,
|
|
13351
13349
|
LOCALHOST_CONTRACTS: () => LOCALHOST_CONTRACTS,
|
|
13352
|
-
LRUCache: () =>
|
|
13350
|
+
LRUCache: () => LRUCache,
|
|
13353
13351
|
LoanCreator: () => LoanCreator,
|
|
13354
13352
|
LoanQuery: () => LoanQuery,
|
|
13355
13353
|
LoanStatus: () => LoanStatus,
|
|
@@ -29565,8 +29563,6 @@ function validateQuantumTiming(signedTimestamp, _bufferSeconds = 30) {
|
|
|
29565
29563
|
var PKP_NFT_ABI = [
|
|
29566
29564
|
"function getPubkey(uint256 tokenId) external view returns (bytes memory)"
|
|
29567
29565
|
];
|
|
29568
|
-
var CHIPOTLE_RPC_URL = "https://yellowstone-rpc.litprotocol.com";
|
|
29569
|
-
var CHIPOTLE_CHAIN_ID = 175188;
|
|
29570
29566
|
async function generateMintAuthorization(positionId, amount, chainId, signerOrPrecomputed) {
|
|
29571
29567
|
if (typeof signerOrPrecomputed === "object" && "signature" in signerOrPrecomputed && !("signMessage" in signerOrPrecomputed)) {
|
|
29572
29568
|
const { timestamp: timestamp2, signature: signature3 } = signerOrPrecomputed;
|
|
@@ -29666,18 +29662,14 @@ async function generatePaymentAuthorization(positionId, amount, chainId, signer)
|
|
|
29666
29662
|
};
|
|
29667
29663
|
}
|
|
29668
29664
|
async function getPKPPublicKeyFromTokenId(pkpTokenId, provider, pkpNftContractAddress) {
|
|
29669
|
-
const
|
|
29670
|
-
|
|
29671
|
-
|
|
29672
|
-
|
|
29673
|
-
|
|
29674
|
-
|
|
29675
|
-
|
|
29676
|
-
|
|
29677
|
-
litChainProvider = new ethers_exports.providers.JsonRpcProvider(targetRpc);
|
|
29678
|
-
}
|
|
29679
|
-
} else {
|
|
29680
|
-
litChainProvider = new ethers_exports.providers.JsonRpcProvider(targetRpc);
|
|
29665
|
+
const rawHex = pkpTokenId.startsWith("0x") ? pkpTokenId.slice(2) : pkpTokenId;
|
|
29666
|
+
if (rawHex.length === 64 && rawHex.startsWith("000000000000000000000000") && rawHex !== "0".repeat(64)) {
|
|
29667
|
+
throw new Error(
|
|
29668
|
+
`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.`
|
|
29669
|
+
);
|
|
29670
|
+
}
|
|
29671
|
+
if (!provider) {
|
|
29672
|
+
throw new Error(`provider is required for getPKPPublicKeyFromTokenId`);
|
|
29681
29673
|
}
|
|
29682
29674
|
if (!pkpNftContractAddress) {
|
|
29683
29675
|
throw new Error(
|
|
@@ -29687,7 +29679,7 @@ async function getPKPPublicKeyFromTokenId(pkpTokenId, provider, pkpNftContractAd
|
|
|
29687
29679
|
const pkpNft = new ethers_exports.Contract(
|
|
29688
29680
|
pkpNftContractAddress,
|
|
29689
29681
|
PKP_NFT_ABI,
|
|
29690
|
-
|
|
29682
|
+
provider
|
|
29691
29683
|
);
|
|
29692
29684
|
const tokenIdBN = ethers_exports.BigNumber.from(pkpTokenId);
|
|
29693
29685
|
const pubkeyBytes = await pkpNft["getPubkey"](tokenIdBN);
|
|
@@ -30292,106 +30284,333 @@ function createContractManager(config) {
|
|
|
30292
30284
|
}
|
|
30293
30285
|
|
|
30294
30286
|
// src/modules/cache/cache-manager.module.ts
|
|
30295
|
-
var
|
|
30296
|
-
cache
|
|
30287
|
+
var LRUCache = class {
|
|
30288
|
+
cache;
|
|
30297
30289
|
maxSize;
|
|
30298
30290
|
ttlMs;
|
|
30299
|
-
|
|
30300
|
-
|
|
30301
|
-
|
|
30291
|
+
debug;
|
|
30292
|
+
name;
|
|
30293
|
+
// Statistics
|
|
30294
|
+
stats = {
|
|
30295
|
+
hits: 0,
|
|
30296
|
+
misses: 0,
|
|
30297
|
+
evictions: 0
|
|
30298
|
+
};
|
|
30299
|
+
constructor(config = {}) {
|
|
30300
|
+
this.cache = /* @__PURE__ */ new Map();
|
|
30301
|
+
this.maxSize = config.maxSize || 1e3;
|
|
30302
|
+
this.ttlMs = config.ttlMs || 6e4;
|
|
30303
|
+
this.debug = config.debug || false;
|
|
30304
|
+
this.name = config.name || "Cache";
|
|
30305
|
+
if (this.debug) {
|
|
30306
|
+
console.log(
|
|
30307
|
+
`\u{1F4BE} [${this.name}] Initialized: maxSize=${this.maxSize}, ttl=${this.ttlMs}ms`
|
|
30308
|
+
);
|
|
30309
|
+
}
|
|
30302
30310
|
}
|
|
30303
30311
|
/**
|
|
30304
30312
|
* Get value from cache
|
|
30313
|
+
*
|
|
30314
|
+
* Returns null if:
|
|
30315
|
+
* - Key not found
|
|
30316
|
+
* - Entry has expired
|
|
30317
|
+
*
|
|
30318
|
+
* @param key - Cache key
|
|
30319
|
+
* @returns Cached value or null
|
|
30305
30320
|
*/
|
|
30306
30321
|
get(key2) {
|
|
30307
30322
|
const entry = this.cache.get(key2);
|
|
30308
30323
|
if (!entry) {
|
|
30309
|
-
|
|
30324
|
+
this.stats.misses++;
|
|
30325
|
+
if (this.debug) {
|
|
30326
|
+
console.log(`\u274C [${this.name}] Cache MISS: ${String(key2)}`);
|
|
30327
|
+
}
|
|
30328
|
+
return null;
|
|
30310
30329
|
}
|
|
30311
|
-
|
|
30312
|
-
if (now2 - entry.timestamp > entry.ttl) {
|
|
30330
|
+
if (this.isExpired(entry)) {
|
|
30313
30331
|
this.cache.delete(key2);
|
|
30314
|
-
|
|
30332
|
+
this.stats.misses++;
|
|
30333
|
+
if (this.debug) {
|
|
30334
|
+
const age = Date.now() - entry.timestamp;
|
|
30335
|
+
console.log(`\u23F0 [${this.name}] Cache EXPIRED: ${String(key2)} (age: ${age}ms)`);
|
|
30336
|
+
}
|
|
30337
|
+
return null;
|
|
30338
|
+
}
|
|
30339
|
+
entry.hits++;
|
|
30340
|
+
entry.lastAccessed = Date.now();
|
|
30341
|
+
this.cache.set(key2, entry);
|
|
30342
|
+
this.stats.hits++;
|
|
30343
|
+
if (this.debug) {
|
|
30344
|
+
const age = Date.now() - entry.timestamp;
|
|
30345
|
+
console.log(
|
|
30346
|
+
`\u2705 [${this.name}] Cache HIT: ${String(key2)} (age: ${age}ms, hits: ${entry.hits})`
|
|
30347
|
+
);
|
|
30315
30348
|
}
|
|
30316
30349
|
return entry.value;
|
|
30317
30350
|
}
|
|
30351
|
+
/**
|
|
30352
|
+
* Get value from cache with Result wrapper
|
|
30353
|
+
*
|
|
30354
|
+
* Useful when you want to distinguish between "not found" and "expired"
|
|
30355
|
+
*/
|
|
30356
|
+
getResult(key2) {
|
|
30357
|
+
const value = this.get(key2);
|
|
30358
|
+
if (value === null) {
|
|
30359
|
+
return failure(
|
|
30360
|
+
new SDKError({
|
|
30361
|
+
message: `Cache miss for key: ${String(key2)}`,
|
|
30362
|
+
category: "CACHE" /* CACHE */,
|
|
30363
|
+
severity: "LOW" /* LOW */,
|
|
30364
|
+
originalError: new Error("Cache miss")
|
|
30365
|
+
})
|
|
30366
|
+
);
|
|
30367
|
+
}
|
|
30368
|
+
return success(value);
|
|
30369
|
+
}
|
|
30318
30370
|
/**
|
|
30319
30371
|
* Set value in cache
|
|
30372
|
+
*
|
|
30373
|
+
* If cache is full, evicts the least recently used entry
|
|
30374
|
+
*
|
|
30375
|
+
* @param key - Cache key
|
|
30376
|
+
* @param value - Value to cache
|
|
30377
|
+
* @param ttl - Optional custom TTL for this entry (ms)
|
|
30320
30378
|
*/
|
|
30321
30379
|
set(key2, value, ttl) {
|
|
30322
30380
|
if (this.cache.size >= this.maxSize && !this.cache.has(key2)) {
|
|
30323
|
-
|
|
30324
|
-
if (firstKey) {
|
|
30325
|
-
this.cache.delete(firstKey);
|
|
30326
|
-
}
|
|
30381
|
+
this.evictLRU();
|
|
30327
30382
|
}
|
|
30328
|
-
|
|
30383
|
+
const entry = {
|
|
30329
30384
|
value,
|
|
30330
30385
|
timestamp: Date.now(),
|
|
30331
|
-
|
|
30332
|
-
|
|
30386
|
+
hits: 0,
|
|
30387
|
+
lastAccessed: Date.now()
|
|
30388
|
+
};
|
|
30389
|
+
this.cache.set(key2, entry);
|
|
30390
|
+
if (this.debug) {
|
|
30391
|
+
const effectiveTtl = ttl || this.ttlMs;
|
|
30392
|
+
console.log(
|
|
30393
|
+
`\u{1F4BE} [${this.name}] Cache SET: ${String(key2)} (ttl: ${effectiveTtl}ms, size: ${this.cache.size}/${this.maxSize})`
|
|
30394
|
+
);
|
|
30395
|
+
}
|
|
30333
30396
|
}
|
|
30334
30397
|
/**
|
|
30335
|
-
*
|
|
30398
|
+
* Set value in cache with Result wrapper
|
|
30399
|
+
*/
|
|
30400
|
+
setResult(key2, value, ttl) {
|
|
30401
|
+
try {
|
|
30402
|
+
this.set(key2, value, ttl);
|
|
30403
|
+
return success(void 0);
|
|
30404
|
+
} catch (error) {
|
|
30405
|
+
return failure(
|
|
30406
|
+
new SDKError({
|
|
30407
|
+
message: `Failed to set cache value for key: ${String(key2)}`,
|
|
30408
|
+
category: "CACHE" /* CACHE */,
|
|
30409
|
+
severity: "MEDIUM" /* MEDIUM */,
|
|
30410
|
+
originalError: error instanceof Error ? error : new Error(String(error))
|
|
30411
|
+
})
|
|
30412
|
+
);
|
|
30413
|
+
}
|
|
30414
|
+
}
|
|
30415
|
+
/**
|
|
30416
|
+
* Check if key exists in cache (without affecting stats)
|
|
30336
30417
|
*/
|
|
30337
30418
|
has(key2) {
|
|
30338
|
-
|
|
30419
|
+
const entry = this.cache.get(key2);
|
|
30420
|
+
return entry !== void 0 && !this.isExpired(entry);
|
|
30339
30421
|
}
|
|
30340
30422
|
/**
|
|
30341
|
-
* Delete key from cache
|
|
30423
|
+
* Delete specific key from cache
|
|
30342
30424
|
*/
|
|
30343
30425
|
delete(key2) {
|
|
30344
|
-
|
|
30426
|
+
const deleted = this.cache.delete(key2);
|
|
30427
|
+
if (deleted && this.debug) {
|
|
30428
|
+
console.log(`\u{1F5D1}\uFE0F [${this.name}] Cache DELETE: ${String(key2)}`);
|
|
30429
|
+
}
|
|
30430
|
+
return deleted;
|
|
30345
30431
|
}
|
|
30346
30432
|
/**
|
|
30347
|
-
* Clear
|
|
30433
|
+
* Clear entire cache
|
|
30348
30434
|
*/
|
|
30349
30435
|
clear() {
|
|
30436
|
+
const previousSize = this.cache.size;
|
|
30350
30437
|
this.cache.clear();
|
|
30438
|
+
this.stats = {
|
|
30439
|
+
hits: 0,
|
|
30440
|
+
misses: 0,
|
|
30441
|
+
evictions: 0
|
|
30442
|
+
};
|
|
30443
|
+
if (this.debug) {
|
|
30444
|
+
console.log(`\u{1F9F9} [${this.name}] Cache CLEARED: removed ${previousSize} entries`);
|
|
30445
|
+
}
|
|
30446
|
+
}
|
|
30447
|
+
/**
|
|
30448
|
+
* Get current cache size
|
|
30449
|
+
*/
|
|
30450
|
+
size() {
|
|
30451
|
+
return this.cache.size;
|
|
30452
|
+
}
|
|
30453
|
+
/**
|
|
30454
|
+
* Get cache statistics
|
|
30455
|
+
*/
|
|
30456
|
+
getStats() {
|
|
30457
|
+
const entries = Array.from(this.cache.values());
|
|
30458
|
+
const timestamps = entries.map((e) => e.timestamp);
|
|
30459
|
+
const total = this.stats.hits + this.stats.misses;
|
|
30460
|
+
const hitRate = total === 0 ? 0 : this.stats.hits / total * 100;
|
|
30461
|
+
return {
|
|
30462
|
+
size: this.cache.size,
|
|
30463
|
+
hits: this.stats.hits,
|
|
30464
|
+
misses: this.stats.misses,
|
|
30465
|
+
evictions: this.stats.evictions,
|
|
30466
|
+
oldestEntry: timestamps.length > 0 ? Math.min(...timestamps) : 0,
|
|
30467
|
+
newestEntry: timestamps.length > 0 ? Math.max(...timestamps) : 0,
|
|
30468
|
+
hitRate
|
|
30469
|
+
};
|
|
30470
|
+
}
|
|
30471
|
+
/**
|
|
30472
|
+
* Get hit rate percentage
|
|
30473
|
+
*/
|
|
30474
|
+
getHitRate() {
|
|
30475
|
+
const total = this.stats.hits + this.stats.misses;
|
|
30476
|
+
return total === 0 ? 0 : this.stats.hits / total * 100;
|
|
30477
|
+
}
|
|
30478
|
+
/**
|
|
30479
|
+
* Get all cached keys (for debugging)
|
|
30480
|
+
*/
|
|
30481
|
+
getKeys() {
|
|
30482
|
+
return Array.from(this.cache.keys());
|
|
30483
|
+
}
|
|
30484
|
+
/**
|
|
30485
|
+
* Get all cached values (for debugging)
|
|
30486
|
+
*/
|
|
30487
|
+
getValues() {
|
|
30488
|
+
return Array.from(this.cache.values()).map((entry) => entry.value);
|
|
30489
|
+
}
|
|
30490
|
+
/**
|
|
30491
|
+
* Get all cache entries with metadata (for debugging)
|
|
30492
|
+
*/
|
|
30493
|
+
getEntries() {
|
|
30494
|
+
return Array.from(this.cache.entries()).map(([key2, entry]) => ({
|
|
30495
|
+
key: key2,
|
|
30496
|
+
value: entry.value,
|
|
30497
|
+
metadata: {
|
|
30498
|
+
timestamp: entry.timestamp,
|
|
30499
|
+
hits: entry.hits,
|
|
30500
|
+
lastAccessed: entry.lastAccessed
|
|
30501
|
+
}
|
|
30502
|
+
}));
|
|
30351
30503
|
}
|
|
30352
30504
|
/**
|
|
30353
|
-
* Clean expired entries
|
|
30505
|
+
* Clean up expired entries
|
|
30506
|
+
*
|
|
30507
|
+
* Useful for periodic maintenance
|
|
30508
|
+
*
|
|
30509
|
+
* @returns Number of entries cleaned
|
|
30354
30510
|
*/
|
|
30355
30511
|
cleanExpired() {
|
|
30356
30512
|
const now2 = Date.now();
|
|
30357
|
-
let
|
|
30513
|
+
let cleanedCount = 0;
|
|
30358
30514
|
for (const [key2, entry] of this.cache.entries()) {
|
|
30359
|
-
if (now2 - entry.timestamp >
|
|
30515
|
+
if (now2 - entry.timestamp > this.ttlMs) {
|
|
30360
30516
|
this.cache.delete(key2);
|
|
30361
|
-
|
|
30517
|
+
cleanedCount++;
|
|
30362
30518
|
}
|
|
30363
30519
|
}
|
|
30364
|
-
|
|
30520
|
+
if (cleanedCount > 0 && this.debug) {
|
|
30521
|
+
console.log(`\u{1F9F9} [${this.name}] Cleaned ${cleanedCount} expired entries`);
|
|
30522
|
+
}
|
|
30523
|
+
return cleanedCount;
|
|
30365
30524
|
}
|
|
30366
30525
|
/**
|
|
30367
|
-
*
|
|
30526
|
+
* Check if cache entry is expired
|
|
30368
30527
|
*/
|
|
30369
|
-
|
|
30370
|
-
return
|
|
30371
|
-
|
|
30372
|
-
|
|
30373
|
-
|
|
30374
|
-
|
|
30528
|
+
isExpired(entry) {
|
|
30529
|
+
return Date.now() - entry.timestamp > this.ttlMs;
|
|
30530
|
+
}
|
|
30531
|
+
/**
|
|
30532
|
+
* Evict least recently used entry
|
|
30533
|
+
*/
|
|
30534
|
+
evictLRU() {
|
|
30535
|
+
let oldestKey = null;
|
|
30536
|
+
let oldestAccess = Infinity;
|
|
30537
|
+
for (const [key2, entry] of this.cache.entries()) {
|
|
30538
|
+
if (entry.lastAccessed < oldestAccess) {
|
|
30539
|
+
oldestAccess = entry.lastAccessed;
|
|
30540
|
+
oldestKey = key2;
|
|
30541
|
+
}
|
|
30542
|
+
}
|
|
30543
|
+
if (oldestKey !== null) {
|
|
30544
|
+
this.cache.delete(oldestKey);
|
|
30545
|
+
this.stats.evictions++;
|
|
30546
|
+
if (this.debug) {
|
|
30547
|
+
const timeSinceAccess = Date.now() - oldestAccess;
|
|
30548
|
+
console.log(
|
|
30549
|
+
`\u267B\uFE0F [${this.name}] Cache EVICT (LRU): ${String(oldestKey)} (last accessed: ${timeSinceAccess}ms ago)`
|
|
30550
|
+
);
|
|
30551
|
+
}
|
|
30552
|
+
}
|
|
30553
|
+
}
|
|
30554
|
+
/**
|
|
30555
|
+
* Get or compute value
|
|
30556
|
+
*
|
|
30557
|
+
* If key exists in cache, returns cached value.
|
|
30558
|
+
* Otherwise, computes value using provided function and caches it.
|
|
30559
|
+
*
|
|
30560
|
+
* @param key - Cache key
|
|
30561
|
+
* @param compute - Function to compute value if not in cache
|
|
30562
|
+
* @param ttl - Optional custom TTL for this entry
|
|
30563
|
+
* @returns Cached or computed value
|
|
30564
|
+
*/
|
|
30565
|
+
async getOrCompute(key2, compute, ttl) {
|
|
30566
|
+
const cached = this.get(key2);
|
|
30567
|
+
if (cached !== null) {
|
|
30568
|
+
return cached;
|
|
30569
|
+
}
|
|
30570
|
+
const value = await compute();
|
|
30571
|
+
this.set(key2, value, ttl);
|
|
30572
|
+
return value;
|
|
30573
|
+
}
|
|
30574
|
+
/**
|
|
30575
|
+
* Get or compute value with Result wrapper
|
|
30576
|
+
*/
|
|
30577
|
+
async getOrComputeResult(key2, compute, ttl) {
|
|
30578
|
+
const cached = this.get(key2);
|
|
30579
|
+
if (cached !== null) {
|
|
30580
|
+
return success(cached);
|
|
30581
|
+
}
|
|
30582
|
+
const result = await compute();
|
|
30583
|
+
if (result.success) {
|
|
30584
|
+
this.set(key2, result.value, ttl);
|
|
30585
|
+
}
|
|
30586
|
+
return result;
|
|
30375
30587
|
}
|
|
30376
30588
|
};
|
|
30377
30589
|
var CacheManager = class {
|
|
30378
30590
|
caches = /* @__PURE__ */ new Map();
|
|
30379
|
-
|
|
30380
|
-
constructor(
|
|
30381
|
-
this.
|
|
30591
|
+
globalConfig;
|
|
30592
|
+
constructor(globalConfig = {}) {
|
|
30593
|
+
this.globalConfig = globalConfig;
|
|
30382
30594
|
}
|
|
30383
30595
|
/**
|
|
30384
|
-
*
|
|
30596
|
+
* Create or get a named cache
|
|
30597
|
+
*
|
|
30598
|
+
* @param name - Unique cache name
|
|
30599
|
+
* @param config - Optional cache-specific configuration
|
|
30600
|
+
* @returns LRU cache instance
|
|
30385
30601
|
*/
|
|
30386
30602
|
getCache(name, config) {
|
|
30387
|
-
|
|
30388
|
-
|
|
30603
|
+
const existingCache = this.caches.get(name);
|
|
30604
|
+
if (existingCache) {
|
|
30605
|
+
return existingCache;
|
|
30389
30606
|
}
|
|
30390
|
-
const
|
|
30607
|
+
const mergedConfig = {
|
|
30608
|
+
...this.globalConfig,
|
|
30609
|
+
...config,
|
|
30610
|
+
name
|
|
30611
|
+
};
|
|
30612
|
+
const cache = new LRUCache(mergedConfig);
|
|
30391
30613
|
this.caches.set(name, cache);
|
|
30392
|
-
if (this.debug) {
|
|
30393
|
-
console.log(`[CacheManager] Created cache: ${name}`, config);
|
|
30394
|
-
}
|
|
30395
30614
|
return cache;
|
|
30396
30615
|
}
|
|
30397
30616
|
/**
|
|
@@ -30406,11 +30625,11 @@ var CacheManager = class {
|
|
|
30406
30625
|
* Clean expired entries from all caches
|
|
30407
30626
|
*/
|
|
30408
30627
|
cleanAllExpired() {
|
|
30409
|
-
let
|
|
30628
|
+
let totalCleaned = 0;
|
|
30410
30629
|
for (const cache of this.caches.values()) {
|
|
30411
|
-
|
|
30630
|
+
totalCleaned += cache.cleanExpired();
|
|
30412
30631
|
}
|
|
30413
|
-
return
|
|
30632
|
+
return totalCleaned;
|
|
30414
30633
|
}
|
|
30415
30634
|
/**
|
|
30416
30635
|
* Get statistics for all caches
|
|
@@ -30423,11 +30642,16 @@ var CacheManager = class {
|
|
|
30423
30642
|
return stats;
|
|
30424
30643
|
}
|
|
30425
30644
|
/**
|
|
30426
|
-
*
|
|
30645
|
+
* Get list of all cache names
|
|
30427
30646
|
*/
|
|
30428
|
-
|
|
30429
|
-
this.
|
|
30430
|
-
|
|
30647
|
+
getCacheNames() {
|
|
30648
|
+
return Array.from(this.caches.keys());
|
|
30649
|
+
}
|
|
30650
|
+
/**
|
|
30651
|
+
* Delete a named cache
|
|
30652
|
+
*/
|
|
30653
|
+
deleteCache(name) {
|
|
30654
|
+
return this.caches.delete(name);
|
|
30431
30655
|
}
|
|
30432
30656
|
};
|
|
30433
30657
|
function createCacheManager(config) {
|
|
@@ -31706,6 +31930,23 @@ function createLoanCreator(config) {
|
|
|
31706
31930
|
}
|
|
31707
31931
|
|
|
31708
31932
|
// src/modules/loan/loan-query.module.ts
|
|
31933
|
+
var POSITION_CORE_ABI = [
|
|
31934
|
+
"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))"
|
|
31935
|
+
];
|
|
31936
|
+
function normalizePkpId(pkpId) {
|
|
31937
|
+
const raw = pkpId.startsWith("0x") ? pkpId.slice(2) : pkpId;
|
|
31938
|
+
if (raw.length === 64 && raw.startsWith("000000000000000000000000") && raw !== "0".repeat(64)) {
|
|
31939
|
+
return `0x${raw.slice(24)}`;
|
|
31940
|
+
}
|
|
31941
|
+
return pkpId;
|
|
31942
|
+
}
|
|
31943
|
+
function padPkpIdForSubgraph(pkpId) {
|
|
31944
|
+
const raw = pkpId.startsWith("0x") ? pkpId.slice(2) : pkpId;
|
|
31945
|
+
if (raw.length === 40) {
|
|
31946
|
+
return `0x${"0".repeat(24)}${raw}`;
|
|
31947
|
+
}
|
|
31948
|
+
return pkpId;
|
|
31949
|
+
}
|
|
31709
31950
|
var LoanQuery = class {
|
|
31710
31951
|
config;
|
|
31711
31952
|
defaultPageSize;
|
|
@@ -31734,7 +31975,7 @@ var LoanQuery = class {
|
|
|
31734
31975
|
const borrowerCreatedAt = typeof rawLoan.borrower === "object" && rawLoan.borrower?.createdAt ? Number(rawLoan.borrower.createdAt) : 0;
|
|
31735
31976
|
const loanData = {
|
|
31736
31977
|
id: rawLoan.id,
|
|
31737
|
-
pkpId: rawLoan.pkpId,
|
|
31978
|
+
pkpId: normalizePkpId(rawLoan.pkpId),
|
|
31738
31979
|
borrower: {
|
|
31739
31980
|
createdAt: borrowerCreatedAt,
|
|
31740
31981
|
id: borrowerId
|
|
@@ -31780,6 +32021,7 @@ var LoanQuery = class {
|
|
|
31780
32021
|
* @returns Loan data
|
|
31781
32022
|
*/
|
|
31782
32023
|
async getLoanByPkpId(pkpId, enrichBalance = false) {
|
|
32024
|
+
pkpId = padPkpIdForSubgraph(pkpId);
|
|
31783
32025
|
if (this.config.debug) {
|
|
31784
32026
|
log.info("\u{1F50D} Querying loan by PKP ID", { pkpId, enrichBalance });
|
|
31785
32027
|
}
|
|
@@ -31802,7 +32044,7 @@ var LoanQuery = class {
|
|
|
31802
32044
|
const borrowerCreatedAt = typeof rawLoan.borrower === "object" && rawLoan.borrower?.createdAt ? Number(rawLoan.borrower.createdAt) : 0;
|
|
31803
32045
|
const loanData = {
|
|
31804
32046
|
id: rawLoan.id,
|
|
31805
|
-
pkpId: rawLoan.pkpId,
|
|
32047
|
+
pkpId: normalizePkpId(rawLoan.pkpId),
|
|
31806
32048
|
borrower: {
|
|
31807
32049
|
createdAt: borrowerCreatedAt,
|
|
31808
32050
|
id: borrowerId
|
|
@@ -31981,10 +32223,30 @@ var LoanQuery = class {
|
|
|
31981
32223
|
await Promise.all(
|
|
31982
32224
|
batch.map(async (loan) => {
|
|
31983
32225
|
try {
|
|
31984
|
-
const
|
|
31985
|
-
|
|
31986
|
-
|
|
31987
|
-
|
|
32226
|
+
const rawId = loan.pkpId?.startsWith("0x") ? loan.pkpId.slice(2) : loan.pkpId;
|
|
32227
|
+
const isChipotlePkpId = typeof rawId === "string" && rawId.length === 40 && !rawId.toLowerCase().startsWith("04");
|
|
32228
|
+
if (isChipotlePkpId) {
|
|
32229
|
+
if (this.config.positionManagerCoreAddress && this.config.provider) {
|
|
32230
|
+
const pmContract = new ethers_exports.Contract(
|
|
32231
|
+
this.config.positionManagerCoreAddress,
|
|
32232
|
+
POSITION_CORE_ABI,
|
|
32233
|
+
this.config.provider
|
|
32234
|
+
);
|
|
32235
|
+
const pos = await pmContract["getPositionDetails"](loan.id);
|
|
32236
|
+
const vaultAddr = pos.vaultAddress ?? pos[3] ?? "";
|
|
32237
|
+
if (vaultAddr) {
|
|
32238
|
+
loan.collateral.vaultAddress = vaultAddr;
|
|
32239
|
+
if (this.config.debug) {
|
|
32240
|
+
log.info(`\u2705 Vault address from contract for loan ${loan.id}`, { vaultAddr });
|
|
32241
|
+
}
|
|
32242
|
+
}
|
|
32243
|
+
} else if (this.config.debug) {
|
|
32244
|
+
log.warn(`\u26A0\uFE0F Chipotle pkpId for loan ${loan.id} but no positionManagerCoreAddress configured`);
|
|
32245
|
+
}
|
|
32246
|
+
return;
|
|
32247
|
+
}
|
|
32248
|
+
const isUncompressedPubKey = typeof rawId === "string" && rawId.length === 130 && rawId.toLowerCase().startsWith("04");
|
|
32249
|
+
const pkpPublicKey = isUncompressedPubKey ? loan.pkpId.startsWith("0x") ? loan.pkpId : `0x${loan.pkpId}` : await getPKPPublicKeyFromTokenId(loan.pkpId, this.config.provider);
|
|
31988
32250
|
const addressesResult = await this.config.bitcoinOperations.deriveAddresses(pkpPublicKey);
|
|
31989
32251
|
if (addressesResult.success) {
|
|
31990
32252
|
loan.collateral.vaultAddress = addressesResult.value;
|
|
@@ -33420,6 +33682,13 @@ var GraphClient = class {
|
|
|
33420
33682
|
var THE_GRAPH_MAX_BATCH_SIZE = 1e3;
|
|
33421
33683
|
|
|
33422
33684
|
// src/graphs/diamond-hands.ts
|
|
33685
|
+
function normalizePkpId2(pkpId) {
|
|
33686
|
+
const raw = pkpId.startsWith("0x") ? pkpId.slice(2) : pkpId;
|
|
33687
|
+
if (raw.length === 64 && raw.startsWith("000000000000000000000000") && raw !== "0".repeat(64)) {
|
|
33688
|
+
return `0x${raw.slice(24)}`;
|
|
33689
|
+
}
|
|
33690
|
+
return pkpId;
|
|
33691
|
+
}
|
|
33423
33692
|
var DiamondHandsGraph = class {
|
|
33424
33693
|
client;
|
|
33425
33694
|
defaultPageSize;
|
|
@@ -33442,7 +33711,7 @@ var DiamondHandsGraph = class {
|
|
|
33442
33711
|
const ucdDebt = graphPosition.ucdDebt ? Number(graphPosition.ucdDebt) : 0;
|
|
33443
33712
|
return {
|
|
33444
33713
|
id: graphPosition.id,
|
|
33445
|
-
pkpId: graphPosition.pkpId,
|
|
33714
|
+
pkpId: normalizePkpId2(graphPosition.pkpId),
|
|
33446
33715
|
borrower: {
|
|
33447
33716
|
createdAt: graphPosition.borrower?.createdAt ? Number(graphPosition.borrower.createdAt) : 0,
|
|
33448
33717
|
id: graphPosition.borrower?.id || graphPosition.borrower
|
|
@@ -34704,39 +34973,6 @@ try {
|
|
|
34704
34973
|
} catch (error) {
|
|
34705
34974
|
console.warn("Telegram bot API not available:", error instanceof Error ? error.message : String(error));
|
|
34706
34975
|
}
|
|
34707
|
-
async function sendTelegramMessage(chatId, chatToken, message, threadId) {
|
|
34708
|
-
try {
|
|
34709
|
-
if (typeof window !== "undefined") {
|
|
34710
|
-
if (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1") {
|
|
34711
|
-
console.log("[Browser] Telegram messaging not available - skipping notification");
|
|
34712
|
-
}
|
|
34713
|
-
return;
|
|
34714
|
-
}
|
|
34715
|
-
if (!TelegramBot) {
|
|
34716
|
-
console.warn("Telegram bot API not available in this environment");
|
|
34717
|
-
return;
|
|
34718
|
-
}
|
|
34719
|
-
const bot = new TelegramBot(chatToken, { polling: false });
|
|
34720
|
-
const options = {
|
|
34721
|
-
disable_web_page_preview: true
|
|
34722
|
-
};
|
|
34723
|
-
if (threadId !== void 0) {
|
|
34724
|
-
options.message_thread_id = threadId;
|
|
34725
|
-
}
|
|
34726
|
-
console.log("\u{1F4F1} Sending Telegram message...");
|
|
34727
|
-
console.log(` Chat ID: ${chatId}`);
|
|
34728
|
-
console.log(` Thread ID: ${threadId || "none"}`);
|
|
34729
|
-
console.log(` Message: ${message}`);
|
|
34730
|
-
const result = await bot.sendMessage(chatId, message, options);
|
|
34731
|
-
console.log("\u2705 Telegram message sent successfully!");
|
|
34732
|
-
console.log(` Message ID: ${result.message_id}`);
|
|
34733
|
-
} catch (error) {
|
|
34734
|
-
console.error("\u274C Failed to send Telegram message:", error);
|
|
34735
|
-
if (error instanceof Error) {
|
|
34736
|
-
console.error(` Error message: ${error.message}`);
|
|
34737
|
-
}
|
|
34738
|
-
}
|
|
34739
|
-
}
|
|
34740
34976
|
function formatMintMessage(mintAmount, loanId, txHash) {
|
|
34741
34977
|
return `${mintAmount} UCD was minted for loan id: ${loanId} Tx: https://sepolia.etherscan.io/tx/${txHash}`;
|
|
34742
34978
|
}
|
|
@@ -35055,6 +35291,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35055
35291
|
network: config.litNetwork || DEFAULT_LIT_NETWORK,
|
|
35056
35292
|
signer: config.mode === "standalone" ? config.litOpsSigner : void 0,
|
|
35057
35293
|
serviceEndpoint: isServiceModeConfig(config) ? config.serviceEndpoint : void 0,
|
|
35294
|
+
serviceAuthToken: isServiceModeConfig(config) ? config.serviceAuthToken : void 0,
|
|
35058
35295
|
debug: config.debug,
|
|
35059
35296
|
litNodeConnectTimeoutMs: config.litNodeConnectTimeoutMs
|
|
35060
35297
|
// TODO Round 2: Add litActionExecution config when added to config.i.ts interface
|
|
@@ -35112,19 +35349,21 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35112
35349
|
);
|
|
35113
35350
|
}
|
|
35114
35351
|
this.pkpManager = pkpManagerResult.value;
|
|
35115
|
-
const
|
|
35352
|
+
const serviceMode = isServiceModeConfig(config);
|
|
35353
|
+
const graphEndpoint = serviceMode ? `${config.serviceEndpoint}/api/lit/graph/query` : config.subgraphs?.diamondHandsUrl;
|
|
35116
35354
|
if (!graphEndpoint) {
|
|
35117
35355
|
throw new Error(
|
|
35118
35356
|
"Diamond Hands subgraph URL is required. Please provide config.subgraphs.diamondHandsUrl"
|
|
35119
35357
|
);
|
|
35120
35358
|
}
|
|
35359
|
+
const graphHeaders = serviceMode && config.serviceAuthToken ? { Authorization: `Bearer ${config.serviceAuthToken}` } : config.graphApiKey ? { Authorization: `Bearer ${config.graphApiKey}` } : void 0;
|
|
35121
35360
|
this.graphClient = new DiamondHandsGraph(
|
|
35122
35361
|
{
|
|
35123
35362
|
endpoint: graphEndpoint,
|
|
35124
35363
|
requestTimeoutMs: config.graphOptions?.requestTimeoutMs,
|
|
35125
35364
|
maxRetries: config.graphOptions?.maxRetries,
|
|
35126
35365
|
defaultPageSize: config.graphOptions?.pageSize,
|
|
35127
|
-
headers:
|
|
35366
|
+
headers: graphHeaders
|
|
35128
35367
|
},
|
|
35129
35368
|
this.bitcoinOperations
|
|
35130
35369
|
);
|
|
@@ -35132,6 +35371,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35132
35371
|
graphClient: this.graphClient,
|
|
35133
35372
|
bitcoinOperations: this.bitcoinOperations,
|
|
35134
35373
|
provider: config.provider,
|
|
35374
|
+
positionManagerCoreAddress: config.contractAddresses?.positionManagerCore,
|
|
35135
35375
|
cache: this.cacheManager.getCache("loan-data", {
|
|
35136
35376
|
maxSize: 200,
|
|
35137
35377
|
ttlMs: 3e4
|
|
@@ -35523,6 +35763,30 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35523
35763
|
/**
|
|
35524
35764
|
* Check if SDK is ready for operations
|
|
35525
35765
|
*/
|
|
35766
|
+
async _relayNotification(message) {
|
|
35767
|
+
if (this.config.mode !== "service")
|
|
35768
|
+
return;
|
|
35769
|
+
const endpoint = this.config.serviceEndpoint;
|
|
35770
|
+
if (!endpoint)
|
|
35771
|
+
return;
|
|
35772
|
+
const token = this.config.serviceAuthToken;
|
|
35773
|
+
try {
|
|
35774
|
+
await fetch(`${endpoint}/api/lit/notifications/send`, {
|
|
35775
|
+
method: "POST",
|
|
35776
|
+
headers: {
|
|
35777
|
+
"Content-Type": "application/json",
|
|
35778
|
+
...token ? { Authorization: `Bearer ${token}` } : {}
|
|
35779
|
+
},
|
|
35780
|
+
body: JSON.stringify({ message })
|
|
35781
|
+
});
|
|
35782
|
+
} catch (err) {
|
|
35783
|
+
if (this.config.debug) {
|
|
35784
|
+
log.warn("Notification relay failed", {
|
|
35785
|
+
error: err instanceof Error ? err.message : String(err)
|
|
35786
|
+
});
|
|
35787
|
+
}
|
|
35788
|
+
}
|
|
35789
|
+
}
|
|
35526
35790
|
checkInitialized() {
|
|
35527
35791
|
if (!this.isInitialized) {
|
|
35528
35792
|
return failure(
|
|
@@ -35598,7 +35862,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35598
35862
|
return failure(initCheck.error);
|
|
35599
35863
|
}
|
|
35600
35864
|
const result = await this.loanCreator.createLoan(request);
|
|
35601
|
-
if (result.success &&
|
|
35865
|
+
if (result.success && result.value.positionId) {
|
|
35602
35866
|
try {
|
|
35603
35867
|
const message = formatLoanCreationMessage(
|
|
35604
35868
|
result.value.positionId,
|
|
@@ -35610,12 +35874,7 @@ var DiamondHandsSDK = class _DiamondHandsSDK {
|
|
|
35610
35874
|
"\u{1F4F1} Attempting to send loan creation Telegram message..."
|
|
35611
35875
|
);
|
|
35612
35876
|
}
|
|
35613
|
-
await
|
|
35614
|
-
this.config.telegram.chatId,
|
|
35615
|
-
this.config.telegram.chatToken,
|
|
35616
|
-
message,
|
|
35617
|
-
this.config.telegram.threadId
|
|
35618
|
-
);
|
|
35877
|
+
await this._relayNotification(message);
|
|
35619
35878
|
if (this.config.debug) {
|
|
35620
35879
|
console.log("\u2705 Loan creation Telegram message sent successfully");
|
|
35621
35880
|
}
|
|
@@ -36789,7 +37048,7 @@ Error data: ${errorData || "none"}`
|
|
|
36789
37048
|
amountMintedUCD: Number(amountMinted) / 10 ** 18
|
|
36790
37049
|
};
|
|
36791
37050
|
try {
|
|
36792
|
-
if (
|
|
37051
|
+
if (result.transactionHash) {
|
|
36793
37052
|
const mintAmount = result.amountMintedUCD || request.amount;
|
|
36794
37053
|
const loanId = result.positionId || request.positionId;
|
|
36795
37054
|
const message = formatMintMessage(
|
|
@@ -36797,12 +37056,7 @@ Error data: ${errorData || "none"}`
|
|
|
36797
37056
|
loanId,
|
|
36798
37057
|
result.transactionHash
|
|
36799
37058
|
);
|
|
36800
|
-
await
|
|
36801
|
-
this.config.telegram.chatId,
|
|
36802
|
-
this.config.telegram.chatToken,
|
|
36803
|
-
message,
|
|
36804
|
-
this.config.telegram.threadId
|
|
36805
|
-
);
|
|
37059
|
+
await this._relayNotification(message);
|
|
36806
37060
|
}
|
|
36807
37061
|
} catch (err) {
|
|
36808
37062
|
}
|
|
@@ -37064,39 +37318,32 @@ Error data: ${errorData || "none"}`
|
|
|
37064
37318
|
}
|
|
37065
37319
|
if (!shouldLiquidate) {
|
|
37066
37320
|
try {
|
|
37067
|
-
if (this.config.
|
|
37068
|
-
|
|
37069
|
-
|
|
37070
|
-
|
|
37071
|
-
|
|
37072
|
-
|
|
37073
|
-
|
|
37074
|
-
|
|
37075
|
-
|
|
37076
|
-
|
|
37077
|
-
|
|
37078
|
-
|
|
37079
|
-
|
|
37080
|
-
|
|
37081
|
-
|
|
37082
|
-
|
|
37083
|
-
|
|
37084
|
-
|
|
37085
|
-
|
|
37086
|
-
|
|
37087
|
-
|
|
37088
|
-
|
|
37089
|
-
|
|
37090
|
-
|
|
37091
|
-
|
|
37092
|
-
message,
|
|
37093
|
-
this.config.telegram.threadId
|
|
37321
|
+
if (this.config.debug) {
|
|
37322
|
+
log.info(`\u{1F4F1} Sending liquidation skipped Telegram message...`);
|
|
37323
|
+
}
|
|
37324
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37325
|
+
const btcPrice2 = litActionResult.btcPrice || "0";
|
|
37326
|
+
const btcVaultBalance = litActionResult.btcAmountSats || positionDetails.btcVaultBalance || "0";
|
|
37327
|
+
const usdPricePerBTC = Number(btcPrice2) / 1e8;
|
|
37328
|
+
const btcAmount = Number(btcVaultBalance) / 1e8;
|
|
37329
|
+
const btcValueUSD = btcAmount * usdPricePerBTC;
|
|
37330
|
+
const debtUSD = Number(debt) / 1e18;
|
|
37331
|
+
const ratio = debtUSD > 0 ? (btcValueUSD / debtUSD * 100).toFixed(2) : "0.00";
|
|
37332
|
+
const message = formatLiquidationSkippedMessage(
|
|
37333
|
+
request.positionId,
|
|
37334
|
+
ratio,
|
|
37335
|
+
`${liquidationThreshold / 100}`,
|
|
37336
|
+
// Convert to percentage
|
|
37337
|
+
positionDetails.vaultAddress || "unknown",
|
|
37338
|
+
btcVaultBalance,
|
|
37339
|
+
debt,
|
|
37340
|
+
btcPrice2
|
|
37341
|
+
);
|
|
37342
|
+
await this._relayNotification(message);
|
|
37343
|
+
if (this.config.debug) {
|
|
37344
|
+
log.info(
|
|
37345
|
+
`\u2705 Liquidation skipped Telegram message sent successfully`
|
|
37094
37346
|
);
|
|
37095
|
-
if (this.config.debug) {
|
|
37096
|
-
log.info(
|
|
37097
|
-
`\u2705 Liquidation skipped Telegram message sent successfully`
|
|
37098
|
-
);
|
|
37099
|
-
}
|
|
37100
37347
|
}
|
|
37101
37348
|
} catch (telegramError) {
|
|
37102
37349
|
if (this.config.debug) {
|
|
@@ -37151,32 +37398,25 @@ Error data: ${errorData || "none"}`
|
|
|
37151
37398
|
});
|
|
37152
37399
|
}
|
|
37153
37400
|
try {
|
|
37154
|
-
if (this.config.
|
|
37155
|
-
|
|
37156
|
-
|
|
37157
|
-
|
|
37158
|
-
|
|
37159
|
-
|
|
37160
|
-
|
|
37161
|
-
|
|
37162
|
-
|
|
37163
|
-
|
|
37164
|
-
|
|
37165
|
-
|
|
37166
|
-
|
|
37167
|
-
|
|
37168
|
-
|
|
37169
|
-
|
|
37170
|
-
|
|
37171
|
-
|
|
37172
|
-
message,
|
|
37173
|
-
this.config.telegram.threadId
|
|
37401
|
+
if (this.config.debug) {
|
|
37402
|
+
log.info(`\u{1F4F1} Sending LIT action rejection Telegram message...`);
|
|
37403
|
+
}
|
|
37404
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37405
|
+
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37406
|
+
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37407
|
+
const message = formatLiquidationFailureMessage(
|
|
37408
|
+
request.positionId,
|
|
37409
|
+
`LIT Action rejected liquidation: ${litActionResult.reason || litActionResult.error || "Unknown error"}`,
|
|
37410
|
+
positionDetails.vaultAddress || "unknown",
|
|
37411
|
+
btcVaultBalance,
|
|
37412
|
+
debt,
|
|
37413
|
+
btcPrice2
|
|
37414
|
+
);
|
|
37415
|
+
await this._relayNotification(message);
|
|
37416
|
+
if (this.config.debug) {
|
|
37417
|
+
log.info(
|
|
37418
|
+
`\u2705 LIT action rejection Telegram message sent successfully`
|
|
37174
37419
|
);
|
|
37175
|
-
if (this.config.debug) {
|
|
37176
|
-
log.info(
|
|
37177
|
-
`\u2705 LIT action rejection Telegram message sent successfully`
|
|
37178
|
-
);
|
|
37179
|
-
}
|
|
37180
37420
|
}
|
|
37181
37421
|
} catch (telegramError) {
|
|
37182
37422
|
if (this.config.debug) {
|
|
@@ -37198,32 +37438,25 @@ Error data: ${errorData || "none"}`
|
|
|
37198
37438
|
);
|
|
37199
37439
|
}
|
|
37200
37440
|
try {
|
|
37201
|
-
if (this.config.
|
|
37202
|
-
|
|
37203
|
-
|
|
37204
|
-
|
|
37205
|
-
|
|
37206
|
-
|
|
37207
|
-
|
|
37208
|
-
|
|
37209
|
-
|
|
37210
|
-
|
|
37211
|
-
|
|
37212
|
-
|
|
37213
|
-
|
|
37214
|
-
|
|
37215
|
-
|
|
37216
|
-
|
|
37217
|
-
|
|
37218
|
-
|
|
37219
|
-
message,
|
|
37220
|
-
this.config.telegram.threadId
|
|
37441
|
+
if (this.config.debug) {
|
|
37442
|
+
log.info(`\u{1F4F1} Sending forced liquidation Telegram message...`);
|
|
37443
|
+
}
|
|
37444
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37445
|
+
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37446
|
+
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37447
|
+
const message = formatLiquidationFailureMessage(
|
|
37448
|
+
request.positionId,
|
|
37449
|
+
`FORCED LIQUIDATION: LIT Action rejected but forceContractCall=true - proceeding with liquidation`,
|
|
37450
|
+
positionDetails.vaultAddress || "unknown",
|
|
37451
|
+
btcVaultBalance,
|
|
37452
|
+
debt,
|
|
37453
|
+
btcPrice2
|
|
37454
|
+
);
|
|
37455
|
+
await this._relayNotification(message);
|
|
37456
|
+
if (this.config.debug) {
|
|
37457
|
+
log.info(
|
|
37458
|
+
`\u2705 Forced liquidation Telegram message sent successfully`
|
|
37221
37459
|
);
|
|
37222
|
-
if (this.config.debug) {
|
|
37223
|
-
log.info(
|
|
37224
|
-
`\u2705 Forced liquidation Telegram message sent successfully`
|
|
37225
|
-
);
|
|
37226
|
-
}
|
|
37227
37460
|
}
|
|
37228
37461
|
} catch (telegramError) {
|
|
37229
37462
|
if (this.config.debug) {
|
|
@@ -37256,34 +37489,27 @@ Error data: ${errorData || "none"}`
|
|
|
37256
37489
|
);
|
|
37257
37490
|
}
|
|
37258
37491
|
try {
|
|
37259
|
-
if (this.config.
|
|
37260
|
-
|
|
37261
|
-
|
|
37262
|
-
`\u{1F4F1} Sending forced liquidation without signature Telegram message...`
|
|
37263
|
-
);
|
|
37264
|
-
}
|
|
37265
|
-
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37266
|
-
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37267
|
-
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37268
|
-
const message = formatLiquidationFailureMessage(
|
|
37269
|
-
request.positionId,
|
|
37270
|
-
"FORCED LIQUIDATION: LIT Action did not provide signature but forceContractCall=true - proceeding without signature",
|
|
37271
|
-
positionDetails.vaultAddress || "unknown",
|
|
37272
|
-
btcVaultBalance,
|
|
37273
|
-
debt,
|
|
37274
|
-
btcPrice2
|
|
37492
|
+
if (this.config.debug) {
|
|
37493
|
+
log.info(
|
|
37494
|
+
`\u{1F4F1} Sending forced liquidation without signature Telegram message...`
|
|
37275
37495
|
);
|
|
37276
|
-
|
|
37277
|
-
|
|
37278
|
-
|
|
37279
|
-
|
|
37280
|
-
|
|
37496
|
+
}
|
|
37497
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37498
|
+
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37499
|
+
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37500
|
+
const message = formatLiquidationFailureMessage(
|
|
37501
|
+
request.positionId,
|
|
37502
|
+
"FORCED LIQUIDATION: LIT Action did not provide signature but forceContractCall=true - proceeding without signature",
|
|
37503
|
+
positionDetails.vaultAddress || "unknown",
|
|
37504
|
+
btcVaultBalance,
|
|
37505
|
+
debt,
|
|
37506
|
+
btcPrice2
|
|
37507
|
+
);
|
|
37508
|
+
await this._relayNotification(message);
|
|
37509
|
+
if (this.config.debug) {
|
|
37510
|
+
log.info(
|
|
37511
|
+
`\u2705 Forced liquidation without signature Telegram message sent successfully`
|
|
37281
37512
|
);
|
|
37282
|
-
if (this.config.debug) {
|
|
37283
|
-
log.info(
|
|
37284
|
-
`\u2705 Forced liquidation without signature Telegram message sent successfully`
|
|
37285
|
-
);
|
|
37286
|
-
}
|
|
37287
37513
|
}
|
|
37288
37514
|
} catch (telegramError) {
|
|
37289
37515
|
if (this.config.debug) {
|
|
@@ -37297,32 +37523,25 @@ Error data: ${errorData || "none"}`
|
|
|
37297
37523
|
}
|
|
37298
37524
|
} else {
|
|
37299
37525
|
try {
|
|
37300
|
-
if (this.config.
|
|
37301
|
-
|
|
37302
|
-
|
|
37303
|
-
|
|
37304
|
-
|
|
37305
|
-
|
|
37306
|
-
|
|
37307
|
-
|
|
37308
|
-
|
|
37309
|
-
|
|
37310
|
-
|
|
37311
|
-
|
|
37312
|
-
|
|
37313
|
-
|
|
37314
|
-
|
|
37315
|
-
|
|
37316
|
-
|
|
37317
|
-
|
|
37318
|
-
message,
|
|
37319
|
-
this.config.telegram.threadId
|
|
37526
|
+
if (this.config.debug) {
|
|
37527
|
+
log.info(`\u{1F4F1} Sending missing signature Telegram message...`);
|
|
37528
|
+
}
|
|
37529
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37530
|
+
const btcPrice2 = litActionResult.btcPrice || "unknown";
|
|
37531
|
+
const btcVaultBalance = litActionResult.btcAmountSats || "unknown";
|
|
37532
|
+
const message = formatLiquidationFailureMessage(
|
|
37533
|
+
request.positionId,
|
|
37534
|
+
"LIT Action did not provide required signature for liquidation",
|
|
37535
|
+
positionDetails.vaultAddress || "unknown",
|
|
37536
|
+
btcVaultBalance,
|
|
37537
|
+
debt,
|
|
37538
|
+
btcPrice2
|
|
37539
|
+
);
|
|
37540
|
+
await this._relayNotification(message);
|
|
37541
|
+
if (this.config.debug) {
|
|
37542
|
+
log.info(
|
|
37543
|
+
`\u2705 Missing signature Telegram message sent successfully`
|
|
37320
37544
|
);
|
|
37321
|
-
if (this.config.debug) {
|
|
37322
|
-
log.info(
|
|
37323
|
-
`\u2705 Missing signature Telegram message sent successfully`
|
|
37324
|
-
);
|
|
37325
|
-
}
|
|
37326
37545
|
}
|
|
37327
37546
|
} catch (telegramError) {
|
|
37328
37547
|
if (this.config.debug) {
|
|
@@ -37561,34 +37780,27 @@ Error data: ${errorData || "none"}`
|
|
|
37561
37780
|
});
|
|
37562
37781
|
}
|
|
37563
37782
|
try {
|
|
37564
|
-
if (this.config.
|
|
37565
|
-
|
|
37566
|
-
|
|
37567
|
-
|
|
37568
|
-
|
|
37569
|
-
|
|
37570
|
-
|
|
37571
|
-
|
|
37572
|
-
|
|
37573
|
-
|
|
37574
|
-
|
|
37575
|
-
|
|
37576
|
-
|
|
37577
|
-
|
|
37578
|
-
|
|
37579
|
-
|
|
37580
|
-
|
|
37581
|
-
|
|
37582
|
-
|
|
37583
|
-
|
|
37584
|
-
message,
|
|
37585
|
-
this.config.telegram.threadId
|
|
37783
|
+
if (this.config.debug) {
|
|
37784
|
+
log.info(`\u{1F4F1} Sending liquidation success Telegram message...`);
|
|
37785
|
+
}
|
|
37786
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37787
|
+
const btcPrice2 = litActionResult.btcPrice || "0";
|
|
37788
|
+
const ratio = debt !== "0" ? (Number(positionDetails.btcVaultBalance || "0") * Number(btcPrice2) / Number(debt) * 100 / 1e8).toFixed(2) : "0.00";
|
|
37789
|
+
const message = formatLiquidationSuccessMessage(
|
|
37790
|
+
request.positionId,
|
|
37791
|
+
ratio,
|
|
37792
|
+
`${liquidationThreshold / 100}`,
|
|
37793
|
+
// Convert to percentage
|
|
37794
|
+
positionDetails.btcVault || "unknown",
|
|
37795
|
+
positionDetails.btcVaultBalance || "0",
|
|
37796
|
+
debt,
|
|
37797
|
+
btcPrice2
|
|
37798
|
+
);
|
|
37799
|
+
await this._relayNotification(message);
|
|
37800
|
+
if (this.config.debug) {
|
|
37801
|
+
log.info(
|
|
37802
|
+
`\u2705 Liquidation success Telegram message sent successfully`
|
|
37586
37803
|
);
|
|
37587
|
-
if (this.config.debug) {
|
|
37588
|
-
log.info(
|
|
37589
|
-
`\u2705 Liquidation success Telegram message sent successfully`
|
|
37590
|
-
);
|
|
37591
|
-
}
|
|
37592
37804
|
}
|
|
37593
37805
|
} catch (telegramError) {
|
|
37594
37806
|
if (this.config.debug) {
|
|
@@ -37620,31 +37832,24 @@ Error data: ${errorData || "none"}`
|
|
|
37620
37832
|
transaction: contractError.transaction
|
|
37621
37833
|
});
|
|
37622
37834
|
try {
|
|
37623
|
-
if (this.config.
|
|
37624
|
-
|
|
37625
|
-
|
|
37626
|
-
|
|
37627
|
-
|
|
37628
|
-
|
|
37629
|
-
|
|
37630
|
-
|
|
37631
|
-
|
|
37632
|
-
|
|
37633
|
-
|
|
37634
|
-
|
|
37635
|
-
|
|
37636
|
-
|
|
37637
|
-
|
|
37638
|
-
|
|
37639
|
-
|
|
37640
|
-
message,
|
|
37641
|
-
this.config.telegram.threadId
|
|
37835
|
+
if (this.config.debug) {
|
|
37836
|
+
log.info(`\u{1F4F1} Sending liquidation failure Telegram message...`);
|
|
37837
|
+
}
|
|
37838
|
+
const debt = positionDetails.debt || positionDetails.ucdDebt || "0";
|
|
37839
|
+
const btcPrice2 = litActionResult.btcPrice || "0";
|
|
37840
|
+
const message = formatLiquidationFailureMessage(
|
|
37841
|
+
request.positionId,
|
|
37842
|
+
contractError.message || "Unknown contract error",
|
|
37843
|
+
positionDetails.btcVault || "unknown",
|
|
37844
|
+
positionDetails.btcVaultBalance || "0",
|
|
37845
|
+
debt,
|
|
37846
|
+
btcPrice2
|
|
37847
|
+
);
|
|
37848
|
+
await this._relayNotification(message);
|
|
37849
|
+
if (this.config.debug) {
|
|
37850
|
+
log.info(
|
|
37851
|
+
`\u2705 Liquidation failure Telegram message sent successfully`
|
|
37642
37852
|
);
|
|
37643
|
-
if (this.config.debug) {
|
|
37644
|
-
log.info(
|
|
37645
|
-
`\u2705 Liquidation failure Telegram message sent successfully`
|
|
37646
|
-
);
|
|
37647
|
-
}
|
|
37648
37853
|
}
|
|
37649
37854
|
} catch (telegramError) {
|
|
37650
37855
|
if (this.config.debug) {
|
|
@@ -37794,26 +37999,19 @@ Error data: ${errorData || "none"}`
|
|
|
37794
37999
|
)} (${potentialNewExpiry}), max allowed: ${formatDate(
|
|
37795
38000
|
maxAllowedTimestamp
|
|
37796
38001
|
)} (${maxAllowedTimestamp})`;
|
|
37797
|
-
|
|
37798
|
-
|
|
37799
|
-
|
|
37800
|
-
|
|
37801
|
-
|
|
37802
|
-
|
|
37803
|
-
|
|
37804
|
-
|
|
37805
|
-
|
|
37806
|
-
|
|
38002
|
+
try {
|
|
38003
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(
|
|
38004
|
+
_positionId,
|
|
38005
|
+
`Loan could not be renewed: ${errorMessage}`
|
|
38006
|
+
));
|
|
38007
|
+
} catch (e) {
|
|
38008
|
+
if (this.config.debug) {
|
|
38009
|
+
log.warn(
|
|
38010
|
+
"Failed to send Telegram notification for renewal rule violation",
|
|
38011
|
+
{
|
|
38012
|
+
error: e instanceof Error ? e.message : String(e)
|
|
38013
|
+
}
|
|
37807
38014
|
);
|
|
37808
|
-
} catch (e) {
|
|
37809
|
-
if (this.config.debug) {
|
|
37810
|
-
log.warn(
|
|
37811
|
-
"Failed to send Telegram notification for renewal rule violation",
|
|
37812
|
-
{
|
|
37813
|
-
error: e instanceof Error ? e.message : String(e)
|
|
37814
|
-
}
|
|
37815
|
-
);
|
|
37816
|
-
}
|
|
37817
38015
|
}
|
|
37818
38016
|
}
|
|
37819
38017
|
throw new Error(errorMessage);
|
|
@@ -37865,19 +38063,12 @@ Error data: ${errorData || "none"}`
|
|
|
37865
38063
|
error: errorMessage
|
|
37866
38064
|
});
|
|
37867
38065
|
}
|
|
37868
|
-
|
|
37869
|
-
|
|
37870
|
-
|
|
37871
|
-
|
|
37872
|
-
|
|
37873
|
-
|
|
37874
|
-
_positionId,
|
|
37875
|
-
`LIT Action failed: ${errorMessage}`
|
|
37876
|
-
),
|
|
37877
|
-
this.config.telegram.threadId
|
|
37878
|
-
);
|
|
37879
|
-
} catch (e) {
|
|
37880
|
-
}
|
|
38066
|
+
try {
|
|
38067
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(
|
|
38068
|
+
_positionId,
|
|
38069
|
+
`LIT Action failed: ${errorMessage}`
|
|
38070
|
+
));
|
|
38071
|
+
} catch (e) {
|
|
37881
38072
|
}
|
|
37882
38073
|
throw litError;
|
|
37883
38074
|
}
|
|
@@ -37887,31 +38078,17 @@ Error data: ${errorData || "none"}`
|
|
|
37887
38078
|
if (!litActionResult.approved) {
|
|
37888
38079
|
const reason = litActionResult.reason ?? litActionResult.error ?? "Extension not approved";
|
|
37889
38080
|
const errorMessage = `Extension not approved: ${reason}`;
|
|
37890
|
-
|
|
37891
|
-
|
|
37892
|
-
|
|
37893
|
-
this.config.telegram.chatId,
|
|
37894
|
-
this.config.telegram.chatToken,
|
|
37895
|
-
formatLoanRenewalFailureMessage(_positionId, errorMessage),
|
|
37896
|
-
this.config.telegram.threadId
|
|
37897
|
-
);
|
|
37898
|
-
} catch (e) {
|
|
37899
|
-
}
|
|
38081
|
+
try {
|
|
38082
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(_positionId, errorMessage));
|
|
38083
|
+
} catch (e) {
|
|
37900
38084
|
}
|
|
37901
38085
|
throw new Error(errorMessage);
|
|
37902
38086
|
}
|
|
37903
38087
|
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) {
|
|
37904
38088
|
const errorMessage = "LIT Action result missing required fields: signature, btcPrice, availableBTCBalance, quantumTimestamp, proRataRenewalFee";
|
|
37905
|
-
|
|
37906
|
-
|
|
37907
|
-
|
|
37908
|
-
this.config.telegram.chatId,
|
|
37909
|
-
this.config.telegram.chatToken,
|
|
37910
|
-
formatLoanRenewalFailureMessage(_positionId, errorMessage),
|
|
37911
|
-
this.config.telegram.threadId
|
|
37912
|
-
);
|
|
37913
|
-
} catch (e) {
|
|
37914
|
-
}
|
|
38089
|
+
try {
|
|
38090
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(_positionId, errorMessage));
|
|
38091
|
+
} catch (e) {
|
|
37915
38092
|
}
|
|
37916
38093
|
throw new Error(errorMessage);
|
|
37917
38094
|
}
|
|
@@ -37998,66 +38175,38 @@ Error data: ${errorData || "none"}`
|
|
|
37998
38175
|
{ hash: txWithProvider.hash, error: errorMessage }
|
|
37999
38176
|
);
|
|
38000
38177
|
}
|
|
38001
|
-
|
|
38002
|
-
|
|
38003
|
-
|
|
38004
|
-
|
|
38005
|
-
|
|
38006
|
-
|
|
38007
|
-
_positionId,
|
|
38008
|
-
`Transaction confirmation failed: ${errorMessage}`
|
|
38009
|
-
),
|
|
38010
|
-
this.config.telegram.threadId
|
|
38011
|
-
);
|
|
38012
|
-
} catch (e) {
|
|
38013
|
-
}
|
|
38178
|
+
try {
|
|
38179
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(
|
|
38180
|
+
_positionId,
|
|
38181
|
+
`Transaction confirmation failed: ${errorMessage}`
|
|
38182
|
+
));
|
|
38183
|
+
} catch (e) {
|
|
38014
38184
|
}
|
|
38015
38185
|
throw waitError;
|
|
38016
38186
|
}
|
|
38017
38187
|
if (!receipt) {
|
|
38018
38188
|
const error = "Transaction receipt is null - transaction may have failed";
|
|
38019
|
-
|
|
38020
|
-
|
|
38021
|
-
|
|
38022
|
-
this.config.telegram.chatId,
|
|
38023
|
-
this.config.telegram.chatToken,
|
|
38024
|
-
formatLoanRenewalFailureMessage(_positionId, error),
|
|
38025
|
-
this.config.telegram.threadId
|
|
38026
|
-
);
|
|
38027
|
-
} catch (e) {
|
|
38028
|
-
}
|
|
38189
|
+
try {
|
|
38190
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(_positionId, error));
|
|
38191
|
+
} catch (e) {
|
|
38029
38192
|
}
|
|
38030
38193
|
throw new Error(error);
|
|
38031
38194
|
}
|
|
38032
38195
|
if (receipt.status === 0) {
|
|
38033
38196
|
const error = `Transaction reverted (tx: ${receipt.transactionHash})`;
|
|
38034
|
-
|
|
38035
|
-
|
|
38036
|
-
|
|
38037
|
-
this.config.telegram.chatId,
|
|
38038
|
-
this.config.telegram.chatToken,
|
|
38039
|
-
formatLoanRenewalFailureMessage(_positionId, error),
|
|
38040
|
-
this.config.telegram.threadId
|
|
38041
|
-
);
|
|
38042
|
-
} catch (e) {
|
|
38043
|
-
}
|
|
38197
|
+
try {
|
|
38198
|
+
await this._relayNotification(formatLoanRenewalFailureMessage(_positionId, error));
|
|
38199
|
+
} catch (e) {
|
|
38044
38200
|
}
|
|
38045
38201
|
throw new Error(error);
|
|
38046
38202
|
}
|
|
38047
|
-
|
|
38048
|
-
|
|
38049
|
-
|
|
38050
|
-
|
|
38051
|
-
|
|
38052
|
-
|
|
38053
|
-
|
|
38054
|
-
);
|
|
38055
|
-
} catch (e) {
|
|
38056
|
-
if (this.config.debug) {
|
|
38057
|
-
log.warn("Failed to send Telegram notification for extension", {
|
|
38058
|
-
error: e instanceof Error ? e.message : String(e)
|
|
38059
|
-
});
|
|
38060
|
-
}
|
|
38203
|
+
try {
|
|
38204
|
+
await this._relayNotification(formatLoanRenewalMessage(_positionId, receipt.transactionHash));
|
|
38205
|
+
} catch (e) {
|
|
38206
|
+
if (this.config.debug) {
|
|
38207
|
+
log.warn("Failed to send Telegram notification for extension", {
|
|
38208
|
+
error: e instanceof Error ? e.message : String(e)
|
|
38209
|
+
});
|
|
38061
38210
|
}
|
|
38062
38211
|
}
|
|
38063
38212
|
return receipt;
|
|
@@ -38171,16 +38320,9 @@ Error data: ${errorData || "none"}`
|
|
|
38171
38320
|
const initCheck = this.checkInitialized();
|
|
38172
38321
|
if (!initCheck.success) {
|
|
38173
38322
|
const error = `SDK not initialized: ${initCheck.error.message}`;
|
|
38174
|
-
|
|
38175
|
-
|
|
38176
|
-
|
|
38177
|
-
this.config.telegram.chatId,
|
|
38178
|
-
this.config.telegram.chatToken,
|
|
38179
|
-
formatBalanceConfirmationFailureMessage(positionId),
|
|
38180
|
-
this.config.telegram.threadId
|
|
38181
|
-
);
|
|
38182
|
-
} catch (e) {
|
|
38183
|
-
}
|
|
38323
|
+
try {
|
|
38324
|
+
await this._relayNotification(formatBalanceConfirmationFailureMessage(positionId));
|
|
38325
|
+
} catch (e) {
|
|
38184
38326
|
}
|
|
38185
38327
|
return {
|
|
38186
38328
|
success: false,
|
|
@@ -38320,21 +38462,14 @@ Error data: ${errorData || "none"}`
|
|
|
38320
38462
|
gasUsed: receipt.gasUsed.toString()
|
|
38321
38463
|
});
|
|
38322
38464
|
}
|
|
38323
|
-
|
|
38324
|
-
|
|
38325
|
-
|
|
38326
|
-
|
|
38327
|
-
|
|
38328
|
-
|
|
38329
|
-
message
|
|
38330
|
-
|
|
38331
|
-
);
|
|
38332
|
-
} catch (telegramError) {
|
|
38333
|
-
if (this.config.debug) {
|
|
38334
|
-
log.warn("\u26A0\uFE0F Failed to send Telegram notification", {
|
|
38335
|
-
error: telegramError instanceof Error ? telegramError.message : String(telegramError)
|
|
38336
|
-
});
|
|
38337
|
-
}
|
|
38465
|
+
try {
|
|
38466
|
+
const message = formatBalanceConfirmationMessage(positionId);
|
|
38467
|
+
await this._relayNotification(message);
|
|
38468
|
+
} catch (telegramError) {
|
|
38469
|
+
if (this.config.debug) {
|
|
38470
|
+
log.warn("\u26A0\uFE0F Failed to send Telegram notification", {
|
|
38471
|
+
error: telegramError instanceof Error ? telegramError.message : String(telegramError)
|
|
38472
|
+
});
|
|
38338
38473
|
}
|
|
38339
38474
|
}
|
|
38340
38475
|
return {
|
|
@@ -38357,17 +38492,10 @@ Error data: ${errorData || "none"}`
|
|
|
38357
38492
|
positionId
|
|
38358
38493
|
});
|
|
38359
38494
|
}
|
|
38360
|
-
|
|
38361
|
-
|
|
38362
|
-
|
|
38363
|
-
|
|
38364
|
-
this.config.telegram.chatId,
|
|
38365
|
-
this.config.telegram.chatToken,
|
|
38366
|
-
message,
|
|
38367
|
-
this.config.telegram.threadId
|
|
38368
|
-
);
|
|
38369
|
-
} catch (telegramError) {
|
|
38370
|
-
}
|
|
38495
|
+
try {
|
|
38496
|
+
const message = formatBalanceConfirmationFailureMessage(positionId);
|
|
38497
|
+
await this._relayNotification(message);
|
|
38498
|
+
} catch (telegramError) {
|
|
38371
38499
|
}
|
|
38372
38500
|
return {
|
|
38373
38501
|
success: false,
|
|
@@ -38916,17 +39044,12 @@ Error data: ${errorData || "none"}`
|
|
|
38916
39044
|
}
|
|
38917
39045
|
if (receipt.status === 0) {
|
|
38918
39046
|
try {
|
|
38919
|
-
if (
|
|
39047
|
+
if (tx.hash) {
|
|
38920
39048
|
const message = formatPartialPaymentFailureMessage(
|
|
38921
39049
|
request.paymentAmount,
|
|
38922
39050
|
request.positionId
|
|
38923
39051
|
);
|
|
38924
|
-
await
|
|
38925
|
-
this.config.telegram.chatId,
|
|
38926
|
-
this.config.telegram.chatToken,
|
|
38927
|
-
message,
|
|
38928
|
-
this.config.telegram.threadId
|
|
38929
|
-
);
|
|
39052
|
+
await this._relayNotification(message);
|
|
38930
39053
|
}
|
|
38931
39054
|
} catch (telegramError) {
|
|
38932
39055
|
if (this.config.debug) {
|
|
@@ -38948,18 +39071,13 @@ Error data: ${errorData || "none"}`
|
|
|
38948
39071
|
log.info(`\u2705 Transaction confirmed in block ${receipt.blockNumber}`);
|
|
38949
39072
|
}
|
|
38950
39073
|
try {
|
|
38951
|
-
if (
|
|
39074
|
+
if (tx.hash) {
|
|
38952
39075
|
const message = formatPartialPaymentMessage(
|
|
38953
39076
|
request.paymentAmount,
|
|
38954
39077
|
request.positionId,
|
|
38955
39078
|
tx.hash
|
|
38956
39079
|
);
|
|
38957
|
-
await
|
|
38958
|
-
this.config.telegram.chatId,
|
|
38959
|
-
this.config.telegram.chatToken,
|
|
38960
|
-
message,
|
|
38961
|
-
this.config.telegram.threadId
|
|
38962
|
-
);
|
|
39080
|
+
await this._relayNotification(message);
|
|
38963
39081
|
}
|
|
38964
39082
|
} catch (telegramError) {
|
|
38965
39083
|
if (this.config.debug) {
|
|
@@ -39013,19 +39131,12 @@ Error data: ${errorData || "none"}`
|
|
|
39013
39131
|
});
|
|
39014
39132
|
}
|
|
39015
39133
|
try {
|
|
39016
|
-
|
|
39017
|
-
|
|
39018
|
-
|
|
39019
|
-
|
|
39020
|
-
|
|
39021
|
-
|
|
39022
|
-
await sendTelegramMessage(
|
|
39023
|
-
this.config.telegram.chatId,
|
|
39024
|
-
this.config.telegram.chatToken,
|
|
39025
|
-
message,
|
|
39026
|
-
this.config.telegram.threadId
|
|
39027
|
-
);
|
|
39028
|
-
}
|
|
39134
|
+
const message = formatPartialPaymentFailureMessage(
|
|
39135
|
+
request.paymentAmount,
|
|
39136
|
+
request.positionId,
|
|
39137
|
+
transactionHash
|
|
39138
|
+
);
|
|
39139
|
+
await this._relayNotification(message);
|
|
39029
39140
|
} catch (telegramError) {
|
|
39030
39141
|
if (this.config.debug) {
|
|
39031
39142
|
log.warn("\u26A0\uFE0F Failed to send Telegram failure notification", {
|
|
@@ -39341,22 +39452,15 @@ Error data: ${errorData || "none"}`
|
|
|
39341
39452
|
});
|
|
39342
39453
|
}
|
|
39343
39454
|
try {
|
|
39344
|
-
|
|
39345
|
-
|
|
39346
|
-
|
|
39347
|
-
|
|
39348
|
-
|
|
39349
|
-
|
|
39350
|
-
|
|
39351
|
-
|
|
39352
|
-
|
|
39353
|
-
await sendTelegramMessage(
|
|
39354
|
-
this.config.telegram.chatId,
|
|
39355
|
-
this.config.telegram.chatToken,
|
|
39356
|
-
message,
|
|
39357
|
-
this.config.telegram.threadId
|
|
39358
|
-
);
|
|
39359
|
-
}
|
|
39455
|
+
const position2 = await this.getPosition(positionId);
|
|
39456
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39457
|
+
const message = formatBTCWithdrawalFailureMessage(
|
|
39458
|
+
btcAmount,
|
|
39459
|
+
position2?.vaultAddress || "unknown",
|
|
39460
|
+
withdrawalAddress,
|
|
39461
|
+
positionId
|
|
39462
|
+
);
|
|
39463
|
+
await this._relayNotification(message);
|
|
39360
39464
|
} catch (telegramError) {
|
|
39361
39465
|
console.error(
|
|
39362
39466
|
"Telegram notification failed:",
|
|
@@ -39388,22 +39492,15 @@ Error data: ${errorData || "none"}`
|
|
|
39388
39492
|
});
|
|
39389
39493
|
}
|
|
39390
39494
|
try {
|
|
39391
|
-
|
|
39392
|
-
|
|
39393
|
-
|
|
39394
|
-
|
|
39395
|
-
|
|
39396
|
-
|
|
39397
|
-
|
|
39398
|
-
|
|
39399
|
-
|
|
39400
|
-
await sendTelegramMessage(
|
|
39401
|
-
this.config.telegram.chatId,
|
|
39402
|
-
this.config.telegram.chatToken,
|
|
39403
|
-
message,
|
|
39404
|
-
this.config.telegram.threadId
|
|
39405
|
-
);
|
|
39406
|
-
}
|
|
39495
|
+
const position = await this.getPosition(positionId);
|
|
39496
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39497
|
+
const message = formatBTCWithdrawalFailureMessage(
|
|
39498
|
+
btcAmount,
|
|
39499
|
+
position?.vaultAddress || "unknown",
|
|
39500
|
+
withdrawalAddress,
|
|
39501
|
+
positionId
|
|
39502
|
+
);
|
|
39503
|
+
await this._relayNotification(message);
|
|
39407
39504
|
} catch (telegramError) {
|
|
39408
39505
|
console.error(
|
|
39409
39506
|
"Telegram notification failed:",
|
|
@@ -39557,22 +39654,15 @@ Error data: ${errorData || "none"}`
|
|
|
39557
39654
|
});
|
|
39558
39655
|
}
|
|
39559
39656
|
try {
|
|
39560
|
-
|
|
39561
|
-
|
|
39562
|
-
|
|
39563
|
-
|
|
39564
|
-
|
|
39565
|
-
|
|
39566
|
-
|
|
39567
|
-
|
|
39568
|
-
|
|
39569
|
-
await sendTelegramMessage(
|
|
39570
|
-
this.config.telegram.chatId,
|
|
39571
|
-
this.config.telegram.chatToken,
|
|
39572
|
-
message,
|
|
39573
|
-
this.config.telegram.threadId
|
|
39574
|
-
);
|
|
39575
|
-
}
|
|
39657
|
+
const position = await this.getPosition(positionId);
|
|
39658
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39659
|
+
const message = formatBTCWithdrawalFailureMessage(
|
|
39660
|
+
btcAmount,
|
|
39661
|
+
position?.vaultAddress || "unknown",
|
|
39662
|
+
withdrawalAddress,
|
|
39663
|
+
positionId
|
|
39664
|
+
);
|
|
39665
|
+
await this._relayNotification(message);
|
|
39576
39666
|
} catch (telegramError) {
|
|
39577
39667
|
console.error(
|
|
39578
39668
|
"Telegram notification failed:",
|
|
@@ -39612,22 +39702,15 @@ Error data: ${errorData || "none"}`
|
|
|
39612
39702
|
});
|
|
39613
39703
|
}
|
|
39614
39704
|
try {
|
|
39615
|
-
|
|
39616
|
-
|
|
39617
|
-
|
|
39618
|
-
|
|
39619
|
-
|
|
39620
|
-
|
|
39621
|
-
|
|
39622
|
-
|
|
39623
|
-
|
|
39624
|
-
await sendTelegramMessage(
|
|
39625
|
-
this.config.telegram.chatId,
|
|
39626
|
-
this.config.telegram.chatToken,
|
|
39627
|
-
message,
|
|
39628
|
-
this.config.telegram.threadId
|
|
39629
|
-
);
|
|
39630
|
-
}
|
|
39705
|
+
const position = await this.getPosition(positionId);
|
|
39706
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39707
|
+
const message = formatBTCWithdrawalSuccessMessage(
|
|
39708
|
+
btcAmount,
|
|
39709
|
+
position?.vaultAddress || "unknown",
|
|
39710
|
+
validationResponse.destinationAddress,
|
|
39711
|
+
positionId
|
|
39712
|
+
);
|
|
39713
|
+
await this._relayNotification(message);
|
|
39631
39714
|
} catch (telegramError) {
|
|
39632
39715
|
console.error(
|
|
39633
39716
|
"Telegram notification failed:",
|
|
@@ -39653,22 +39736,15 @@ Error data: ${errorData || "none"}`
|
|
|
39653
39736
|
});
|
|
39654
39737
|
}
|
|
39655
39738
|
try {
|
|
39656
|
-
|
|
39657
|
-
|
|
39658
|
-
|
|
39659
|
-
|
|
39660
|
-
|
|
39661
|
-
|
|
39662
|
-
|
|
39663
|
-
|
|
39664
|
-
|
|
39665
|
-
await sendTelegramMessage(
|
|
39666
|
-
this.config.telegram.chatId,
|
|
39667
|
-
this.config.telegram.chatToken,
|
|
39668
|
-
message,
|
|
39669
|
-
this.config.telegram.threadId
|
|
39670
|
-
);
|
|
39671
|
-
}
|
|
39739
|
+
const position = await this.getPosition(positionId);
|
|
39740
|
+
const btcAmount = (Number(withdrawalAmount) / 1e8).toFixed(8);
|
|
39741
|
+
const message = formatBTCWithdrawalFailureMessage(
|
|
39742
|
+
btcAmount,
|
|
39743
|
+
position?.vaultAddress || "unknown",
|
|
39744
|
+
withdrawalAddress,
|
|
39745
|
+
positionId
|
|
39746
|
+
);
|
|
39747
|
+
await this._relayNotification(message);
|
|
39672
39748
|
} catch (telegramError) {
|
|
39673
39749
|
console.error(
|
|
39674
39750
|
"Telegram notification failed:",
|
|
@@ -39732,7 +39808,34 @@ Error data: ${errorData || "none"}`
|
|
|
39732
39808
|
const bitcoinNetwork = this.getBitcoinNetwork();
|
|
39733
39809
|
const mode = chainId === 1337 || chainId === 31337 || bitcoinNetwork === "regtest" ? "dev" : "prod";
|
|
39734
39810
|
const bitcoin = await import("bitcoinjs-lib");
|
|
39735
|
-
const
|
|
39811
|
+
const encodeBitcoinVarInt = (value) => {
|
|
39812
|
+
if (value < 253) {
|
|
39813
|
+
return Buffer.from([value]);
|
|
39814
|
+
}
|
|
39815
|
+
if (value <= 65535) {
|
|
39816
|
+
const buf2 = Buffer.allocUnsafe(3);
|
|
39817
|
+
buf2[0] = 253;
|
|
39818
|
+
buf2.writeUInt16LE(value, 1);
|
|
39819
|
+
return buf2;
|
|
39820
|
+
}
|
|
39821
|
+
if (value <= 4294967295) {
|
|
39822
|
+
const buf2 = Buffer.allocUnsafe(5);
|
|
39823
|
+
buf2[0] = 254;
|
|
39824
|
+
buf2.writeUInt32LE(value, 1);
|
|
39825
|
+
return buf2;
|
|
39826
|
+
}
|
|
39827
|
+
const buf = Buffer.allocUnsafe(9);
|
|
39828
|
+
buf[0] = 255;
|
|
39829
|
+
buf.writeBigUInt64LE(BigInt(value), 1);
|
|
39830
|
+
return buf;
|
|
39831
|
+
};
|
|
39832
|
+
const witnessStackToScriptWitness = (witness) => {
|
|
39833
|
+
const serializedChunks = [encodeBitcoinVarInt(witness.length)];
|
|
39834
|
+
for (const item of witness) {
|
|
39835
|
+
serializedChunks.push(encodeBitcoinVarInt(item.length), item);
|
|
39836
|
+
}
|
|
39837
|
+
return Buffer.concat(serializedChunks);
|
|
39838
|
+
};
|
|
39736
39839
|
const networks2 = bitcoinNetwork === "mainnet" ? bitcoin.networks.bitcoin : bitcoinNetwork === "regtest" ? bitcoin.networks.regtest : bitcoin.networks.testnet;
|
|
39737
39840
|
if (this.config.debug) {
|
|
39738
39841
|
log.info("\u{1F4CB} Network configuration", {
|