@gvnrdao/dh-lit-actions 0.0.282 → 0.0.284

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.
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 1418,
5
5
  "compressionRatio": 0.4642992066490367,
6
6
  "hash": "b66a469b07b3ba5d753ff8726775188d32450b3e6a77b91404c8d5e8114be9e8",
7
- "buildTime": 1777471360424,
7
+ "buildTime": 1777481711131,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 856,
5
5
  "compressionRatio": 0.4751686082158185,
6
6
  "hash": "bc0bcb38452275c93fa74c5240ae496d7a3eef9d38e7fb0dd99c5202c554d5e3",
7
- "buildTime": 1777471360433,
7
+ "buildTime": 1777481711142,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 51556,
5
5
  "compressionRatio": 0.564037950920868,
6
6
  "hash": "8eb26b08623d6be2ded733579d61c389fe312eef8d12ae1e62166c9359bbd037",
7
- "buildTime": 1777471360708,
7
+ "buildTime": 1777481711393,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 4143,
5
5
  "compressionRatio": 0.5279170464904284,
6
6
  "hash": "25007f80b4ed3169470bf617d403971136be431eb29dfb09f78afe2494bf0138",
7
- "buildTime": 1777471360741,
7
+ "buildTime": 1777481711417,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 1695,
5
5
  "compressionRatio": 0.46292775665399244,
6
6
  "hash": "def4576ba6c382d145f996c4f950b5e39e58792415ee7fdd749e0d2bc61e8f0b",
7
- "buildTime": 1777471360753,
7
+ "buildTime": 1777481711428,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 2026,
5
5
  "compressionRatio": 0.48197391971362824,
6
6
  "hash": "349d51aa096d56b394f82de75ed34cd4eef72719969f7e5fe584f4582b2745fa",
7
- "buildTime": 1777471360777,
7
+ "buildTime": 1777481711442,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 25657,
5
5
  "compressionRatio": 0.5613213192675295,
6
6
  "hash": "422311d10447a806bf435a1df440ff00d4eee986c019ccdb4af15bdbfd8019cf",
7
- "buildTime": 1777471360994,
7
+ "buildTime": 1777481711567,
8
8
  "version": "0.1.0"
9
9
  }
@@ -1 +1 @@
1
- var _LIT_ACTION_=(()=>{var t=Object.defineProperty,e=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,i={};((e,r)=>{for(var o in r)t(e,o,{get:r[o],enumerable:!0})})(i,{main:()=>main});var a=11e3,n=100000000n,s=1000000000000000000n,c=1000000000000n,l=100000000000000n,u=546n,d=3,h=500,p=100,g=8e3;function m(t){switch(t){case 0:return"PENDING_DEPOSIT";case 1:return"PENDING_MINT";case 2:return"ACTIVE";case 3:return"EXPIRED";case 4:return"LIQUIDATABLE";case 5:return"LIQUIDATED";case 6:return"REPAID";case 7:return"CLOSED";default:return`UNKNOWN(${t})`}}var w="DiamondHands.Protocol",f="1",y=(t=>(t.SEPOLIA="sepolia",t.ETHEREUM="ethereum",t.HARDHAT="hardhat",t))(y||{}),b={sepolia:"testnet",ethereum:"mainnet",hardhat:"regtest"},T=["infura.io","drpc.org"],v={ethereum:1,sepolia:11155111,hardhat:1337};function S(t){const e=t.toLowerCase().trim();if("sepolia"===e)return"sepolia";if("ethereum"===e||"mainnet"===e)return"ethereum";if("hardhat"===e)return"hardhat";throw new Error(`Unsupported EVM chain: "${t}". Supported chains: ${Object.values(y).join(", ")}`)}function P(t){return v[t]}function E(t){return Math.floor(t/p)*p}async function $(){const t=Math.floor(Date.now()/1e3),e=t%p;if(!function(t){const e=(t??Math.floor(Date.now()/1e3))%p;return e<8||e>=92}(t))return;let r;r=e>=92?p-e+8:8-e,console.log(`[Quantum] Waiting ${r}s for safe moment (current time in quantum: ${e}s)`),await new Promise((t=>setTimeout(t,1e3*r))),console.log(`[Quantum] Safe quantum ready: ${E(Math.floor(Date.now()/1e3))}`)}var A=class t{static verifyAmountPositionActionAuthorizationStructure(t){if(!t||"object"!=typeof t)throw new Error('Missing or invalid "auth" parameter - must be an object');if(!t.positionId)throw new Error("auth.positionId is required");if("number"!=typeof t.chainId)throw new Error("auth.chainId must be a number");if("number"!=typeof t.timestamp)throw new Error("auth.timestamp must be a number");if(void 0===t.amount||null===t.amount)throw new Error("auth.amount is required");if(!t.action)throw new Error("auth.action is required");if(!t.signature)throw new Error("auth.signature is required");return t}static async recoverSigner(t,e){try{const r=ethers.utils.arrayify(t),o=ethers.utils.hashMessage(r);return ethers.utils.recoverAddress(o,e)}catch(t){throw new Error(`Failed to recover signer: ${t instanceof Error?t.message:String(t)}`)}}static async checkEIP1271(t,e,r,o){try{const i=new ethers.Contract(t,["function isValidSignature(bytes32,bytes) view returns (bytes4)"],o);return"0x1626ba7e"===await i.isValidSignature(e,r)}catch{return!1}}static async verifyActionAuthorization(t,e,r,o){const i=Math.floor(Date.now()/1e3);await $();const a=o?.strictCurrentQuantum?i:void 0;try{!function(t,e,r){const o=e??Math.floor(Date.now()/1e3),i=E(o),a=E(t);if(r?.strictCurrentQuantum){if(a!==i)throw new Error(`[Quantum] Signature must come from current quantum (strict mode). Signature quantum: ${a}, current quantum: ${i}`);return}const n=i-p,s=i+p;if(a!==n&&a!==i&&a!==s)throw new Error(`[Quantum] Signature outside 3-quantum window. Signature quantum: ${a}, Valid range: [${n} (past), ${i} (current), ${s} (next)]`);if(a===n){if(o<n+8)throw new Error(`[Quantum] Dead zone violation: Current time (${o}) is in first 8 seconds of PAST quantum (${n}). This is unsafe due to boundary instability.`)}else if(a===s&&o>=s+92)throw new Error(`[Quantum] Dead zone violation: Current time (${o}) is in last 8 seconds of NEXT quantum (${s}). This is unsafe due to boundary instability.`)}(t.timestamp,a,{strictCurrentQuantum:!0===o?.strictCurrentQuantum})}catch{return!1}const n=e(),s=await this.recoverSigner(n,t.signature);return await r(s,n,t.signature)}static async verifyAmountPositionActionAuthorization(e,r,o){return this.verifyActionAuthorization(e,(()=>{const t=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(e.action)),r="string"==typeof e.amount?BigInt(e.amount):e.amount,o=[e.positionId,e.timestamp,e.chainId,r.toString(),t];return ethers.utils.solidityKeccak256(["bytes32","uint256","uint256","uint256","bytes32"],o)}),(async(e,i,a)=>e.toLowerCase()===r.toLowerCase()||!!o&&t.checkEIP1271(r,i,a,o)))}static async verifyMintAuthorization(t,e,r){return"mint-ucd"===t.action&&this.verifyAmountPositionActionAuthorization(t,e,r)}static async verifyWithdrawAuthorization(e,r,o){if("withdraw-btc"!==e.action)return!1;return this.verifyActionAuthorization(e,(()=>{const t=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(e.action)),r="string"==typeof e.amount?BigInt(e.amount):e.amount,o=[e.positionId,e.timestamp,e.chainId,r.toString(),e.destinationAddress,t];return ethers.utils.solidityKeccak256(["bytes32","uint256","uint256","uint256","string","bytes32"],o)}),(async(e,i,a)=>e.toLowerCase()===r.toLowerCase()||!!o&&t.checkEIP1271(r,i,a,o)))}static verifyTermPositionActionAuthorizationStructure(t){if(!t||"object"!=typeof t)throw new Error('Missing or invalid "auth" parameter - must be an object');if(!t.positionId)throw new Error("auth.positionId is required");if("number"!=typeof t.chainId)throw new Error("auth.chainId must be a number");if("number"!=typeof t.timestamp)throw new Error("auth.timestamp must be a number");if(void 0===t.newTerm||null===t.newTerm)throw new Error("auth.newTerm is required");if("number"!=typeof t.newTerm)throw new Error("auth.newTerm must be a number");if(!t.action)throw new Error("auth.action is required");if(!t.signature)throw new Error("auth.signature is required");return t}static async verifyTermPositionActionAuthorization(e,r,o){return this.verifyActionAuthorization(e,(()=>{const t=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(e.action)),r=[e.positionId,e.timestamp,e.chainId,e.newTerm,t];return ethers.utils.solidityKeccak256(["bytes32","uint256","uint256","uint256","bytes32"],r)}),(async(e,i,a)=>e.toLowerCase()===r.toLowerCase()||!!o&&t.checkEIP1271(r,i,a,o)))}static async verifyExtendAuthorization(t,e,r){return"extend-position"===t.action&&this.verifyTermPositionActionAuthorization(t,e,r)}static async verifyBtcExecutionAuthorization(e,r,o){if("execute-btc-withdrawal"!==e.action)return!1;return this.verifyActionAuthorization(e,(()=>{const t=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(e.action)),r=[e.positionId,e.timestamp,e.chainId,e.utxoIdentifier,e.networkFee,t];return ethers.utils.solidityKeccak256(["bytes32","uint256","uint256","string","uint256","bytes32"],r)}),(async(e,i,a)=>e.toLowerCase()===r.toLowerCase()||!!o&&t.checkEIP1271(r,i,a,o)),{strictCurrentQuantum:!0})}};function I(t){if(!0===t)return!0;if(!1===t)return!1;const e=globalThis;return!0===e.debugAction||(!0===e.LIT_ACTION_DEBUG||("true"===e.LIT_ACTION_DEBUG||function(){try{if("undefined"==typeof process||!process.env)return!1;const t=process.env.LIT_ACTION_DEBUG,e=process.env.DEBUG;return"1"===t||"true"===t||"1"===e||"true"===e}catch{return!1}}()))}function C(...t){I()&&console.log(...t)}var B=class{stepStart(t,e){}stepEnd(t,e){}log(t,e,...r){}warn(t,e){}error(t,e){}getElapsed(){return 0}getRemaining(){return 3e4}summary(){}getExecutionId(){return""}isDebugEnabled(){return!1}},U=class{constructor(t){this.stepStartTimes=new Map,this.stepDurations=new Map,this.TIMEOUT_MS=3e4,this.actionName=t,this.executionStartTime=Date.now();const e=Date.now(),r=Math.random().toString(36).substring(2,9);this.executionId=`exec_${e}_${r}`,this.logHeader()}logHeader(){console.log(`[${this.actionName}] ========================================`),console.log(`[${this.actionName}] Execution started`),console.log(`[${this.actionName}] Execution ID: ${this.executionId}`);void 0!==globalThis.litNodeContext?(console.log(`[${this.actionName}] Context: LIT Node`),console.log(`[${this.actionName}] Node: ${globalThis.litNodeContext?.nodeAddress||"unknown"}`)):console.log(`[${this.actionName}] Context: Browser/Test`),console.log(`[${this.actionName}] ========================================`)}stepStart(t,e){this.stepStartTimes.set(t,Date.now());const r=Date.now()-this.executionStartTime,o=this.TIMEOUT_MS-r;console.log(`[Step ${t}] ${e}...`),console.log(`[Step ${t}] Elapsed: ${r}ms | Remaining: ${o}ms`)}stepEnd(t,e=5e3){const r=this.stepStartTimes.get(t);if(!r)return console.warn(`[Step ${t}] \u26a0\ufe0f stepEnd called without matching stepStart`),void 0;const o=Date.now()-r;this.stepDurations.set(t,o),console.log(`[Step ${t}] Duration: ${o}ms`),o>e&&console.warn(`\u26a0\ufe0f [Step ${t}] Took ${o}ms (> ${e}ms threshold)`);const i=Date.now()-this.executionStartTime,a=this.TIMEOUT_MS-i;a<5e3&&console.warn(`\u26a0\ufe0f [Step ${t}] Time remaining: ${a}ms (approaching timeout)`)}log(t,e,...r){r.length>0?console.log(`[Step ${t}] ${e}`,...r):console.log(`[Step ${t}] ${e}`)}warn(t,e){console.warn(`\u26a0\ufe0f [Step ${t}] ${e}`)}error(t,e){console.error(`\u274c [Step ${t}] ${e}`)}getElapsed(){return Date.now()-this.executionStartTime}getRemaining(){return this.TIMEOUT_MS-this.getElapsed()}summary(){const t=Date.now()-this.executionStartTime,e=this.TIMEOUT_MS-t;if(console.log(`[${this.actionName}] ========================================`),console.log(`[${this.actionName}] Execution Summary`),console.log(`[${this.actionName}] Execution ID: ${this.executionId}`),console.log(`[${this.actionName}] Total time: ${(t/1e3).toFixed(2)}s`),console.log(`[${this.actionName}] Time remaining: ${e}ms`),this.stepDurations.size>0){console.log(`[${this.actionName}] Step breakdown:`);for(const[e,r]of this.stepDurations.entries()){const o=(r/t*100).toFixed(1);console.log(`[${this.actionName}] Step ${e}: ${r}ms (${o}%)`)}}t>2e4&&console.warn(`\u26a0\ufe0f [${this.actionName}] Slow execution: ${(t/1e3).toFixed(2)}s (${e}ms remaining)`),e<5e3&&console.warn(`\u26a0\ufe0f [${this.actionName}] CRITICAL: Only ${e}ms remaining before timeout!`),console.log(`[${this.actionName}] ========================================`)}getExecutionId(){return this.executionId}isDebugEnabled(){return!0}},M=class{static create(t="LIT Action",e){return I(e)?new U(t):new B}};function x(){const t=globalThis,e=t.jsParams;return null==e||"object"!=typeof e||Array.isArray(e)?t:e}function D(t){if(t instanceof Error)return t.message;if("string"==typeof t)return t;try{return JSON.stringify(t)}catch{return String(t)}}function O(t){return t instanceof Error&&"AbortError"===t.name}var k=class{constructor(t){this.config=t,this.timeout=t.timeout||15e3,this.logger=M.create("BitcoinDataProvider")}async getCurrentBlockHeight(){if(this.logger.stepStart("0","getCurrentBlockHeight"),this.config.rpcHelper){const t=await this.config.rpcHelper.getBlockCount();return this.logger.stepEnd("0"),t}const t=new AbortController,e=setTimeout((()=>t.abort()),this.timeout);try{const r=Date.now(),o=await fetch(`${this.config.providerUrl}/blocks/tip/height`,{signal:t.signal,headers:{Accept:"text/plain","User-Agent":"Mozilla/5.0 (compatible; DiamondHandsValidator/1.0)","ngrok-skip-browser-warning":"true"}});if(clearTimeout(e),C(`[BitcoinDataProvider] blocks/tip/height ${Date.now()-r}ms (timeout budget ${this.timeout}ms)`),!o.ok)throw new Error(`Failed to fetch block height: ${o.status} ${o.statusText}`);const i=await o.text();if(i.trim().startsWith("<!DOCTYPE")||i.trim().startsWith("<html"))throw new Error("Bitcoin RPC endpoint returned HTML instead of block height. URL may be pointing to web interface instead of API endpoint. Expected: plain text number, Got: HTML document. Check that URL ends with /api/esplora (not root /)");const a=parseInt(i.trim(),10);if(isNaN(a)){const t=i.length>200?i.substring(0,200)+"... (truncated)":i;throw new Error(`Invalid block height response: ${t}`)}return this.logger.stepEnd("0"),a}catch(t){if(clearTimeout(e),this.logger.stepEnd("0"),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);throw t}}async getUTXOs(t){this.logger.log("0",`Original address: "${t}"`);const e=this.stripNetworkPrefix(t);if(this.logger.log("0",`Cleaned address: "${e}"`),this.config.rpcHelper)return await this.fetchUTXOsFromRPC(e);try{return await this.fetchUTXOsFromProvider(this.config.providerUrl,e)}catch(t){if(this.logger.warn("0",`Primary provider failed: ${D(t)}`),this.config.fallbackProviders&&this.config.fallbackProviders.length>0){const t=[...this.config.fallbackProviders].sort(((t,e)=>t.priority-e.priority));for(const r of t)try{return this.logger.log("0",`Trying fallback: ${r.name} (${r.url})`),await this.fetchUTXOsFromProvider(r.url,e)}catch(t){this.logger.warn("0",`Fallback ${r.name} failed: ${D(t)}`);continue}}throw new Error(`Failed to fetch UTXOs: ${D(t)}`)}}stripNetworkPrefix(t){return t.replace(/^(REGTEST_|TESTNET_|MAINNET_)/,"")}async fetchUTXOsFromRPC(t){if(!this.config.rpcHelper)throw new Error("RPC helper not configured");const e=this.config.rpcWallet||"";return(await this.config.rpcHelper.listUnspent(e,t)).map((t=>({txid:t.txid,vout:t.vout,satoshis:BigInt(Math.round(1e8*t.amount)),confirmations:t.confirmations})))}parseBlockstreamUTXOs(t,e){if(!Array.isArray(t))throw new Error("Invalid Blockstream response format: expected an array");const r=t,o=[];for(const t of r){let r=0;t.status&&"object"==typeof t.status?t.status.confirmed&&(r=void 0!==t.status.block_height&&t.status.block_height>0?e-t.status.block_height+1:1):void 0!==t.confirmations&&(r=t.confirmations);const i=t.txid,a=void 0!==t.vout?t.vout:t.n,n=void 0!==t.value?t.value:t.satoshis;if(void 0===i||void 0===a||void 0===n)throw new Error("Invalid UTXO row: missing txid, vout/n, or value/satoshis");o.push({txid:i,vout:a,satoshis:BigInt(n),confirmations:r})}return o}async fetchUTXOsFromProvider(t,e){this.logger.stepStart("1","fetchUTXOsFromProvider");const r=`${t}/address/${e}/utxos`;this.logger.log("1",`Fetching UTXOs from ${r}`);const o=new AbortController,i=setTimeout((()=>o.abort()),this.timeout);try{const t=Date.now(),[a,n]=await Promise.all([this.getCurrentBlockHeight(),fetch(r,{signal:o.signal,headers:{Accept:"application/json","Content-Type":"application/json","User-Agent":"Mozilla/5.0 (compatible; DiamondHandsValidator/1.0)","ngrok-skip-browser-warning":"true"}})]);if(clearTimeout(i),C(`[BitcoinDataProvider] parallel(tipHeight + GET utxos) wall ${Date.now()-t}ms endpoint tail .../${e.slice(0,12)}.../utxos (timeout budget ${this.timeout}ms)`),this.logger.log("1",`Current block height: ${a}`),!n.ok)throw new Error(`Bitcoin provider error: ${n.status} ${n.statusText}`);const s=await n.text();if(s.trim().startsWith("<!DOCTYPE")||s.trim().startsWith("<html"))throw new Error("Bitcoin RPC endpoint returned HTML instead of JSON. URL may be pointing to web interface instead of API endpoint. Expected: JSON array of UTXOs, Got: HTML document. Check that URL ends with /api/esplora (not root /)");let c;try{c=JSON.parse(s)}catch(t){const e=s.length>200?s.substring(0,200)+"... (truncated)":s;throw new Error(`Failed to parse JSON response: ${D(t)}. Response: ${e}`)}this.logger.log("1",`Raw API Response: ${JSON.stringify(c,null,2)}`);const l=this.parseBlockstreamUTXOs(c,a);return this.logger.stepEnd("1"),l}catch(t){if(clearTimeout(i),this.logger.stepEnd("1"),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);throw t}}async getUTXOSet(t,e){let r=[],o=null;const i=d,a=h;for(let e=1;e<=i;e++)try{this.logger.log("2",`UTXO query attempt ${e}/${i}...`),r=await this.getUTXOs(t),this.logger.log("2",`UTXO query succeeded on attempt ${e}`),o=null;break}catch(t){o=t instanceof Error?t:new Error(D(t)),this.logger.error("2",`UTXO query failed on attempt ${e}: ${D(t)}`),e<i&&(this.logger.log("2",`Waiting ${a}ms before retry...`),await new Promise((t=>setTimeout(t,a))))}if(o)throw new Error(`Failed to query UTXOs after ${i} attempts: ${o.message}`);const n=r.reduce(((t,e)=>t+e.satoshis),0n),s=r.filter((t=>t.confirmations>=e)).reduce(((t,e)=>t+e.satoshis),0n),c=n-s;return{utxos:r,totalBalance:n,totalUTXOs:r.length,confirmedBalance:s,unconfirmedBalance:c}}async getBalance(t){const e=this.stripNetworkPrefix(t),r=`${this.config.providerUrl}/address/${e}`;this.logger.log("3",`Fetching balance from ${r}`);const o=new AbortController,i=setTimeout((()=>o.abort()),this.timeout);try{const t=Date.now(),e=await fetch(r,{signal:o.signal,headers:{Accept:"application/json","Content-Type":"application/json","User-Agent":"Mozilla/5.0 (compatible; DiamondHandsValidator/1.0)","ngrok-skip-browser-warning":"true"}});if(clearTimeout(i),C(`[BitcoinDataProvider] GET address chain_stats ${Date.now()-t}ms (timeout budget ${this.timeout}ms)`),!e.ok)throw new Error(`Bitcoin provider error: ${e.status} ${e.statusText}`);const a=await e.json();if(!a.chain_stats)throw new Error("Invalid response: missing chain_stats");const n=a.chain_stats.funded_txo_sum,s=a.chain_stats.spent_txo_sum;if(void 0===n||void 0===s)throw new Error(`Invalid response: missing required fields. funded_txo_sum: ${n}, spent_txo_sum: ${s}`);const c=BigInt(n-s);return this.logger.log("3",`Balance: ${c.toString()} sats`),this.logger.log("3",` - Funded: ${n} sats, Spent: ${s} sats`),c}catch(t){if(clearTimeout(i),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);const r=D(t);throw this.logger.log("3",`Balance fetch failed: ${r}`),new Error(`Failed to fetch Bitcoin balance for address ${e}: ${r}`)}}async getTransaction(t){if(this.config.rpcHelper)try{const e=this.config.rpcWallet||"",r=await this.config.rpcHelper.getTransaction(e,t);return{txid:r.txid,confirmations:r.confirmations||0}}catch(t){const e=D(t),r=null!==t&&"object"==typeof t&&"code"in t&&"number"==typeof t.code?t.code:void 0;if(e.includes("Invalid or non-wallet transaction")||-5===r)return null;throw t}const e=new AbortController,r=setTimeout((()=>e.abort()),this.timeout);try{const o=Date.now(),i=await fetch(`${this.config.providerUrl}/tx/${t}`,{signal:e.signal});if(clearTimeout(r),C(`[BitcoinDataProvider] GET tx/${t.slice(0,10)}\u2026 ${Date.now()-o}ms (timeout budget ${this.timeout}ms)`),!i.ok){if(404===i.status)return null;throw new Error(`Bitcoin provider error: ${i.status} ${i.statusText}`)}const a=await i.json();return a.status?{txid:a.txid??t,confirmations:a.status.confirmed&&a.status.block_height?1:0}:null}catch(t){if(clearTimeout(r),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);if(D(t).includes("404"))return null;throw t}}async getTransactionOutputs(t){if(!this.config.providerUrl)return null;const e=new AbortController,r=setTimeout((()=>e.abort()),this.timeout);try{const o=await fetch(`${this.config.providerUrl}/tx/${t}`,{signal:e.signal});if(clearTimeout(r),!o.ok){if(404===o.status)return null;throw new Error(`Bitcoin provider error: ${o.status} ${o.statusText}`)}const i=await o.json();return i.vout&&Array.isArray(i.vout)?i.vout.map(((t,e)=>({index:e,scriptpubkey:t.scriptpubkey,scriptpubkey_address:t.scriptpubkey_address,value:t.value??0}))):null}catch(t){if(clearTimeout(r),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);throw t}}},N=class t{constructor(e,r,o){if(r&&Array.isArray(r))this.sources=r;else{if(!Array.isArray(e))throw new Error("Price oracle requires a priceProviders array \u2014 defaults and fallbacks have been removed. Pass 3 distinct {name, apiKey} entries from the supported set: "+t.ACTIVE_PROVIDER_NAMES.join(", "));this.sources=this.buildSources(e)}this.sources.sort(((t,e)=>t.priority-e.priority)),this.validateProviderCount()}validateProviderCount(){if(this.sources.length<t.MIN_DISTINCT_PROVIDERS)throw new Error(`Price oracle requires at least ${t.MIN_DISTINCT_PROVIDERS} eligible providers for consensus. Currently configured: ${this.sources.length} provider(s). Supported active providers: ${t.ACTIVE_PROVIDER_NAMES.join(", ")}`)}buildSources(e){if(0===e.length)throw new Error("priceProviders must be a non-empty array of 3 distinct providers, each with an apiKey.");const r=[],o=new Set;let i=1;for(const a of e){if(!a||"string"!=typeof a.name)throw new Error("priceProviders entries must be {name, apiKey, apiSecret?} objects");const e=a.name.toLowerCase();if(!t.ACTIVE_PROVIDER_NAMES.includes(e))throw new Error(`Unsupported price provider "${a.name}". Supported: ${t.ACTIVE_PROVIDER_NAMES.join(", ")}`);if(o.has(e))throw new Error(`Duplicate price provider "${e}" \u2014 the oracle requires 3 DISTINCT providers so a single upstream failure or manipulation cannot compromise consensus. Use 3 different provider names from: ${t.ACTIVE_PROVIDER_NAMES.join(", ")}`);switch(o.add(e),e){case"binance":if(!a.apiKey)throw new Error("Binance provider requires an apiKey");r.push(this.createBinanceSource(a.apiKey,i++));break;case"coinbase":if(!a.apiKey)throw new Error("Coinbase provider requires an apiKey");r.push(this.createCoinbaseSource(a.apiKey,i++));break;case"cryptocompare":if(!a.apiKey)throw new Error("CryptoCompare provider requires an apiKey");r.push(this.createCryptoCompareSource(a.apiKey,i++));break;case"coinmarketcap":if(!a.apiKey)throw new Error("CoinMarketCap provider requires an apiKey");r.push(this.createCoinMarketCapSource(a.apiKey,i++));break;case"coingecko":if(!a.apiKey)throw new Error("CoinGecko provider requires an apiKey (Demo or Pro). Unauthenticated CoinGecko access is not accepted \u2014 the free tier is rate-limited and edge-cached, which breaks median consensus under load.");r.push(this.createCoinGeckoSource(a.apiKey,i++));break;default:throw new Error(`Unhandled provider: ${e}`)}}if(r.length<t.MIN_DISTINCT_PROVIDERS)throw new Error(`Insufficient price providers: need at least ${t.MIN_DISTINCT_PROVIDERS} distinct entries, got ${r.length}.`);return this.selectSampledSources(r)}createCryptoCompareSource(t,e){return{name:"CryptoCompare",fetchPrice:async()=>{const e=new URL("https://min-api.cryptocompare.com/data/price");e.searchParams.set("fsym","BTC"),e.searchParams.set("tsyms","USDT"),e.searchParams.set("api_key",t);const r=await(async t=>{const e=new AbortController,r=setTimeout((()=>e.abort()),5e3);try{const o=await fetch(t,{signal:e.signal,headers:{Accept:"application/json"}});if(clearTimeout(r),!o.ok)throw new Error(`HTTP ${o.status} ${o.statusText}`);return await o.json()}catch(t){if(clearTimeout(r),"AbortError"===t.name)throw new Error("Request timeout after 5000ms");throw t}})(e.toString()),o=Number(r?.USDT);if(!Number.isFinite(o)||o<=0)throw new Error("Invalid CryptoCompare price payload");return o},priority:e}}createFetchJson(){return async(t,e)=>{const r=new AbortController,o=setTimeout((()=>r.abort()),5e3);try{const o=await fetch(t,{headers:{Accept:"application/json",...e||{}},signal:r.signal});if(!o.ok)throw new Error(`HTTP ${o.status} ${o.statusText}`);return await o.json()}finally{clearTimeout(o)}}}getSelectionSeed(){const t="undefined"!=typeof process?process.env.PRICE_PROVIDER_SELECTION_SEED:void 0,e=t?Number(t):NaN;return Number.isFinite(e)?e:("undefined"!=typeof process,0,Math.floor(Date.now()+1e6*Math.random()))}selectSampledSources(t){const e=[...t];let r=this.getSelectionSeed()>>>0;for(let t=e.length-1;t>0;t--){const o=Math.floor((r=1664525*r+1013904223>>>0,r/4294967296*(t+1)));[e[t],e[o]]=[e[o],e[t]]}return e.slice(0,3).map(((t,e)=>({...t,priority:e+1})))}createCoinGeckoSource(t,e){if(!t)throw new Error("createCoinGeckoSource requires an apiKey");const r=this.createFetchJson();return{name:"CoinGecko",fetchPrice:async()=>{const e=t.startsWith("pro:"),o=e?t.slice(4):t,i=e?{"x-cg-pro-api-key":o}:{"x-cg-demo-api-key":o},a=new URL("https://api.coingecko.com/api/v3/simple/price");a.searchParams.set("ids","bitcoin"),a.searchParams.set("vs_currencies","usd");const n=await r(a.toString(),i),s=Number(n?.bitcoin?.usd);if(!Number.isFinite(s)||s<=0)throw new Error("Invalid CoinGecko price payload");return s},priority:e}}createBinanceSource(t,e){if(!t)throw new Error("createBinanceSource requires an apiKey");const r=this.createFetchJson();return{name:"Binance",fetchPrice:async()=>{const e=new URL("https://api.binance.com/api/v3/ticker/price");e.searchParams.set("symbol","BTCUSDT");const o=await r(e.toString(),{"X-MBX-APIKEY":t}),i=Number(o?.price);if(!Number.isFinite(i)||i<=0)throw new Error("Invalid Binance price payload");return i},priority:e}}createCoinbaseSource(t,e){if(!t)throw new Error("createCoinbaseSource requires an apiKey");const r=this.createFetchJson();return{name:"Coinbase",fetchPrice:async()=>{const e=await r("https://api.coinbase.com/v2/prices/BTC-USDT/spot",{"CB-ACCESS-KEY":t}),o=Number(e?.data?.amount);if(!Number.isFinite(o)||o<=0)throw new Error("Invalid Coinbase price payload");return o},priority:e}}createCoinMarketCapSource(t,e){const r=this.createFetchJson();return{name:"CoinMarketCap",fetchPrice:async()=>{const e=new URL("https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest");e.searchParams.set("symbol","BTC"),e.searchParams.set("convert","USDT");const o=await r(e.toString(),{"X-CMC_PRO_API_KEY":t}),i=Number(o?.data?.BTC?.[0]?.quote?.USDT?.price??o?.data?.BTC?.quote?.USDT?.price);if(!Number.isFinite(i)||i<=0)throw new Error("Invalid CoinMarketCap price payload");return i},priority:e}}async getBTCPrice(){const t=Date.now();if(3!==this.sources.length)throw new Error(`Price oracle requires exactly 3 providers. Currently configured: ${this.sources.length}`);const e=new Promise(((t,e)=>{setTimeout((()=>{e(new Error("Price oracle global timeout after 8000ms"))}),8e3)})),r=Promise.all(this.sources.map((async t=>{const e=Date.now(),r=await t.fetchPrice();return console.log(`[Price Oracle] \u2705 [+${Date.now()-e}ms] ${t.name}: $${r.toLocaleString()}`),r}))),o=[...await Promise.race([r,e])].sort(((t,e)=>t-e)),i=o[1];if((o[2]-o[0])/o[0]>.01){const t=this.sources.map((t=>t.name)).join(", "),e=o.map((t=>`$${t.toLocaleString()}`)).join(", ");throw new Error(`Price consensus failed: prices not within 1% tolerance. Providers: [${t}]. Prices: [${e}]`)}const a=Math.round(100*i),n=1000000n*BigInt(a),s=Date.now()-t;return console.log(`[Price Oracle] Median price: $${i.toLocaleString()} \u2014 total time: ${s}ms`),console.log(`[Price Oracle] Price with 8 decimals: ${n}`),n}async getBTCPriceConsensus(){console.log("[Price Oracle] Fetching BTC price with consensus...");const t=(await Promise.allSettled(this.sources.map((async t=>{const e=await t.fetchPrice();return{source:t.name,price:e}})))).filter((t=>"fulfilled"===t.status)).map((t=>t.value));if(0===t.length)throw new Error("No price sources returned data");console.log(`[Price Oracle] Got prices from ${t.length}/${this.sources.length} sources:`),t.forEach((t=>{console.log(` ${t.source}: $${t.price.toLocaleString()}`)}));const e=t.map((t=>t.price));e.sort(((t,e)=>t-e));const r=e[Math.floor(e.length/2)],o=e[0],i=e[e.length-1]/o,a=t.filter((t=>Math.abs(t.price-r)/r<=.02));if(i>1.05&&a.length===t.length)throw new Error(`Price consensus failed: sources too dispersed (${(100*(i-1)).toFixed(1)}% spread)`);if(a.length<t.length){const e=t.filter((t=>!a.find((e=>e.source===t.source))));if(console.log(`[Price Oracle] \u26a0\ufe0f Detected ${e.length} outlier(s):`),e.forEach((t=>{const e=Math.abs(t.price-r)/r;console.log(` ${t.source}: $${t.price.toLocaleString()} (${(100*e).toFixed(1)}% deviation)`)})),a.length<2)throw new Error("Price consensus failed: insufficient valid sources after outlier removal");console.log(`[Price Oracle] \u2705 Outliers filtered, continuing with ${a.length} valid sources`);const o=a.map((t=>t.price));o.sort(((t,e)=>t-e));const i=o[Math.floor(o.length/2)];console.log(`[Price Oracle] \u2705 Consensus price (median): $${i.toLocaleString()}`);const n=Math.round(100*i);return 1000000n*BigInt(n)}console.log(`[Price Oracle] \u2705 Consensus price (median): $${r.toLocaleString()}`);const n=Math.round(100*r);return 1000000n*BigInt(n)}};N.ACTIVE_PROVIDER_NAMES=["cryptocompare","coinbase","binance","coinmarketcap","coingecko"],N.MIN_DISTINCT_PROVIDERS=3;var R=N,q=class{constructor(t){this.config=t,this.bitcoinProvider=t.bitcoinProvider}async calculateBalance(t,e){const r=await this.bitcoinProvider.getBalance(e),o=await this.getAuthorizedSpendsFromContract(t),i=o.reduce(((t,e)=>t+e.satoshis),0n),a=r>i?r-i:0n;return{totalUTXOs:[],totalBalance:r,authorizedUTXOs:o,authorizedBalance:i,authorizedSpendsHash:this.computeAuthorizedSpendsHash(t,o),availableUTXOs:[],availableBalance:a,vaultAddress:e,positionId:t,timestamp:Date.now()}}async calculateTrustedBalance(t,e,r){if(r)return await this.calculateBalance(t,e);const o=this.config.minConfirmations||6,i=await this.bitcoinProvider.getUTXOSet(e,o),a=await this.getAuthorizedSpendsFromContract(t);for(const t of a){if(i.utxos.some((e=>e.txid===t.txid&&e.vout===t.vout)))throw new Error(`Authorized UTXO ${t.txid}:${t.vout} not yet spent. Transaction was authorized in smart contract but not signed and broadcasted to Bitcoin network. Complete the transaction by signing and broadcasting it.`)}const n=a.reduce(((t,e)=>t+e.satoshis),0n),s=i.utxos.filter((t=>!this.isUTXOAuthorized(t,a))),c=s.reduce(((t,e)=>t+e.satoshis),0n),l=this.computeAuthorizedSpendsHash(t,a);return{totalUTXOs:i.utxos,totalBalance:i.totalBalance,authorizedUTXOs:a,authorizedBalance:n,authorizedSpendsHash:l,availableUTXOs:s,availableBalance:c,vaultAddress:e,positionId:t,timestamp:Date.now()}}async getTrustedBalance(t,e){return(await this.calculateTrustedBalance(t,e)).availableBalance}async getAvailableUTXOs(t,e){return(await this.calculateTrustedBalance(t,e)).availableUTXOs}async isUTXOAvailable(t,e,r,o){return(await this.getAvailableUTXOs(t,e)).some((t=>t.txid===r&&t.vout===o))}isUTXOAuthorized(t,e){return e.some((e=>e.txid===t.txid&&e.vout===t.vout))}async getAuthorizedSpendsFromContract(t){const e=t.startsWith("0x")?t:`0x${t.padStart(64,"0")}`;let r;r=this.config.rpcUrl?this.config.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.config.chain});const o=new ethers.providers.StaticJsonRpcProvider({url:r,timeout:g},this.config.chainId),i=new ethers.Contract(this.config.contractAddress,[{inputs:[{internalType:"bytes32",name:"positionId",type:"bytes32"}],name:"getAuthorizedSpends",outputs:[{components:[{internalType:"string",name:"txid",type:"string"},{internalType:"uint32",name:"vout",type:"uint32"},{internalType:"uint256",name:"satoshis",type:"uint256"},{internalType:"string",name:"targetAddress",type:"string"},{internalType:"uint256",name:"targetAmount",type:"uint256"},{internalType:"uint256",name:"authorizedAt",type:"uint256"}],internalType:"struct LoanOperationsManager.AuthorizedSpend[]",name:"",type:"tuple[]"}],stateMutability:"view",type:"function"}],o);return(await i.getAuthorizedSpends(e)).map((e=>({txid:e.txid,vout:Number(e.vout),satoshis:BigInt(e.satoshis.toString()),positionId:t,targetAddress:e.targetAddress,targetAmount:BigInt(e.targetAmount.toString()),timestamp:Number(e.authorizedAt)})))}computeAuthorizedSpendsHash(t,e){const r=t.startsWith("0x")?t:`0x${t.padStart(64,"0")}`;if(0===e.length)return ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["bytes32","bytes32[]"],[r,[]]));const o=e.map((t=>{const e=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(t.txid)),r=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(t.targetAddress));return ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["bytes32","uint32","uint256","bytes32","uint256","uint256"],[e,t.vout,t.satoshis.toString(),r,t.targetAmount.toString(),t.timestamp]))}));return ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["bytes32","bytes32[]"],[r,o]))}};function L(t,e){if(0===t)return{termDurationDays:0,termLengthDays:30*e,isExpired:!1,daysUntilExpiry:30*e,daysIntoGracePeriod:0};const r=30*e,o=Math.floor(Date.now()/1e3)-t,i=Math.floor(o/86400);return{termDurationDays:i,termLengthDays:r,isExpired:i>r,daysUntilExpiry:Math.max(0,r-i),daysIntoGracePeriod:Math.max(0,i-r)}}function F(t,e,r,o){if(!t)return r??13e3;const i=o??a,n=Math.min(e,30);return a+n*n*(i-a)/900}function _(t,e,r){const o=t*e/(100000000n*n);if(0n===r)return{collateralValueUsd:o,collateralRatioBps:Number.MAX_SAFE_INTEGER};return{collateralValueUsd:o,collateralRatioBps:Number(o*s*10000n/r)}}function X(t,e){if(t<0n)throw new Error("BTC amount cannot be negative");if(e<=0n)throw new Error("BTC price must be positive");return t*e/n}function z(t,e){if(t<0n)throw new Error("Collateral value cannot be negative");if(e<=0n)throw new Error("Debt must be positive to calculate ratio");const r=Number(10000n*(10000000000n*t)/e);if(r<0)throw new Error(`Collateral ratio out of bounds: ${r} bps (${r/100}%)`);return!isFinite(r)||r>Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:r}function H(t){return t/100}var V=class{constructor(t){this.termManagerAddress=t.termManagerAddress,this.loanOpsManagerAddress=t.loanOpsManagerAddress,this.liquidationManagerAddress=t.liquidationManagerAddress,this.chain=t.chain,this.chainId=t.chainId,this.rpcUrl=t.rpcUrl}async getLiquidationThreshold(){try{let t;t=this.rpcUrl?this.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.chain});const e=new ethers.providers.StaticJsonRpcProvider({url:t,timeout:g},{name:"any",chainId:this.chainId}),r=[{inputs:[],name:"liquidationThreshold",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"}],o=new ethers.Contract(this.loanOpsManagerAddress,r,e),i=await o.liquidationThreshold();return Number(i.toString())}catch(t){throw console.error("[ProtocolParameters] Error fetching liquidation threshold:",t.message),new Error(`Failed to fetch liquidation threshold: ${t.message}`)}}async getTermFees(t){try{let e;e=this.rpcUrl?this.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.chain});const r=new ethers.providers.StaticJsonRpcProvider({url:e,timeout:g},{name:"any",chainId:this.chainId}),o=[{inputs:[{internalType:"uint256",name:"_termMonths",type:"uint256"}],name:"getTermFees",outputs:[{internalType:"uint88",name:"originationFee",type:"uint88"},{internalType:"uint88",name:"extensionFee",type:"uint88"}],stateMutability:"view",type:"function"}],i=new ethers.Contract(this.termManagerAddress,o,r),a=await i.getTermFees(t);return{originationFeeBps:Number(a.originationFee?.toString?.()??a[0]?.toString?.()??a[0]),extensionFeeBps:Number(a.extensionFee?.toString?.()??a[1]?.toString?.()??a[1])}}catch(t){throw console.error("[ProtocolParameters] Error fetching term fees:",t.message),new Error(`Failed to fetch term fees: ${t.message}`)}}async getAuthorizedSpendsHash(t){try{const e=this.rpcUrl||await Lit.Actions.getRpcUrl({chain:this.chain}),r=new ethers.providers.StaticJsonRpcProvider({url:e,timeout:g},{name:"any",chainId:this.chainId}),o=t.startsWith("0x")?t:`0x${t.padStart(64,"0")}`,i=new ethers.Contract(this.loanOpsManagerAddress,[{inputs:[{name:"positionId",type:"bytes32"}],name:"getAuthorizedSpendsHash",outputs:[{name:"",type:"bytes32"}],stateMutability:"view",type:"function"}],r);return await i.getAuthorizedSpendsHash(o)}catch(t){throw console.error("[ProtocolParameters] Error fetching authorized spends hash:",t.message),new Error(`Failed to fetch authorized spends hash: ${t.message}`)}}async getMaxEscalatedThreshold(){try{let t;t=this.rpcUrl?this.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.chain});const e=new ethers.providers.StaticJsonRpcProvider({url:t,timeout:g},{name:"any",chainId:this.chainId}),r=[{inputs:[],name:"maxEscalatedThreshold",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"}],o=new ethers.Contract(this.liquidationManagerAddress,r,e),i=await o.maxEscalatedThreshold();return Number(i.toString())}catch(t){throw console.error("[ProtocolParameters] Error fetching max escalated threshold:",t.message),new Error(`Failed to fetch max escalated threshold: ${t.message}`)}}};function W(t){return new V(t)}var j=class{constructor(t){this.config=t}async getVaultSnapshot(t){const e=await this.queryPositionState(t);console.log(`[Vault Snapshot] Raw vault address from contract: "${e.vaultAddress}"`);const r=!0===this.config.debugOverrides?.useStubbedBtcData,[o,i]=r?this.buildStubbedBtcSnapshotInputs(e):await Promise.all([this.config.vaultBalance.calculateTrustedBalance(t,e.vaultAddress),this.config.priceOracle.getBTCPriceConsensus()]),a=W({termManagerAddress:this.config.termManagerAddress,loanOpsManagerAddress:this.config.loanOpsManagerAddress,liquidationManagerAddress:this.config.liquidationManagerAddress,chain:this.config.chain,chainId:this.config.chainId||1,rpcUrl:this.config.rpcUrl}),n=this.config.termOverride??e.selectedTerm,[s,c,l]=await Promise.all([a.getLiquidationThreshold(),a.getMaxEscalatedThreshold(),a.getTermFees(n)]),u=L(e.termStartTimestamp,e.selectedTerm),d=F(u.isExpired,u.daysIntoGracePeriod,s,c),h=_(o.availableBalance,i,e.ucdDebt),p=h.collateralRatioBps<d,g=h.collateralRatioBps-d;return{positionId:e.positionId,pkpId:e.pkpId,borrower:e.borrower,vaultAddress:e.vaultAddress,ucdDebt:e.ucdDebt,termStartTimestamp:e.termStartTimestamp,selectedTerm:e.selectedTerm,status:e.status,expiryAt:e.expiryAt,previousExpiryAt:e.previousExpiryAt,totalTerm:e.totalTerm,totalBTCSats:o.totalBalance,totalUTXOs:o.totalUTXOs,authorizedSpendsSats:o.authorizedBalance,authorizedSpendsHash:o.authorizedSpendsHash,availableBTCSats:o.availableBalance,availableUTXOs:o.availableUTXOs,btcPriceUsd:i,collateralValueUsd:h.collateralValueUsd,collateralRatioBps:h.collateralRatioBps,termDurationDays:u.termDurationDays,termLengthDays:u.termLengthDays,isExpired:u.isExpired,daysUntilExpiry:u.daysUntilExpiry,daysIntoGracePeriod:u.daysIntoGracePeriod,currentLiquidationThreshold:d,isLiquidatable:p,marginToLiquidationBps:g,liquidationThresholdBps:s,originationFeeBps:l.originationFeeBps,extensionFeeBps:l.extensionFeeBps,timestamp:Date.now()}}async getVaultSnapshotFast(t){const e=await this.queryPositionState(t);console.log(`[Vault Snapshot] Raw vault address from contract: "${e.vaultAddress}"`);const r=!0===this.config.debugOverrides?.useStubbedBtcData,[o,i]=r?this.buildStubbedBtcSnapshotInputs(e):await Promise.all([this.config.vaultBalance.calculateTrustedBalance(t,e.vaultAddress,!0),this.config.priceOracle.getBTCPriceConsensus()]),a=W({termManagerAddress:this.config.termManagerAddress,loanOpsManagerAddress:this.config.loanOpsManagerAddress,liquidationManagerAddress:this.config.liquidationManagerAddress,chain:this.config.chain,chainId:this.config.chainId||1,rpcUrl:this.config.rpcUrl}),n=this.config.termOverride??e.selectedTerm,[s,c,l]=await Promise.all([a.getLiquidationThreshold(),a.getMaxEscalatedThreshold(),a.getTermFees(n)]),u=L(e.termStartTimestamp,e.selectedTerm),d=F(u.isExpired,u.daysIntoGracePeriod,s,c),h=_(o.availableBalance,i,e.ucdDebt),p=h.collateralRatioBps<d,g=h.collateralRatioBps-d;return{positionId:e.positionId,pkpId:e.pkpId,borrower:e.borrower,vaultAddress:e.vaultAddress,ucdDebt:e.ucdDebt,termStartTimestamp:e.termStartTimestamp,selectedTerm:e.selectedTerm,status:e.status,expiryAt:e.expiryAt,previousExpiryAt:e.previousExpiryAt,totalTerm:e.totalTerm,totalBTCSats:o.totalBalance,totalUTXOs:o.totalUTXOs,authorizedSpendsSats:o.authorizedBalance,authorizedSpendsHash:o.authorizedSpendsHash,availableBTCSats:o.availableBalance,availableUTXOs:o.availableUTXOs,btcPriceUsd:i,collateralValueUsd:h.collateralValueUsd,collateralRatioBps:h.collateralRatioBps,termDurationDays:u.termDurationDays,termLengthDays:u.termLengthDays,isExpired:u.isExpired,daysUntilExpiry:u.daysUntilExpiry,daysIntoGracePeriod:u.daysIntoGracePeriod,currentLiquidationThreshold:d,isLiquidatable:p,marginToLiquidationBps:g,liquidationThresholdBps:s,originationFeeBps:l.originationFeeBps,extensionFeeBps:l.extensionFeeBps,timestamp:Date.now()}}buildStubbedBtcSnapshotInputs(t){const e=BigInt(this.config.debugOverrides?.stubbedAvailableBtcSats??"10000000"),r=BigInt(this.config.debugOverrides?.stubbedBtcPriceUsd??"5000000000000");return[{totalUTXOs:[],totalBalance:e,authorizedUTXOs:[],authorizedBalance:0n,authorizedSpendsHash:this.config.debugOverrides?.stubbedAuthorizedSpendsHash??ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["bytes32","bytes32[]"],[t.positionId,[]])),availableUTXOs:[],availableBalance:e,vaultAddress:t.vaultAddress,positionId:t.positionId,timestamp:Date.now()},r]}async queryPositionState(t){const e=t.startsWith("0x")?t:`0x${t.padStart(64,"0")}`;let r;r=this.config.rpcUrl?this.config.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.config.chain});const o=new ethers.providers.StaticJsonRpcProvider({url:r,timeout:g},this.config.chainId),i=new ethers.Contract(this.config.contractAddress,[{inputs:[],name:"core",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"}],o),a=await i.core(),n=new ethers.Contract(a,[{inputs:[{internalType:"bytes32",name:"positionId",type:"bytes32"}],name:"getPositionDetails",outputs:[{components:[{internalType:"bytes32",name:"positionId",type:"bytes32"},{internalType:"bytes32",name:"pkpId",type:"bytes32"},{internalType:"uint256",name:"ucdDebt",type:"uint256"},{internalType:"string",name:"vaultAddress",type:"string"},{internalType:"address",name:"borrower",type:"address"},{internalType:"uint40",name:"createdAt",type:"uint40"},{internalType:"uint40",name:"lastUpdated",type:"uint40"},{internalType:"uint16",name:"selectedTerm",type:"uint16"},{internalType:"uint40",name:"expiryAt",type:"uint40"},{internalType:"enum LoanStatusLib.LoanStatus",name:"status",type:"uint8"},{internalType:"uint40",name:"previousExpiryAt",type:"uint40"},{internalType:"uint16",name:"totalTerm",type:"uint16"}],internalType:"struct IPositionManagerCore.Position",name:"",type:"tuple"}],stateMutability:"view",type:"function"}],o),s=await n.getPositionDetails(e),c=Number(s.status);if(c<0||c>7)throw console.error("[VaultSnapshot] INVALID STATUS - ABI decoding error detected"),console.error(" Position ID:",e),console.error(" Contract:",this.config.contractAddress),console.error(" Status decoded:",c,"(expected 0-7)"),console.error(" Full position:",JSON.stringify(s,null,2)),new Error(`Invalid position status decoded from contract: ${c} (expected 0-7). This indicates an ABI decoding issue. Position: ${e}`);const l=Number(s.expiryAt),u=Number(s.selectedTerm),d=Number(s.totalTerm),h=Number(s.previousExpiryAt),p=(w=u,0===(m=l)?0:m-30*w*86400);var m,w;return{positionId:s.positionId,pkpId:s.pkpId,borrower:s.borrower,vaultAddress:this.parseVaultAddress(s.vaultAddress,S(this.config.chain)),ucdDebt:BigInt(s.ucdDebt.toString()),termStartTimestamp:p,selectedTerm:u,status:c,expiryAt:l,previousExpiryAt:h,totalTerm:d}}parseVaultAddress(t,e){try{const r=JSON.parse(t);if("object"==typeof r&&null!==r){if("sepolia"===e.toLowerCase())return r.regtest||r.testnet||r.mainnet;const t=function(t){return b[t]}(e);return"testnet"===t&&(r.testnet||r.regtest)||r.mainnet}}catch(t){}return t}async isLiquidatable(t){return(await this.getVaultSnapshot(t)).isLiquidatable}async getCollateralRatio(t){return(await this.getVaultSnapshot(t)).collateralRatioBps}async getAvailableBalance(t){return(await this.getVaultSnapshot(t)).availableBTCSats}async hasSufficientCollateral(t,e,r){const o=await this.getVaultSnapshot(t);return function(t,e,r,o){const i=e+r;return 0n===i||Number(t*s*10000n/i)>=o}(o.collateralValueUsd,o.ucdDebt,e,r)}};var G="function getProtocolPauseStatus() view returns (tuple(bool positionManagerPaused, bool positionManagerLiquidationsPaused, bool positionManagerCorePaused, bool loanOperationsPaused, bool collateralManagerPaused, bool liquidationManagerPaused, bool circuitBreakerPaused, bool ucdControllerPaused, bool ucdTokenPaused, bool simplePsmPaused))",K={mintUcd:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","circuitBreakerPaused","ucdControllerPaused","ucdTokenPaused","simplePsmPaused"],withdrawBtc:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","collateralManagerPaused","circuitBreakerPaused","ucdControllerPaused","ucdTokenPaused","simplePsmPaused"],processPayment:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","circuitBreakerPaused","ucdControllerPaused","ucdTokenPaused"],extendPosition:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","circuitBreakerPaused","ucdControllerPaused","ucdTokenPaused","simplePsmPaused"],liquidation:["positionManagerLiquidationsPaused","liquidationManagerPaused","circuitBreakerPaused"],adminLiquidation:["positionManagerLiquidationsPaused","liquidationManagerPaused","circuitBreakerPaused"],btcTransactionSign:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","collateralManagerPaused","circuitBreakerPaused"]};function J(t){return{positionManagerPaused:t.positionManagerPaused,positionManagerLiquidationsPaused:t.positionManagerLiquidationsPaused,positionManagerCorePaused:t.positionManagerCorePaused,loanOperationsPaused:t.loanOperationsPaused,collateralManagerPaused:t.collateralManagerPaused,liquidationManagerPaused:t.liquidationManagerPaused,circuitBreakerPaused:t.circuitBreakerPaused,ucdControllerPaused:t.ucdControllerPaused,ucdTokenPaused:t.ucdTokenPaused,simplePsmPaused:t.simplePsmPaused}}var Q=new ethers.utils.Interface(["function views() view returns (address)","function paused() view returns (bool)","function liquidationPaused() view returns (bool)","function simplePsm() view returns (address)"]),Y=new ethers.utils.Interface(["function core() view returns (address)","function loanOps() view returns (address)","function collateralManager() view returns (address)","function liquidationManager() view returns (address)","function circuitBreaker() view returns (address)"]),Z=new ethers.utils.Interface(["function getUcdController() view returns (address)","function ucdToken() view returns (address)"]),tt=new ethers.utils.Interface(["function paused() view returns (bool)"]);async function et(t,e,r){return t.call({to:e,data:r})}async function rt(t,e){const r=new ethers.utils.Interface([G]).encodeFunctionData("getProtocolPauseStatus",[]);let o;try{return function(t){const e=new ethers.utils.Interface([G]).decodeFunctionResult("getProtocolPauseStatus",t)[0];return Array.isArray(e)?J({positionManagerPaused:e[0],positionManagerLiquidationsPaused:e[1],positionManagerCorePaused:e[2],loanOperationsPaused:e[3],collateralManagerPaused:e[4],liquidationManagerPaused:e[5],circuitBreakerPaused:e[6],ucdControllerPaused:e[7],ucdTokenPaused:e[8],simplePsmPaused:e[9]}):J(e)}(await t.call({to:e,data:r}))}catch(t){o=t}try{return await async function(t,e){const r=await et(t,e,Q.encodeFunctionData("views",[])),[o]=Q.decodeFunctionResult("views",r),[i,a,n,s,c,l,u,d]=await Promise.all([et(t,e,Q.encodeFunctionData("paused",[])),et(t,e,Q.encodeFunctionData("liquidationPaused",[])),et(t,e,Q.encodeFunctionData("simplePsm",[])),et(t,o,Y.encodeFunctionData("core",[])),et(t,o,Y.encodeFunctionData("loanOps",[])),et(t,o,Y.encodeFunctionData("collateralManager",[])),et(t,o,Y.encodeFunctionData("liquidationManager",[])),et(t,o,Y.encodeFunctionData("circuitBreaker",[]))]),h=Q.decodeFunctionResult("paused",i)[0],p=Q.decodeFunctionResult("liquidationPaused",a)[0],g=Q.decodeFunctionResult("simplePsm",n)[0],m=Y.decodeFunctionResult("core",s)[0],w=Y.decodeFunctionResult("loanOps",c)[0],f=Y.decodeFunctionResult("collateralManager",l)[0],y=Y.decodeFunctionResult("liquidationManager",u)[0],b=Y.decodeFunctionResult("circuitBreaker",d)[0],T=await et(t,w,Z.encodeFunctionData("getUcdController",[])),v=await et(t,w,Z.encodeFunctionData("ucdToken",[])),S=Z.decodeFunctionResult("getUcdController",T)[0],P=Z.decodeFunctionResult("ucdToken",v)[0],E=async e=>{if(!e||e===ethers.constants.AddressZero)return!1;try{const r=await et(t,e,tt.encodeFunctionData("paused",[]));return tt.decodeFunctionResult("paused",r)[0]}catch{return!1}},[$,A,I,C,B,U,M,x]=await Promise.all([E(m),E(w),E(f),E(y),E(b),E(S),E(P),E(g)]);return J({positionManagerPaused:h,positionManagerLiquidationsPaused:p,positionManagerCorePaused:$,loanOperationsPaused:A,collateralManagerPaused:I,liquidationManagerPaused:C,circuitBreakerPaused:B,ucdControllerPaused:U,ucdTokenPaused:M,simplePsmPaused:x})}(t,e)}catch(t){const e=o instanceof Error?o.message:String(o),r=t instanceof Error?t.message:String(t);throw new Error(`getProtocolPauseStatus failed (aggregate: ${e}; decomposed: ${r})`)}}function ot(t){if("string"!=typeof t)throw new Error("positionId must be a string");const e=t.trim(),r=/^0x/i.test(e)?e.slice(2):e;if(0===r.length)throw new Error("positionId is empty");if(!/^[0-9a-fA-F]+$/.test(r))throw new Error("positionId must be hexadecimal (bytes32)");if(r.length>64)throw new Error("positionId exceeds 32 bytes");return"0x"+r.padStart(64,"0").toLowerCase()}var it={hardhat:{chain:"hardhat",chainId:v.hardhat,bitcoinNetwork:b.hardhat,allowArbitraryBitcoinProvider:!0,allowArbitraryEvmRpc:!0,minBitcoinConfirmations:1},sepolia:{chain:"sepolia",chainId:v.sepolia,bitcoinNetwork:b.sepolia,allowArbitraryBitcoinProvider:!1,allowArbitraryEvmRpc:!1,minBitcoinConfirmations:1},ethereum:{chain:"ethereum",chainId:v.ethereum,bitcoinNetwork:b.ethereum,allowArbitraryBitcoinProvider:!1,allowArbitraryEvmRpc:!1,minBitcoinConfirmations:6}};var at,nt=[{inputs:[{internalType:"uint256",name:"chainId",type:"uint256"}],name:"getProviders",outputs:[{internalType:"bytes32[]",name:"ids",type:"bytes32[]"},{components:[{internalType:"bytes",name:"ciphertext",type:"bytes"},{internalType:"bytes32",name:"pkpId",type:"bytes32"},{internalType:"uint64",name:"addedAt",type:"uint64"}],internalType:"struct BitcoinProviderRegistry.ProviderEntry[]",name:"entries",type:"tuple[]"}],stateMutability:"view",type:"function"}];async function st(t,e){const r=66===e.length?"0x"+e.slice(-40):e;try{const e=await Lit.Actions.Decrypt({pkpId:r,ciphertext:t}),o="string"==typeof e?e:String(e??"");if(!o)throw new Error("Decrypt returned empty plaintext");return o}catch(t){throw new Error(`Failed to decrypt Bitcoin provider URL (pkpId=${e}): ${t?.message??String(t)}`)}}async function ct(t){const{policy:e,bitcoinProviderUrl:r,ethersProvider:o,registryAddress:i}=t;if(!r||"string"!=typeof r)throw new Error("resolveBitcoinProviderForPolicy: bitcoinProviderUrl is required");if(e.allowArbitraryBitcoinProvider)return{name:"Custom Provider",url:r,minConfirmations:e.minBitcoinConfirmations,network:e.bitcoinNetwork};if(!i)throw new Error(`Bitcoin provider registry address is required on chain "${e.chain}" \u2014 set contractAddresses.BitcoinProviderRegistry. Hardcoded allowlists have been removed (see audit C-1/H-6 fix).`);const a=await async function(t,e,r){if(!r||"string"!=typeof r)throw new Error("fetchBitcoinProviderEntries: registryAddress (BitcoinProviderRegistry) is required");if(!e)throw new Error("fetchBitcoinProviderEntries: ethers provider is required");const o=new ethers.Contract(r,nt,e),[i,a]=await o.getProviders(t),n=[];for(let t=0;t<i.length;t++)n.push({providerId:i[t],ciphertext:a[t].ciphertext,pkpId:a[t].pkpId,addedAt:Number(a[t].addedAt)});return n}(e.chainId,o,i);if(0===a.length)throw new Error(`No Bitcoin providers registered for chainId=${e.chainId} in ${i}. Admin must addProvider(...) via AdminModule before LIT Actions can sign.`);const n=await async function(t,e){if(!e)throw new Error("matchAllowedProviderUrl: candidateUrl is required");for(const r of t)if(await st(r.ciphertext,r.pkpId)===e)return r.providerId;return null}(a,r);if(!n)throw new Error(`Bitcoin provider URL not in any registered encrypted slot for chainId=${e.chainId}`);return{name:`Registry Provider ${n.slice(0,10)}`,url:r,minConfirmations:e.minBitcoinConfirmations,network:e.bitcoinNetwork}}async function main(t){for(const[e,r]of Object.entries(t))globalThis[e]=r;const e=M.create("BTC Withdrawal Validator");console.log("[Step 0] Validating configuration..."),e.stepStart("0","Validate configuration parameters");const r=globalThis.chain,o=globalThis.bitcoinProviderUrl;if(!r)throw new Error('Missing required parameter: "chain". Must be "sepolia" or "ethereum"');if(!o)throw new Error('Missing required parameter: "bitcoinProviderUrl". Must be an approved Bitcoin RPC provider URL');const i=function(t){const e=S(t),r=it[e];if(!r)throw new Error(`No chain policy registered for "${t}"`);return r}(r),a=i.chain,n=i.bitcoinNetwork;let s;if(console.log(` \u2705 Chain: ${r} (${a})`),console.log(` \u2705 Bitcoin Network: ${n}`),!globalThis.contractAddresses||"object"!=typeof globalThis.contractAddresses)throw new Error('Required "contractAddresses" object with: PositionManager, LoanOperationsManagerModule, TermManagerModule');const p=globalThis.contractAddresses.PositionManager,g=globalThis.contractAddresses.LoanOperationsManagerModule,y=globalThis.contractAddresses.TermManagerModule,b=globalThis.contractAddresses.UCDController,v=globalThis.contractAddresses.LITActionValidator,E=globalThis.contractAddresses.LiquidationManagerModule??globalThis.contractAddresses.LiquidationManager??"",$=globalThis.contractAddresses.BTCSpendAuthorizer??"";if(!(p&&g&&y&&b&&E))throw new Error("All contract addresses are required: PositionManager, LoanOperationsManagerModule, TermManagerModule, UCDController, and LiquidationManager or LiquidationManagerModule");console.log(" \u2705 Contract addresses loaded and validated"),console.log(` PositionManager: ${p}`),console.log(` LoanOpsManager: ${g}`),e.stepEnd("0"),console.log("[Step 0.5] Critical system health checks..."),e.stepStart("0.5","Critical system health checks"),e.warn("0.5","System health checks temporarily disabled (SystemHealthModule not available)"),e.log("0.5","\u2705 System health checks complete (skipped)"),e.stepEnd("0.5");const I=globalThis.auth;if(!I||"object"!=typeof I)throw new Error('Missing or invalid "auth" parameter - must be an object');if(!I.positionId)throw new Error("auth.positionId is required");if("number"!=typeof I.timestamp)throw new Error("auth.timestamp must be a number");if(!I.signature)throw new Error("auth.signature is required");const C=BigInt(I.amount);if(C<=0n)throw new Error(`Withdrawal amount must be positive, got: ${C.toString()} sats`);const B=u;if(C<B)throw new Error(`Withdrawal amount ${C.toString()} sats is below minimum ${B.toString()} sats (Bitcoin dust limit). This amount is not economically viable for Bitcoin network transactions.`);const U=I.destinationAddress;if(!U||"string"!=typeof U)throw new Error('Missing or invalid "destinationAddress" parameter - must be a valid Bitcoin address');const D=x().publicKey;if(!D)throw new Error("publicKey must not be blank");if("string"!=typeof D||0===D.length)throw new Error("publicKey must not be blank");const O=D;if(!(()=>{try{const t=/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{26,35}$/.test(U),e=/^(bc1|tb1|bcrt1)[0-9a-zA-Z]{11,87}$/.test(U);return!(!t&&!e)&&("testnet"===n||"regtest"===n?U.startsWith("m")||U.startsWith("n")||U.startsWith("2")||U.startsWith("tb1")||U.startsWith("bcrt1"):"mainnet"===n&&(U.startsWith("1")||U.startsWith("3")||U.startsWith("bc1")))}catch(t){return!1}})())throw new Error(`Invalid Bitcoin address format for ${n} network: ${U}. Expected ${"mainnet"===n?"address starting with 1, 3, or bc1":"address starting with m, n, 2, tb1, or bcrt1"}`);console.log(` \u2705 Destination address validated: ${U} (${n})`);let N="0.5";try{console.log("[BTC Withdrawal] Started"),console.log(` Position: ${I.positionId}`),console.log(` Withdrawal Amount: ${C.toString()} sats`),console.log(` Destination Address: ${U}`);const t=new R(globalThis.priceProviders,void 0),n=globalThis.rpcUrl;let u;n&&"string"==typeof n?(!function(t,e){if(t.allowArbitraryEvmRpc)return;if(!e||"string"!=typeof e)throw new Error("validateEvmRpcForPolicy: rpcUrl must be a non-empty string");let r;try{r=new URL(e).hostname}catch(t){throw new Error(`Invalid rpcUrl: ${t?.message??String(t)}`)}if(!T.some((t=>r===t||r.endsWith(`.${t}`))))throw new Error(`Custom RPC domain "${r}" is not in the approved list: ${T.join(", ")}`)}(i,n),console.log(` Using RPC URL override: ${function(t){if(null==t||"string"!=typeof t)return"[missing]";let e=t.replace(/([?&])(dkey|apikey|api_key|key|token|secret|password|auth|authorization)=[^&]*/gi,"$1$2=[REDACTED]");try{const t=new URL(e);(t.username||t.password)&&(t.username="",t.password="",e=t.toString())}catch{}return e}(n)}`),u=n):(u=await Lit.Actions.getRpcUrl({chain:r}),console.log(` Using LIT-provided RPC URL for chain: ${r}`));const S=new ethers.providers.JsonRpcProvider(u);s=await ct({policy:i,bitcoinProviderUrl:o,ethersProvider:S,registryAddress:globalThis.contractAddresses.BitcoinProviderRegistry}),console.log(` \u2705 Bitcoin Provider: ${s.name} (min confs ${s.minConfirmations})`);const B=new k({providerUrl:s.url});!function(t,e){const r=K[t],o=[];for(const t of r)e[t]&&o.push(t);if(o.length>0)throw new Error(JSON.stringify({code:"PROTOCOL_PAUSED",operation:t,paused:o,status:e}))}("withdrawBtc",await rt(S,p));const M=(L={contractAddress:$||g,chain:r,chainId:P(a),rpcUrl:u,bitcoinProvider:B,minConfirmations:s.minConfirmations},new q(L));N="1",console.log("[Step 1] Getting vault snapshot..."),e.stepStart("1","Get vault snapshot");const x=function(t){return new j(t)}({contractAddress:p,termManagerAddress:y,loanOpsManagerAddress:g,liquidationManagerAddress:E,chain:r,chainId:P(a),rpcUrl:u,vaultBalance:M,priceOracle:t}),D=await x.getVaultSnapshot(I.positionId);console.log(` \u2705 Vault balance: ${D.availableBTCSats.toString()} sats`),console.log(` \u2705 Current debt: ${D.ucdDebt.toString()} wei`),e.stepEnd("1"),N="2",console.log("[Step 2] Authenticating caller..."),e.stepStart("2","Authenticate caller");const F=e.getElapsed();console.log(`[TIMING] Step 2 started at ${F}ms`);const _=P(a),V=new ethers.providers.StaticJsonRpcProvider(u,_);let W;if(5===D.status){if(!v)throw new Error("LITActionValidator address required for LIQUIDATED position withdrawals. Pass contractAddresses.LITActionValidator in jsParams.");const t=new ethers.Contract(v,["function pkpOwners(bytes32) view returns (address)"],V);if(W=await t.pkpOwners(D.pkpId),!W||W===ethers.constants.AddressZero)throw new Error("No PKP owner registered for this liquidated position in LITActionValidator");console.log(` \u2139\ufe0f LIQUIDATED position \u2014 verifying against PKP owner: ${W}`)}else W=D.borrower;if(!await A.verifyWithdrawAuthorization(I,W,V))throw new Error("Caller not authorized");console.log(" \u2705 Caller authorized"),e.stepEnd("2"),N="2.5",console.log("[Step 2.5] Validating position status..."),e.stepStart("2.5","Validate position status");const G=e.getElapsed();console.log(`[TIMING] Step 2.5 started at ${G}ms`);if(![0,1,2,6,5].includes(D.status))throw new Error(`Position status ${m(D.status)} does not allow withdrawal. Valid statuses: PENDING_DEPOSIT, PENDING_MINT, ACTIVE, REPAID, LIQUIDATED.`);console.log(` \u2705 Position status valid for withdrawal: ${m(D.status)}`),e.stepEnd("2.5"),N="3",console.log("[Step 3] Validating post-withdrawal collateral ratio..."),e.stepStart("3","Validate collateral ratio");const J=e.getElapsed();console.log(`[TIMING] Step 3 started at ${J}ms`);const Q=C;if(0n===D.ucdDebt)console.log(" \u2705 Position has zero debt - withdrawal allowed");else{if(D.btcPriceUsd<c||D.btcPriceUsd>l)throw new Error(`Bitcoin price ${D.btcPriceUsd} is outside acceptable range (${c} - ${l}). This may indicate oracle manipulation or stale price data. Please try again later.`);console.log(` \u2705 BTC price validation passed: $${(Number(D.btcPriceUsd)/1e8).toFixed(2)}`);const t=D.availableBTCSats-Q,e=z(X(t,D.btcPriceUsd),D.ucdDebt);if(e<D.liquidationThresholdBps)throw new Error(`Insufficient collateral: post-withdrawal ratio ${H(e)}% < liquidation threshold ${H(D.liquidationThresholdBps)}%. Withdrawal would result in insufficient collateralization.`);console.log(` \u2705 Post-withdrawal collateral ratio: ${H(e)}%`),console.log(` \u2705 Exceeds liquidation threshold: ${H(D.liquidationThresholdBps)}%`)}e.stepEnd("3"),N="4",console.log("[Step 4] Validating withdrawal amount and balance..."),e.stepStart("4","Validate withdrawal amount and balance");const Y=e.getElapsed();console.log(`[TIMING] Step 4 started at ${Y}ms`);const Z="string"==typeof I.amount?BigInt(I.amount):I.amount;if(Z!==C)throw new Error(`Authorization amount mismatch: auth.amount=${Z.toString()} sats, but requested withdrawal=${C.toString()} sats. The signed authorization must match the requested withdrawal amount.`);if(console.log(" \u2705 Authorization amount matches withdrawal amount"),Q>D.availableBTCSats)throw new Error(`Insufficient vault balance: need ${Q.toString()} sats but only ${D.availableBTCSats.toString()} sats available`);console.log(" \u2705 Total deduction is within available balance");const tt=D.availableBTCSats-Q,et=D.ucdDebt,it=X(tt,D.btcPriceUsd),at=et>0n?z(it,et):void 0;if(console.log(` Post-withdrawal collateral: ${tt.toString()} sats`),console.log(` Post-withdrawal collateral value: $${(Number(it)/1e8).toFixed(2)}`),console.log(` Post-withdrawal debt: ${et.toString()} wei`),console.log(` Post-withdrawal collateral ratio: ${et>0n&&void 0!==at?H(Number(at)):"\u221e"}%`),tt<0n)throw new Error(`Withdrawal would result in negative balance: ${tt.toString()} sats`);console.log(" \u2705 Withdrawal validation passed"),e.stepEnd("4"),N="4.5",console.log("[Step 4.5] Querying vault UTXOs from Bitcoin network..."),e.stepStart("4.5","Query and select UTXO");const nt=e.getElapsed();console.log(`[TIMING] Step 4.5 started at ${nt}ms`);const st=D.vaultAddress;if(!st)throw new Error("Vault address not found in snapshot");console.log(` Vault address: ${st}`);let lt=[],ut=null;const dt=d,ht=h;for(let t=1;t<=dt;t++)try{console.log(` \ud83d\udd04 UTXO query attempt ${t}/${dt}...`),lt=await B.getUTXOs(st),console.log(` \u2705 UTXO query succeeded on attempt ${t}`),ut=null;break}catch(e){ut=e,console.error(` \u274c UTXO query failed on attempt ${t}:`,e.message),t<dt&&(console.log(` \u23f3 Waiting ${ht}ms before retry...`),await new Promise((t=>setTimeout(t,ht))))}if(ut)throw new Error(`Failed to query UTXOs after ${dt} attempts: ${ut.message}`);if(!lt||0===lt.length)throw new Error(`No UTXOs found in vault ${st}`);console.log(` \u2705 Found ${lt.length} UTXO(s) in vault`);const pt=s.minConfirmations,gt=lt.filter((t=>t.confirmations>=pt));if(0===gt.length)throw new Error(`No confirmed UTXOs found in vault. Required confirmations: ${pt}, found ${lt.length} UTXO(s) with insufficient confirmations.`);console.log(` \u2705 Found ${gt.length} confirmed UTXO(s)`);const mt=gt.filter((t=>t.satoshis>=Q));let wt;if(0===mt.length){const t=gt.reduce(((t,e)=>t+e.satoshis),0n);if(t<Q)throw new Error(`Insufficient vault balance for withdrawal. Need ${Q.toString()} sats, total across ${gt.length} UTXO(s): ${t.toString()} sats.`);wt=[...gt].sort(((t,e)=>Number(e.satoshis-t.satoshis)))[0],console.log(" \u2139\ufe0f No single UTXO covers withdrawal \u2014 multi-UTXO consolidation will be used in Phase 2."),console.log(` Primary UTXO (contract auth): ${wt.txid}:${wt.vout} (${wt.satoshis.toString()} sats)`)}else wt=mt.sort(((t,e)=>Number(t.satoshis-e.satoshis)))[0];console.log(` \u2705 Selected UTXO: ${wt.txid}:${wt.vout}`),console.log(` \u2705 UTXO value: ${wt.satoshis.toString()} sats`),console.log(` \u2705 UTXO confirmations: ${wt.confirmations}`);const ft=D.availableBTCSats;if(wt.satoshis<ft&&console.warn(` \u26a0\ufe0f Selected UTXO value (${wt.satoshis.toString()}) < calculated balance (${ft.toString()}). This is expected for multi-UTXO vaults where we select one UTXO.`),wt.satoshis<Q)throw new Error(`Selected UTXO value (${wt.satoshis.toString()} sats) < withdrawal amount (${Q.toString()} sats). This should never happen after eligibility filtering.`);console.log(" \u2705 UTXO validation passed"),console.log(" \ud83d\udd0d Verifying UTXO vout against Bitcoin transaction...");const yt=await B.getTransactionOutputs(wt.txid);if(yt){for(const t of yt)if(t.scriptpubkey_address===st){t.index!==wt.vout?(console.log(` \u26a0\ufe0f Esplora API reported vout=${wt.vout} but vault output is at vout=${t.index}. Correcting.`),wt={...wt,vout:t.index}):console.log(` \u2705 UTXO vout=${wt.vout} confirmed correct`);break}}else console.log(` \u26a0\ufe0f Could not fetch transaction outputs for vout verification - using API-reported vout=${wt.vout}`);e.stepEnd("4.5"),N="5",console.log("[Step 5] Building authorization message..."),e.stepStart("5","Build authorization message");const bt=e.getElapsed();console.log(`[TIMING] Step 5 started at ${bt}ms`);const Tt=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(I.action)),vt=D.authorizedSpendsHash,St=ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["uint256"],[D.ucdDebt])),Pt=ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["address","address","address","address"],[p,g,y,b])),Et=BigInt(I.timestamp),$t=tt,At=D.btcPriceUsd;if(At<c||At>l)throw new Error(`BTC price ${At.toString()} (8 decimals) is outside acceptable range (${c.toString()} - ${l.toString()})`);console.log("[Step 5] DEBUG: Message Hash Parameters:"),console.log(" positionId:",I.positionId),console.log(" action:",I.action),console.log(" actionHash:",Tt),console.log(" authorizedSpendsHash:",vt),console.log(" ucdDebtHash:",St),console.log(" withdrawalAddress:",U),console.log(" totalDeduction:",Q.toString()),console.log(" newCollateral:",$t.toString()),console.log(" quantumTimestamp:",Et.toString()),console.log(" btcPrice:",At.toString()),console.log(" utxoTxid:",wt.txid),console.log(" utxoVout:",wt.vout);const It=ot(I.positionId),Ct=P(a),Bt={name:w,version:f,chainId:Ct,verifyingContract:ethers.utils.getAddress(g)},Ut={WithdrawalAuthorization:[{name:"positionId",type:"bytes32"},{name:"actionHash",type:"bytes32"},{name:"authorizedSpendsHash",type:"bytes32"},{name:"ucdDebtHash",type:"bytes32"},{name:"contractBundleHash",type:"bytes32"},{name:"withdrawalAddress",type:"string"},{name:"totalDeduction",type:"uint256"},{name:"newCollateral",type:"uint256"},{name:"quantumTimestamp",type:"uint256"},{name:"btcPrice",type:"uint256"},{name:"utxoTxid",type:"string"},{name:"utxoVout",type:"uint32"}]},Mt=ethers.utils._TypedDataEncoder.hash(Bt,Ut,{positionId:It,actionHash:Tt,authorizedSpendsHash:vt,ucdDebtHash:St,contractBundleHash:Pt,withdrawalAddress:U,totalDeduction:Q.toString(),newCollateral:$t.toString(),quantumTimestamp:Et.toString(),btcPrice:At.toString(),utxoTxid:wt.txid,utxoVout:wt.vout});console.log("[Step 5] Contract message hash for signing:",Mt),console.log("[Step 5] Message hash bytes length:",ethers.utils.arrayify(Mt).length),e.stepEnd("5"),N="6",console.log("[Step 6] Signing contract message hash..."),e.stepStart("6","Sign message");const xt=e.getElapsed();console.log(`[TIMING] Step 6 started at ${xt}ms`),e.log("6","========================================"),e.log("6","\ud83d\udd0d FINAL HASH INPUTS - ALL LIT NODES MUST MATCH"),e.log("6","========================================"),e.log("6",`Position ID: ${I.positionId}`),e.log("6",`Action Hash: ${Tt}`),e.log("6",`Authorized Spends Hash: ${vt}`),e.log("6",`UCD Debt Hash: ${St}`),e.log("6",`Contract Bundle Hash: ${Pt}`),e.log("6",`Destination Address: ${U}`),e.log("6",`Total Deduction: ${Q.toString()}`),e.log("6",`New Collateral: ${$t.toString()}`),e.log("6",`Quantum Timestamp: ${Et.toString()}`),e.log("6",`BTC Price: ${At.toString()}`),e.log("6",`Selected UTXO Txid: ${wt.txid}`),e.log("6",`Selected UTXO Vout: ${wt.vout}`),e.log("6",`Selected UTXO Satoshis: ${wt.satoshis.toString()}`),e.log("6",`Selected UTXO Confirmations: ${wt.confirmations}`),e.log("6","---"),e.log("6",`\ud83d\udcdd FINAL CONTRACT MESSAGE HASH: ${Mt}`),e.log("6","========================================"),e.log("6","Preparing signEcdsa call"),e.log("6",`contractMessageHash: ${Mt}`),e.log("6",`publicKey: ${O}`),e.log("6","publicKey with 0x prefix: "+("0x"+O));const Dt=ethers.utils.arrayify(Mt);e.log("6",`messageBytes length: ${Dt.length}`),e.log("6",`messageBytes: ${JSON.stringify(Array.from(Dt))}`),e.log("6","About to sign with wallet-derived key (Chipotle)...");const Ot=Date.now(),kt=globalThis.validatorWalletAddress;if(!kt||!kt.startsWith("0x"))throw new Error("validatorWalletAddress required \u2014 must be a createWallet-derived address");const Nt=await Lit.Actions.getPrivateKey({pkpId:kt}),Rt="string"==typeof Nt?Nt.startsWith("0x")?Nt:`0x${Nt}`:String(Nt),qt=new ethers.Wallet(Rt),Lt=new ethers.utils.SigningKey(Rt);e.log("6",`Wallet-derived signer address: ${qt.address}`),e.log("6",`validatorWalletAddress: ${kt}`);const Ft=Lt.signDigest(Mt),_t=ethers.utils.joinSignature(Ft),Xt=Date.now()-Ot;e.log("6",`Chipotle signature created in ${Xt}ms`),e.log("6",`signature: ${_t}`);const zt=globalThis.contractAddresses.BTCSpendAuthorizer?.trim()||"";let Ht=null;if(zt){const t=ot(I.positionId),r=P(a),o=$t+Q,i={name:w,version:f,chainId:r,verifyingContract:ethers.utils.getAddress(zt)},n={BtcSpendAuth:[{name:"positionId",type:"bytes32"},{name:"txid",type:"string"},{name:"vout",type:"uint32"},{name:"satoshis",type:"uint256"},{name:"targetAddress",type:"string"},{name:"targetAmount",type:"uint256"}]},s=ethers.utils._TypedDataEncoder.hash(i,n,{positionId:t,txid:wt.txid,vout:wt.vout,satoshis:o.toString(),targetAddress:U,targetAmount:Q.toString()});e.log("6",`EIP-712 BtcSpendAuth digest: ${s}`),Ht=await qt._signTypedData(i,n,{positionId:t,txid:wt.txid,vout:wt.vout,satoshis:o.toString(),targetAddress:U,targetAmount:Q.toString()}),e.log("6",`btcSpendAuth signature: ${Ht}`)}e.stepEnd("6"),console.log("[BTC Withdrawal] \u2705 Complete"),e.summary();const Vt={approved:!0,positionId:I.positionId,actionHash:Tt,authorizedSpendsHash:vt,ucdDebtHash:St,contractBundleHash:Pt,totalDeduction:Q.toString(),remainingCollateral:tt.toString(),newCollateralRatioBps:et>0n&&void 0!==at?Number(at):void 0,destinationAddress:U,signature:_t,btcSpendAuthSignature:Ht,timestamp:Et.toString(),btcPrice:At.toString(),utxoTxid:wt.txid,utxoVout:wt.vout,utxoSatoshis:wt.satoshis.toString()};return console.log("[BTC Withdrawal] \ud83d\udd0d Response data before JSON.stringify:"),console.log(" totalDeduction:",Q,"type:",typeof Q,"toString():",Q.toString()),console.log(" remainingCollateral:",tt,"type:",typeof tt,"toString():",tt.toString()),console.log(" btcPrice:",At,"type:",typeof At,"toString():",At.toString()),console.log(" timestamp:",Et,"type:",typeof Et,"toString():",Et.toString()),console.log(" Full response object:",JSON.stringify(Vt,null,2)),Vt}catch(t){return console.error("[BTC Withdrawal] \u274c Failed:",t.message),console.error(`[BTC Withdrawal] Failed at step: ${N}`),e.error("error",`Failed: ${t.message}`),{approved:!1,reason:t.message||t.toString(),positionId:I?.positionId,timestamp:Date.now()}}var L}return at=i,((i,a,n,s)=>{if(a&&"object"==typeof a||"function"==typeof a)for(let c of r(a))o.call(i,c)||c===n||t(i,c,{get:()=>a[c],enumerable:!(s=e(a,c))||s.enumerable});return i})(t({},"__esModule",{value:!0}),at)})();if("object"==typeof _LIT_ACTION_)if("function"==typeof _LIT_ACTION_.main)var main=_LIT_ACTION_.main;else"function"==typeof _LIT_ACTION_.go&&_LIT_ACTION_.go();
1
+ var _LIT_ACTION_=(()=>{var t=Object.defineProperty,e=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,o=Object.prototype.hasOwnProperty,i={};((e,r)=>{for(var o in r)t(e,o,{get:r[o],enumerable:!0})})(i,{main:()=>main});var n=11e3,a=100000000n,s=1000000000000000000n,c=1000000000000n,l=100000000000000n,u=546n,d=3,h=500,p=100,g=8e3;function m(t){switch(t){case 0:return"PENDING_DEPOSIT";case 1:return"PENDING_MINT";case 2:return"ACTIVE";case 3:return"EXPIRED";case 4:return"LIQUIDATABLE";case 5:return"LIQUIDATED";case 6:return"REPAID";case 7:return"CLOSED";default:return`UNKNOWN(${t})`}}var w="DiamondHands.Protocol",f="1",y=(t=>(t.SEPOLIA="sepolia",t.ETHEREUM="ethereum",t.HARDHAT="hardhat",t))(y||{}),b={sepolia:"testnet",ethereum:"mainnet",hardhat:"regtest"},T=["infura.io","drpc.org"],v={ethereum:1,sepolia:11155111,hardhat:1337};function S(t){const e=t.toLowerCase().trim();if("sepolia"===e)return"sepolia";if("ethereum"===e||"mainnet"===e)return"ethereum";if("hardhat"===e)return"hardhat";throw new Error(`Unsupported EVM chain: "${t}". Supported chains: ${Object.values(y).join(", ")}`)}function P(t){return v[t]}function E(t){return Math.floor(t/p)*p}async function $(){const t=Math.floor(Date.now()/1e3),e=t%p;if(!function(t){const e=(t??Math.floor(Date.now()/1e3))%p;return e<8||e>=92}(t))return;let r;r=e>=92?p-e+8:8-e,console.log(`[Quantum] Waiting ${r}s for safe moment (current time in quantum: ${e}s)`),await new Promise((t=>setTimeout(t,1e3*r))),console.log(`[Quantum] Safe quantum ready: ${E(Math.floor(Date.now()/1e3))}`)}var A=class t{static verifyAmountPositionActionAuthorizationStructure(t){if(!t||"object"!=typeof t)throw new Error('Missing or invalid "auth" parameter - must be an object');if(!t.positionId)throw new Error("auth.positionId is required");if("number"!=typeof t.chainId)throw new Error("auth.chainId must be a number");if("number"!=typeof t.timestamp)throw new Error("auth.timestamp must be a number");if(void 0===t.amount||null===t.amount)throw new Error("auth.amount is required");if(!t.action)throw new Error("auth.action is required");if(!t.signature)throw new Error("auth.signature is required");return t}static async recoverSigner(t,e){try{const r=ethers.utils.arrayify(t),o=ethers.utils.hashMessage(r);return ethers.utils.recoverAddress(o,e)}catch(t){throw new Error(`Failed to recover signer: ${t instanceof Error?t.message:String(t)}`)}}static async checkEIP1271(t,e,r,o){try{const i=new ethers.Contract(t,["function isValidSignature(bytes32,bytes) view returns (bytes4)"],o);return"0x1626ba7e"===await i.isValidSignature(e,r)}catch{return!1}}static async verifyActionAuthorization(t,e,r,o){const i=Math.floor(Date.now()/1e3);await $();const n=o?.strictCurrentQuantum?i:void 0;try{!function(t,e,r){const o=e??Math.floor(Date.now()/1e3),i=E(o),n=E(t);if(r?.strictCurrentQuantum){if(n!==i)throw new Error(`[Quantum] Signature must come from current quantum (strict mode). Signature quantum: ${n}, current quantum: ${i}`);return}const a=i-p,s=i+p;if(n!==a&&n!==i&&n!==s)throw new Error(`[Quantum] Signature outside 3-quantum window. Signature quantum: ${n}, Valid range: [${a} (past), ${i} (current), ${s} (next)]`);if(n===a){if(o<a+8)throw new Error(`[Quantum] Dead zone violation: Current time (${o}) is in first 8 seconds of PAST quantum (${a}). This is unsafe due to boundary instability.`)}else if(n===s&&o>=s+92)throw new Error(`[Quantum] Dead zone violation: Current time (${o}) is in last 8 seconds of NEXT quantum (${s}). This is unsafe due to boundary instability.`)}(t.timestamp,n,{strictCurrentQuantum:!0===o?.strictCurrentQuantum})}catch{return!1}const a=e(),s=await this.recoverSigner(a,t.signature);return await r(s,a,t.signature)}static async verifyAmountPositionActionAuthorization(e,r,o){return this.verifyActionAuthorization(e,(()=>{const t=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(e.action)),r="string"==typeof e.amount?BigInt(e.amount):e.amount,o=[e.positionId,e.timestamp,e.chainId,r.toString(),t];return ethers.utils.solidityKeccak256(["bytes32","uint256","uint256","uint256","bytes32"],o)}),(async(e,i,n)=>e.toLowerCase()===r.toLowerCase()||!!o&&t.checkEIP1271(r,i,n,o)))}static async verifyMintAuthorization(t,e,r){return"mint-ucd"===t.action&&this.verifyAmountPositionActionAuthorization(t,e,r)}static async verifyWithdrawAuthorization(e,r,o){if("withdraw-btc"!==e.action)return!1;return this.verifyActionAuthorization(e,(()=>{const t=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(e.action)),r="string"==typeof e.amount?BigInt(e.amount):e.amount,o=[e.positionId,e.timestamp,e.chainId,r.toString(),e.destinationAddress,t];return ethers.utils.solidityKeccak256(["bytes32","uint256","uint256","uint256","string","bytes32"],o)}),(async(e,i,n)=>e.toLowerCase()===r.toLowerCase()||!!o&&t.checkEIP1271(r,i,n,o)))}static verifyTermPositionActionAuthorizationStructure(t){if(!t||"object"!=typeof t)throw new Error('Missing or invalid "auth" parameter - must be an object');if(!t.positionId)throw new Error("auth.positionId is required");if("number"!=typeof t.chainId)throw new Error("auth.chainId must be a number");if("number"!=typeof t.timestamp)throw new Error("auth.timestamp must be a number");if(void 0===t.newTerm||null===t.newTerm)throw new Error("auth.newTerm is required");if("number"!=typeof t.newTerm)throw new Error("auth.newTerm must be a number");if(!t.action)throw new Error("auth.action is required");if(!t.signature)throw new Error("auth.signature is required");return t}static async verifyTermPositionActionAuthorization(e,r,o){return this.verifyActionAuthorization(e,(()=>{const t=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(e.action)),r=[e.positionId,e.timestamp,e.chainId,e.newTerm,t];return ethers.utils.solidityKeccak256(["bytes32","uint256","uint256","uint256","bytes32"],r)}),(async(e,i,n)=>e.toLowerCase()===r.toLowerCase()||!!o&&t.checkEIP1271(r,i,n,o)))}static async verifyExtendAuthorization(t,e,r){return"extend-position"===t.action&&this.verifyTermPositionActionAuthorization(t,e,r)}static async verifyBtcExecutionAuthorization(e,r,o){if("execute-btc-withdrawal"!==e.action)return!1;return this.verifyActionAuthorization(e,(()=>{const t=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(e.action)),r=[e.positionId,e.timestamp,e.chainId,e.utxoIdentifier,e.networkFee,t];return ethers.utils.solidityKeccak256(["bytes32","uint256","uint256","string","uint256","bytes32"],r)}),(async(e,i,n)=>e.toLowerCase()===r.toLowerCase()||!!o&&t.checkEIP1271(r,i,n,o)),{strictCurrentQuantum:!0})}};function I(t){if(!0===t)return!0;if(!1===t)return!1;const e=globalThis;return!0===e.debugAction||(!0===e.LIT_ACTION_DEBUG||("true"===e.LIT_ACTION_DEBUG||function(){try{if("undefined"==typeof process||!process.env)return!1;const t=process.env.LIT_ACTION_DEBUG,e=process.env.DEBUG;return"1"===t||"true"===t||"1"===e||"true"===e}catch{return!1}}()))}function C(...t){I()&&console.log(...t)}var B=class{stepStart(t,e){}stepEnd(t,e){}log(t,e,...r){}warn(t,e){}error(t,e){}getElapsed(){return 0}getRemaining(){return 3e4}summary(){}getExecutionId(){return""}isDebugEnabled(){return!1}},U=class{constructor(t){this.stepStartTimes=new Map,this.stepDurations=new Map,this.TIMEOUT_MS=3e4,this.actionName=t,this.executionStartTime=Date.now();const e=Date.now(),r=Math.random().toString(36).substring(2,9);this.executionId=`exec_${e}_${r}`,this.logHeader()}logHeader(){console.log(`[${this.actionName}] ========================================`),console.log(`[${this.actionName}] Execution started`),console.log(`[${this.actionName}] Execution ID: ${this.executionId}`);void 0!==globalThis.litNodeContext?(console.log(`[${this.actionName}] Context: LIT Node`),console.log(`[${this.actionName}] Node: ${globalThis.litNodeContext?.nodeAddress||"unknown"}`)):console.log(`[${this.actionName}] Context: Browser/Test`),console.log(`[${this.actionName}] ========================================`)}stepStart(t,e){this.stepStartTimes.set(t,Date.now());const r=Date.now()-this.executionStartTime,o=this.TIMEOUT_MS-r;console.log(`[Step ${t}] ${e}...`),console.log(`[Step ${t}] Elapsed: ${r}ms | Remaining: ${o}ms`)}stepEnd(t,e=5e3){const r=this.stepStartTimes.get(t);if(!r)return console.warn(`[Step ${t}] \u26a0\ufe0f stepEnd called without matching stepStart`),void 0;const o=Date.now()-r;this.stepDurations.set(t,o),console.log(`[Step ${t}] Duration: ${o}ms`),o>e&&console.warn(`\u26a0\ufe0f [Step ${t}] Took ${o}ms (> ${e}ms threshold)`);const i=Date.now()-this.executionStartTime,n=this.TIMEOUT_MS-i;n<5e3&&console.warn(`\u26a0\ufe0f [Step ${t}] Time remaining: ${n}ms (approaching timeout)`)}log(t,e,...r){r.length>0?console.log(`[Step ${t}] ${e}`,...r):console.log(`[Step ${t}] ${e}`)}warn(t,e){console.warn(`\u26a0\ufe0f [Step ${t}] ${e}`)}error(t,e){console.error(`\u274c [Step ${t}] ${e}`)}getElapsed(){return Date.now()-this.executionStartTime}getRemaining(){return this.TIMEOUT_MS-this.getElapsed()}summary(){const t=Date.now()-this.executionStartTime,e=this.TIMEOUT_MS-t;if(console.log(`[${this.actionName}] ========================================`),console.log(`[${this.actionName}] Execution Summary`),console.log(`[${this.actionName}] Execution ID: ${this.executionId}`),console.log(`[${this.actionName}] Total time: ${(t/1e3).toFixed(2)}s`),console.log(`[${this.actionName}] Time remaining: ${e}ms`),this.stepDurations.size>0){console.log(`[${this.actionName}] Step breakdown:`);for(const[e,r]of this.stepDurations.entries()){const o=(r/t*100).toFixed(1);console.log(`[${this.actionName}] Step ${e}: ${r}ms (${o}%)`)}}t>2e4&&console.warn(`\u26a0\ufe0f [${this.actionName}] Slow execution: ${(t/1e3).toFixed(2)}s (${e}ms remaining)`),e<5e3&&console.warn(`\u26a0\ufe0f [${this.actionName}] CRITICAL: Only ${e}ms remaining before timeout!`),console.log(`[${this.actionName}] ========================================`)}getExecutionId(){return this.executionId}isDebugEnabled(){return!0}},M=class{static create(t="LIT Action",e){return I(e)?new U(t):new B}};function x(){const t=globalThis,e=t.jsParams;return null==e||"object"!=typeof e||Array.isArray(e)?t:e}function D(t){if(t instanceof Error)return t.message;if("string"==typeof t)return t;try{return JSON.stringify(t)}catch{return String(t)}}function O(t){return t instanceof Error&&"AbortError"===t.name}var k=class{constructor(t){this.config=t,this.timeout=t.timeout||15e3,this.logger=M.create("BitcoinDataProvider")}async getCurrentBlockHeight(){if(this.logger.stepStart("0","getCurrentBlockHeight"),this.config.rpcHelper){const t=await this.config.rpcHelper.getBlockCount();return this.logger.stepEnd("0"),t}const t=new AbortController,e=setTimeout((()=>t.abort()),this.timeout);try{const r=Date.now(),o=await fetch(`${this.config.providerUrl}/blocks/tip/height`,{signal:t.signal,headers:{Accept:"text/plain","User-Agent":"Mozilla/5.0 (compatible; DiamondHandsValidator/1.0)","ngrok-skip-browser-warning":"true"}});if(clearTimeout(e),C(`[BitcoinDataProvider] blocks/tip/height ${Date.now()-r}ms (timeout budget ${this.timeout}ms)`),!o.ok)throw new Error(`Failed to fetch block height: ${o.status} ${o.statusText}`);const i=await o.text();if(i.trim().startsWith("<!DOCTYPE")||i.trim().startsWith("<html"))throw new Error("Bitcoin RPC endpoint returned HTML instead of block height. URL may be pointing to web interface instead of API endpoint. Expected: plain text number, Got: HTML document. Check that URL ends with /api/esplora (not root /)");const n=parseInt(i.trim(),10);if(isNaN(n)){const t=i.length>200?i.substring(0,200)+"... (truncated)":i;throw new Error(`Invalid block height response: ${t}`)}return this.logger.stepEnd("0"),n}catch(t){if(clearTimeout(e),this.logger.stepEnd("0"),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);throw t}}async getUTXOs(t){this.logger.log("0",`Original address: "${t}"`);const e=this.stripNetworkPrefix(t);if(this.logger.log("0",`Cleaned address: "${e}"`),this.config.rpcHelper)return await this.fetchUTXOsFromRPC(e);try{return await this.fetchUTXOsFromProvider(this.config.providerUrl,e)}catch(t){if(this.logger.warn("0",`Primary provider failed: ${D(t)}`),this.config.fallbackProviders&&this.config.fallbackProviders.length>0){const t=[...this.config.fallbackProviders].sort(((t,e)=>t.priority-e.priority));for(const r of t)try{return this.logger.log("0",`Trying fallback: ${r.name} (${r.url})`),await this.fetchUTXOsFromProvider(r.url,e)}catch(t){this.logger.warn("0",`Fallback ${r.name} failed: ${D(t)}`);continue}}throw new Error(`Failed to fetch UTXOs: ${D(t)}`)}}stripNetworkPrefix(t){return t.replace(/^(REGTEST_|TESTNET_|MAINNET_)/,"")}async fetchUTXOsFromRPC(t){if(!this.config.rpcHelper)throw new Error("RPC helper not configured");const e=this.config.rpcWallet||"";return(await this.config.rpcHelper.listUnspent(e,t)).map((t=>({txid:t.txid,vout:t.vout,satoshis:BigInt(Math.round(1e8*t.amount)),confirmations:t.confirmations})))}parseBlockstreamUTXOs(t,e){if(!Array.isArray(t))throw new Error("Invalid Blockstream response format: expected an array");const r=t,o=[];for(const t of r){let r=0;t.status&&"object"==typeof t.status?t.status.confirmed&&(r=void 0!==t.status.block_height&&t.status.block_height>0?e-t.status.block_height+1:1):void 0!==t.confirmations&&(r=t.confirmations);const i=t.txid,n=void 0!==t.vout?t.vout:t.n,a=void 0!==t.value?t.value:t.satoshis;if(void 0===i||void 0===n||void 0===a)throw new Error("Invalid UTXO row: missing txid, vout/n, or value/satoshis");o.push({txid:i,vout:n,satoshis:BigInt(a),confirmations:r})}return o}async fetchUTXOsFromProvider(t,e){this.logger.stepStart("1","fetchUTXOsFromProvider");const r=`${t}/address/${e}/utxos`;this.logger.log("1",`Fetching UTXOs from ${r}`);const o=new AbortController,i=setTimeout((()=>o.abort()),this.timeout);try{const t=Date.now(),[n,a]=await Promise.all([this.getCurrentBlockHeight(),fetch(r,{signal:o.signal,headers:{Accept:"application/json","Content-Type":"application/json","User-Agent":"Mozilla/5.0 (compatible; DiamondHandsValidator/1.0)","ngrok-skip-browser-warning":"true"}})]);if(clearTimeout(i),C(`[BitcoinDataProvider] parallel(tipHeight + GET utxos) wall ${Date.now()-t}ms endpoint tail .../${e.slice(0,12)}.../utxos (timeout budget ${this.timeout}ms)`),this.logger.log("1",`Current block height: ${n}`),!a.ok)throw new Error(`Bitcoin provider error: ${a.status} ${a.statusText}`);const s=await a.text();if(s.trim().startsWith("<!DOCTYPE")||s.trim().startsWith("<html"))throw new Error("Bitcoin RPC endpoint returned HTML instead of JSON. URL may be pointing to web interface instead of API endpoint. Expected: JSON array of UTXOs, Got: HTML document. Check that URL ends with /api/esplora (not root /)");let c;try{c=JSON.parse(s)}catch(t){const e=s.length>200?s.substring(0,200)+"... (truncated)":s;throw new Error(`Failed to parse JSON response: ${D(t)}. Response: ${e}`)}this.logger.log("1",`Raw API Response: ${JSON.stringify(c,null,2)}`);const l=this.parseBlockstreamUTXOs(c,n);return this.logger.stepEnd("1"),l}catch(t){if(clearTimeout(i),this.logger.stepEnd("1"),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);throw t}}async getUTXOSet(t,e){let r=[],o=null;const i=d,n=h;for(let e=1;e<=i;e++)try{this.logger.log("2",`UTXO query attempt ${e}/${i}...`),r=await this.getUTXOs(t),this.logger.log("2",`UTXO query succeeded on attempt ${e}`),o=null;break}catch(t){o=t instanceof Error?t:new Error(D(t)),this.logger.error("2",`UTXO query failed on attempt ${e}: ${D(t)}`),e<i&&(this.logger.log("2",`Waiting ${n}ms before retry...`),await new Promise((t=>setTimeout(t,n))))}if(o)throw new Error(`Failed to query UTXOs after ${i} attempts: ${o.message}`);const a=r.reduce(((t,e)=>t+e.satoshis),0n),s=r.filter((t=>t.confirmations>=e)).reduce(((t,e)=>t+e.satoshis),0n),c=a-s;return{utxos:r,totalBalance:a,totalUTXOs:r.length,confirmedBalance:s,unconfirmedBalance:c}}async getBalance(t){const e=this.stripNetworkPrefix(t),r=`${this.config.providerUrl}/address/${e}`;this.logger.log("3",`Fetching balance from ${r}`);const o=new AbortController,i=setTimeout((()=>o.abort()),this.timeout);try{const t=Date.now(),e=await fetch(r,{signal:o.signal,headers:{Accept:"application/json","Content-Type":"application/json","User-Agent":"Mozilla/5.0 (compatible; DiamondHandsValidator/1.0)","ngrok-skip-browser-warning":"true"}});if(clearTimeout(i),C(`[BitcoinDataProvider] GET address chain_stats ${Date.now()-t}ms (timeout budget ${this.timeout}ms)`),!e.ok)throw new Error(`Bitcoin provider error: ${e.status} ${e.statusText}`);const n=await e.json();if(!n.chain_stats)throw new Error("Invalid response: missing chain_stats");const a=n.chain_stats.funded_txo_sum,s=n.chain_stats.spent_txo_sum;if(void 0===a||void 0===s)throw new Error(`Invalid response: missing required fields. funded_txo_sum: ${a}, spent_txo_sum: ${s}`);const c=BigInt(a-s);return this.logger.log("3",`Balance: ${c.toString()} sats`),this.logger.log("3",` - Funded: ${a} sats, Spent: ${s} sats`),c}catch(t){if(clearTimeout(i),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);const r=D(t);throw this.logger.log("3",`Balance fetch failed: ${r}`),new Error(`Failed to fetch Bitcoin balance for address ${e}: ${r}`)}}async getTransaction(t){if(this.config.rpcHelper)try{const e=this.config.rpcWallet||"",r=await this.config.rpcHelper.getTransaction(e,t);return{txid:r.txid,confirmations:r.confirmations||0}}catch(t){const e=D(t),r=null!==t&&"object"==typeof t&&"code"in t&&"number"==typeof t.code?t.code:void 0;if(e.includes("Invalid or non-wallet transaction")||-5===r)return null;throw t}const e=new AbortController,r=setTimeout((()=>e.abort()),this.timeout);try{const o=Date.now(),i=await fetch(`${this.config.providerUrl}/tx/${t}`,{signal:e.signal});if(clearTimeout(r),C(`[BitcoinDataProvider] GET tx/${t.slice(0,10)}\u2026 ${Date.now()-o}ms (timeout budget ${this.timeout}ms)`),!i.ok){if(404===i.status)return null;throw new Error(`Bitcoin provider error: ${i.status} ${i.statusText}`)}const n=await i.json();return n.status?{txid:n.txid??t,confirmations:n.status.confirmed&&n.status.block_height?1:0}:null}catch(t){if(clearTimeout(r),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);if(D(t).includes("404"))return null;throw t}}async getTransactionOutputs(t){if(!this.config.providerUrl)return null;const e=new AbortController,r=setTimeout((()=>e.abort()),this.timeout);try{const o=await fetch(`${this.config.providerUrl}/tx/${t}`,{signal:e.signal});if(clearTimeout(r),!o.ok){if(404===o.status)return null;throw new Error(`Bitcoin provider error: ${o.status} ${o.statusText}`)}const i=await o.json();return i.vout&&Array.isArray(i.vout)?i.vout.map(((t,e)=>({index:e,scriptpubkey:t.scriptpubkey,scriptpubkey_address:t.scriptpubkey_address,value:t.value??0}))):null}catch(t){if(clearTimeout(r),O(t))throw new Error(`Request timeout after ${this.timeout}ms`);throw t}}},N=class t{constructor(e,r,o){if(r&&Array.isArray(r))this.sources=r;else{if(!Array.isArray(e))throw new Error("Price oracle requires a priceProviders array \u2014 defaults and fallbacks have been removed. Pass 3 distinct {name, apiKey} entries from the supported set: "+t.ACTIVE_PROVIDER_NAMES.join(", "));this.sources=this.buildSources(e)}this.sources.sort(((t,e)=>t.priority-e.priority)),this.validateProviderCount()}validateProviderCount(){if(this.sources.length<t.MIN_DISTINCT_PROVIDERS)throw new Error(`Price oracle requires at least ${t.MIN_DISTINCT_PROVIDERS} eligible providers for consensus. Currently configured: ${this.sources.length} provider(s). Supported active providers: ${t.ACTIVE_PROVIDER_NAMES.join(", ")}`)}buildSources(e){if(0===e.length)throw new Error("priceProviders must be a non-empty array of 3 distinct providers, each with an apiKey.");const r=[],o=new Set;let i=1;for(const n of e){if(!n||"string"!=typeof n.name)throw new Error("priceProviders entries must be {name, apiKey, apiSecret?} objects");const e=n.name.toLowerCase();if(!t.ACTIVE_PROVIDER_NAMES.includes(e))throw new Error(`Unsupported price provider "${n.name}". Supported: ${t.ACTIVE_PROVIDER_NAMES.join(", ")}`);if(o.has(e))throw new Error(`Duplicate price provider "${e}" \u2014 the oracle requires 3 DISTINCT providers so a single upstream failure or manipulation cannot compromise consensus. Use 3 different provider names from: ${t.ACTIVE_PROVIDER_NAMES.join(", ")}`);switch(o.add(e),e){case"binance":if(!n.apiKey)throw new Error("Binance provider requires an apiKey");r.push(this.createBinanceSource(n.apiKey,i++));break;case"coinbase":if(!n.apiKey)throw new Error("Coinbase provider requires an apiKey");r.push(this.createCoinbaseSource(n.apiKey,i++));break;case"cryptocompare":if(!n.apiKey)throw new Error("CryptoCompare provider requires an apiKey");r.push(this.createCryptoCompareSource(n.apiKey,i++));break;case"coinmarketcap":if(!n.apiKey)throw new Error("CoinMarketCap provider requires an apiKey");r.push(this.createCoinMarketCapSource(n.apiKey,i++));break;case"coingecko":if(!n.apiKey)throw new Error("CoinGecko provider requires an apiKey (Demo or Pro). Unauthenticated CoinGecko access is not accepted \u2014 the free tier is rate-limited and edge-cached, which breaks median consensus under load.");r.push(this.createCoinGeckoSource(n.apiKey,i++));break;default:throw new Error(`Unhandled provider: ${e}`)}}if(r.length<t.MIN_DISTINCT_PROVIDERS)throw new Error(`Insufficient price providers: need at least ${t.MIN_DISTINCT_PROVIDERS} distinct entries, got ${r.length}.`);return this.selectSampledSources(r)}createCryptoCompareSource(t,e){return{name:"CryptoCompare",fetchPrice:async()=>{const e=new URL("https://min-api.cryptocompare.com/data/price");e.searchParams.set("fsym","BTC"),e.searchParams.set("tsyms","USDT"),e.searchParams.set("api_key",t);const r=await(async t=>{const e=new AbortController,r=setTimeout((()=>e.abort()),5e3);try{const o=await fetch(t,{signal:e.signal,headers:{Accept:"application/json"}});if(clearTimeout(r),!o.ok)throw new Error(`HTTP ${o.status} ${o.statusText}`);return await o.json()}catch(t){if(clearTimeout(r),"AbortError"===t.name)throw new Error("Request timeout after 5000ms");throw t}})(e.toString()),o=Number(r?.USDT);if(!Number.isFinite(o)||o<=0)throw new Error("Invalid CryptoCompare price payload");return o},priority:e}}createFetchJson(){return async(t,e)=>{const r=new AbortController,o=setTimeout((()=>r.abort()),5e3);try{const o=await fetch(t,{headers:{Accept:"application/json",...e||{}},signal:r.signal});if(!o.ok)throw new Error(`HTTP ${o.status} ${o.statusText}`);return await o.json()}finally{clearTimeout(o)}}}getSelectionSeed(){const t="undefined"!=typeof process?process.env.PRICE_PROVIDER_SELECTION_SEED:void 0,e=t?Number(t):NaN;return Number.isFinite(e)?e:("undefined"!=typeof process,0,Math.floor(Date.now()+1e6*Math.random()))}selectSampledSources(t){const e=[...t];let r=this.getSelectionSeed()>>>0;for(let t=e.length-1;t>0;t--){const o=Math.floor((r=1664525*r+1013904223>>>0,r/4294967296*(t+1)));[e[t],e[o]]=[e[o],e[t]]}return e.slice(0,3).map(((t,e)=>({...t,priority:e+1})))}createCoinGeckoSource(t,e){if(!t)throw new Error("createCoinGeckoSource requires an apiKey");const r=this.createFetchJson();return{name:"CoinGecko",fetchPrice:async()=>{const e=t.startsWith("pro:"),o=e?t.slice(4):t,i=e?{"x-cg-pro-api-key":o}:{"x-cg-demo-api-key":o},n=new URL("https://api.coingecko.com/api/v3/simple/price");n.searchParams.set("ids","bitcoin"),n.searchParams.set("vs_currencies","usd");const a=await r(n.toString(),i),s=Number(a?.bitcoin?.usd);if(!Number.isFinite(s)||s<=0)throw new Error("Invalid CoinGecko price payload");return s},priority:e}}createBinanceSource(t,e){if(!t)throw new Error("createBinanceSource requires an apiKey");const r=this.createFetchJson();return{name:"Binance",fetchPrice:async()=>{const e=new URL("https://api.binance.com/api/v3/ticker/price");e.searchParams.set("symbol","BTCUSDT");const o=await r(e.toString(),{"X-MBX-APIKEY":t}),i=Number(o?.price);if(!Number.isFinite(i)||i<=0)throw new Error("Invalid Binance price payload");return i},priority:e}}createCoinbaseSource(t,e){if(!t)throw new Error("createCoinbaseSource requires an apiKey");const r=this.createFetchJson();return{name:"Coinbase",fetchPrice:async()=>{const e=await r("https://api.coinbase.com/v2/prices/BTC-USDT/spot",{"CB-ACCESS-KEY":t}),o=Number(e?.data?.amount);if(!Number.isFinite(o)||o<=0)throw new Error("Invalid Coinbase price payload");return o},priority:e}}createCoinMarketCapSource(t,e){const r=this.createFetchJson();return{name:"CoinMarketCap",fetchPrice:async()=>{const e=new URL("https://pro-api.coinmarketcap.com/v2/cryptocurrency/quotes/latest");e.searchParams.set("symbol","BTC"),e.searchParams.set("convert","USDT");const o=await r(e.toString(),{"X-CMC_PRO_API_KEY":t}),i=Number(o?.data?.BTC?.[0]?.quote?.USDT?.price??o?.data?.BTC?.quote?.USDT?.price);if(!Number.isFinite(i)||i<=0)throw new Error("Invalid CoinMarketCap price payload");return i},priority:e}}async getBTCPrice(){const t=Date.now();if(3!==this.sources.length)throw new Error(`Price oracle requires exactly 3 providers. Currently configured: ${this.sources.length}`);const e=new Promise(((t,e)=>{setTimeout((()=>{e(new Error("Price oracle global timeout after 8000ms"))}),8e3)})),r=Promise.all(this.sources.map((async t=>{const e=Date.now(),r=await t.fetchPrice();return console.log(`[Price Oracle] \u2705 [+${Date.now()-e}ms] ${t.name}: $${r.toLocaleString()}`),r}))),o=[...await Promise.race([r,e])].sort(((t,e)=>t-e)),i=o[1];if((o[2]-o[0])/o[0]>.01){const t=this.sources.map((t=>t.name)).join(", "),e=o.map((t=>`$${t.toLocaleString()}`)).join(", ");throw new Error(`Price consensus failed: prices not within 1% tolerance. Providers: [${t}]. Prices: [${e}]`)}const n=Math.round(100*i),a=1000000n*BigInt(n),s=Date.now()-t;return console.log(`[Price Oracle] Median price: $${i.toLocaleString()} \u2014 total time: ${s}ms`),console.log(`[Price Oracle] Price with 8 decimals: ${a}`),a}async getBTCPriceConsensus(){console.log("[Price Oracle] Fetching BTC price with consensus...");const t=(await Promise.allSettled(this.sources.map((async t=>{const e=await t.fetchPrice();return{source:t.name,price:e}})))).filter((t=>"fulfilled"===t.status)).map((t=>t.value));if(0===t.length)throw new Error("No price sources returned data");console.log(`[Price Oracle] Got prices from ${t.length}/${this.sources.length} sources:`),t.forEach((t=>{console.log(` ${t.source}: $${t.price.toLocaleString()}`)}));const e=t.map((t=>t.price));e.sort(((t,e)=>t-e));const r=e[Math.floor(e.length/2)],o=e[0],i=e[e.length-1]/o,n=t.filter((t=>Math.abs(t.price-r)/r<=.02));if(i>1.05&&n.length===t.length)throw new Error(`Price consensus failed: sources too dispersed (${(100*(i-1)).toFixed(1)}% spread)`);if(n.length<t.length){const e=t.filter((t=>!n.find((e=>e.source===t.source))));if(console.log(`[Price Oracle] \u26a0\ufe0f Detected ${e.length} outlier(s):`),e.forEach((t=>{const e=Math.abs(t.price-r)/r;console.log(` ${t.source}: $${t.price.toLocaleString()} (${(100*e).toFixed(1)}% deviation)`)})),n.length<2)throw new Error("Price consensus failed: insufficient valid sources after outlier removal");console.log(`[Price Oracle] \u2705 Outliers filtered, continuing with ${n.length} valid sources`);const o=n.map((t=>t.price));o.sort(((t,e)=>t-e));const i=o[Math.floor(o.length/2)];console.log(`[Price Oracle] \u2705 Consensus price (median): $${i.toLocaleString()}`);const a=Math.round(100*i);return 1000000n*BigInt(a)}console.log(`[Price Oracle] \u2705 Consensus price (median): $${r.toLocaleString()}`);const a=Math.round(100*r);return 1000000n*BigInt(a)}};N.ACTIVE_PROVIDER_NAMES=["cryptocompare","coinbase","binance","coinmarketcap","coingecko"],N.MIN_DISTINCT_PROVIDERS=3;var R=N,q=class{constructor(t){this.config=t,this.bitcoinProvider=t.bitcoinProvider}async calculateBalance(t,e){const r=await this.bitcoinProvider.getBalance(e),o=await this.getAuthorizedSpendsFromContract(t),i=o.reduce(((t,e)=>t+e.satoshis),0n),n=r>i?r-i:0n;return{totalUTXOs:[],totalBalance:r,authorizedUTXOs:o,authorizedBalance:i,authorizedSpendsHash:this.computeAuthorizedSpendsHash(t,o),availableUTXOs:[],availableBalance:n,vaultAddress:e,positionId:t,timestamp:Date.now()}}async calculateTrustedBalance(t,e,r){if(r)return await this.calculateBalance(t,e);const o=this.config.minConfirmations||6,i=await this.bitcoinProvider.getUTXOSet(e,o),n=await this.getAuthorizedSpendsFromContract(t);for(const t of n){if(i.utxos.some((e=>e.txid===t.txid&&e.vout===t.vout)))throw new Error(`Authorized UTXO ${t.txid}:${t.vout} not yet spent. Transaction was authorized in smart contract but not signed and broadcasted to Bitcoin network. Complete the transaction by signing and broadcasting it.`)}const a=n.reduce(((t,e)=>t+e.satoshis),0n),s=i.utxos.filter((t=>!this.isUTXOAuthorized(t,n))),c=s.reduce(((t,e)=>t+e.satoshis),0n),l=this.computeAuthorizedSpendsHash(t,n);return{totalUTXOs:i.utxos,totalBalance:i.totalBalance,authorizedUTXOs:n,authorizedBalance:a,authorizedSpendsHash:l,availableUTXOs:s,availableBalance:c,vaultAddress:e,positionId:t,timestamp:Date.now()}}async getTrustedBalance(t,e){return(await this.calculateTrustedBalance(t,e)).availableBalance}async getAvailableUTXOs(t,e){return(await this.calculateTrustedBalance(t,e)).availableUTXOs}async isUTXOAvailable(t,e,r,o){return(await this.getAvailableUTXOs(t,e)).some((t=>t.txid===r&&t.vout===o))}isUTXOAuthorized(t,e){return e.some((e=>e.txid===t.txid&&e.vout===t.vout))}async getAuthorizedSpendsFromContract(t){const e=t.startsWith("0x")?t:`0x${t.padStart(64,"0")}`;let r;r=this.config.rpcUrl?this.config.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.config.chain});const o=new ethers.providers.StaticJsonRpcProvider({url:r,timeout:g},this.config.chainId),i=new ethers.Contract(this.config.contractAddress,[{inputs:[{internalType:"bytes32",name:"positionId",type:"bytes32"}],name:"getAuthorizedSpends",outputs:[{components:[{internalType:"string",name:"txid",type:"string"},{internalType:"uint32",name:"vout",type:"uint32"},{internalType:"uint256",name:"satoshis",type:"uint256"},{internalType:"string",name:"targetAddress",type:"string"},{internalType:"uint256",name:"targetAmount",type:"uint256"},{internalType:"uint256",name:"authorizedAt",type:"uint256"}],internalType:"struct LoanOperationsManager.AuthorizedSpend[]",name:"",type:"tuple[]"}],stateMutability:"view",type:"function"}],o);return(await i.getAuthorizedSpends(e)).map((e=>({txid:e.txid,vout:Number(e.vout),satoshis:BigInt(e.satoshis.toString()),positionId:t,targetAddress:e.targetAddress,targetAmount:BigInt(e.targetAmount.toString()),timestamp:Number(e.authorizedAt)})))}computeAuthorizedSpendsHash(t,e){const r=t.startsWith("0x")?t:`0x${t.padStart(64,"0")}`;if(0===e.length)return ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["bytes32","bytes32[]"],[r,[]]));const o=e.map((t=>{const e=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(t.txid)),r=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(t.targetAddress));return ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["bytes32","uint32","uint256","bytes32","uint256","uint256"],[e,t.vout,t.satoshis.toString(),r,t.targetAmount.toString(),t.timestamp]))}));return ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["bytes32","bytes32[]"],[r,o]))}};function L(t,e){if(0===t)return{termDurationDays:0,termLengthDays:30*e,isExpired:!1,daysUntilExpiry:30*e,daysIntoGracePeriod:0};const r=30*e,o=Math.floor(Date.now()/1e3)-t,i=Math.floor(o/86400);return{termDurationDays:i,termLengthDays:r,isExpired:i>r,daysUntilExpiry:Math.max(0,r-i),daysIntoGracePeriod:Math.max(0,i-r)}}function F(t,e,r,o){if(!t)return r??13e3;const i=o??n,a=Math.min(e,30);return n+a*a*(i-n)/900}function _(t,e,r){const o=t*e/(100000000n*a);if(0n===r)return{collateralValueUsd:o,collateralRatioBps:Number.MAX_SAFE_INTEGER};return{collateralValueUsd:o,collateralRatioBps:Number(o*s*10000n/r)}}function z(t,e){if(t<0n)throw new Error("BTC amount cannot be negative");if(e<=0n)throw new Error("BTC price must be positive");return t*e/a}function X(t,e){if(t<0n)throw new Error("Collateral value cannot be negative");if(e<=0n)throw new Error("Debt must be positive to calculate ratio");const r=Number(10000n*(10000000000n*t)/e);if(r<0)throw new Error(`Collateral ratio out of bounds: ${r} bps (${r/100}%)`);return!isFinite(r)||r>Number.MAX_SAFE_INTEGER?Number.MAX_SAFE_INTEGER:r}function V(t){return t/100}var H=class{constructor(t){this.termManagerAddress=t.termManagerAddress,this.loanOpsManagerAddress=t.loanOpsManagerAddress,this.liquidationManagerAddress=t.liquidationManagerAddress,this.chain=t.chain,this.chainId=t.chainId,this.rpcUrl=t.rpcUrl}async getLiquidationThreshold(){try{let t;t=this.rpcUrl?this.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.chain});const e=new ethers.providers.StaticJsonRpcProvider({url:t,timeout:g},{name:"any",chainId:this.chainId}),r=[{inputs:[],name:"liquidationThreshold",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"}],o=new ethers.Contract(this.loanOpsManagerAddress,r,e),i=await o.liquidationThreshold();return Number(i.toString())}catch(t){throw console.error("[ProtocolParameters] Error fetching liquidation threshold:",t.message),new Error(`Failed to fetch liquidation threshold: ${t.message}`)}}async getTermFees(t){try{let e;e=this.rpcUrl?this.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.chain});const r=new ethers.providers.StaticJsonRpcProvider({url:e,timeout:g},{name:"any",chainId:this.chainId}),o=[{inputs:[{internalType:"uint256",name:"_termMonths",type:"uint256"}],name:"getTermFees",outputs:[{internalType:"uint88",name:"originationFee",type:"uint88"},{internalType:"uint88",name:"extensionFee",type:"uint88"}],stateMutability:"view",type:"function"}],i=new ethers.Contract(this.termManagerAddress,o,r),n=await i.getTermFees(t);return{originationFeeBps:Number(n.originationFee?.toString?.()??n[0]?.toString?.()??n[0]),extensionFeeBps:Number(n.extensionFee?.toString?.()??n[1]?.toString?.()??n[1])}}catch(t){throw console.error("[ProtocolParameters] Error fetching term fees:",t.message),new Error(`Failed to fetch term fees: ${t.message}`)}}async getAuthorizedSpendsHash(t){try{const e=this.rpcUrl||await Lit.Actions.getRpcUrl({chain:this.chain}),r=new ethers.providers.StaticJsonRpcProvider({url:e,timeout:g},{name:"any",chainId:this.chainId}),o=t.startsWith("0x")?t:`0x${t.padStart(64,"0")}`,i=new ethers.Contract(this.loanOpsManagerAddress,[{inputs:[{name:"positionId",type:"bytes32"}],name:"getAuthorizedSpendsHash",outputs:[{name:"",type:"bytes32"}],stateMutability:"view",type:"function"}],r);return await i.getAuthorizedSpendsHash(o)}catch(t){throw console.error("[ProtocolParameters] Error fetching authorized spends hash:",t.message),new Error(`Failed to fetch authorized spends hash: ${t.message}`)}}async getMaxEscalatedThreshold(){try{let t;t=this.rpcUrl?this.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.chain});const e=new ethers.providers.StaticJsonRpcProvider({url:t,timeout:g},{name:"any",chainId:this.chainId}),r=[{inputs:[],name:"maxEscalatedThreshold",outputs:[{internalType:"uint256",name:"",type:"uint256"}],stateMutability:"view",type:"function"}],o=new ethers.Contract(this.liquidationManagerAddress,r,e),i=await o.maxEscalatedThreshold();return Number(i.toString())}catch(t){throw console.error("[ProtocolParameters] Error fetching max escalated threshold:",t.message),new Error(`Failed to fetch max escalated threshold: ${t.message}`)}}};function W(t){return new H(t)}var j=class{constructor(t){this.config=t}async getVaultSnapshot(t){const e=await this.queryPositionState(t);console.log(`[Vault Snapshot] Raw vault address from contract: "${e.vaultAddress}"`);const r=!0===this.config.debugOverrides?.useStubbedBtcData,[o,i]=r?this.buildStubbedBtcSnapshotInputs(e):await Promise.all([this.config.vaultBalance.calculateTrustedBalance(t,e.vaultAddress),this.config.priceOracle.getBTCPriceConsensus()]),n=W({termManagerAddress:this.config.termManagerAddress,loanOpsManagerAddress:this.config.loanOpsManagerAddress,liquidationManagerAddress:this.config.liquidationManagerAddress,chain:this.config.chain,chainId:this.config.chainId||1,rpcUrl:this.config.rpcUrl}),a=this.config.termOverride??e.selectedTerm,[s,c,l]=await Promise.all([n.getLiquidationThreshold(),n.getMaxEscalatedThreshold(),n.getTermFees(a)]),u=L(e.termStartTimestamp,e.selectedTerm),d=F(u.isExpired,u.daysIntoGracePeriod,s,c),h=_(o.availableBalance,i,e.ucdDebt),p=h.collateralRatioBps<d,g=h.collateralRatioBps-d;return{positionId:e.positionId,pkpId:e.pkpId,borrower:e.borrower,vaultAddress:e.vaultAddress,ucdDebt:e.ucdDebt,termStartTimestamp:e.termStartTimestamp,selectedTerm:e.selectedTerm,status:e.status,expiryAt:e.expiryAt,previousExpiryAt:e.previousExpiryAt,totalTerm:e.totalTerm,totalBTCSats:o.totalBalance,totalUTXOs:o.totalUTXOs,authorizedSpendsSats:o.authorizedBalance,authorizedSpendsHash:o.authorizedSpendsHash,availableBTCSats:o.availableBalance,availableUTXOs:o.availableUTXOs,btcPriceUsd:i,collateralValueUsd:h.collateralValueUsd,collateralRatioBps:h.collateralRatioBps,termDurationDays:u.termDurationDays,termLengthDays:u.termLengthDays,isExpired:u.isExpired,daysUntilExpiry:u.daysUntilExpiry,daysIntoGracePeriod:u.daysIntoGracePeriod,currentLiquidationThreshold:d,isLiquidatable:p,marginToLiquidationBps:g,liquidationThresholdBps:s,originationFeeBps:l.originationFeeBps,extensionFeeBps:l.extensionFeeBps,timestamp:Date.now()}}async getVaultSnapshotFast(t){const e=await this.queryPositionState(t);console.log(`[Vault Snapshot] Raw vault address from contract: "${e.vaultAddress}"`);const r=!0===this.config.debugOverrides?.useStubbedBtcData,[o,i]=r?this.buildStubbedBtcSnapshotInputs(e):await Promise.all([this.config.vaultBalance.calculateTrustedBalance(t,e.vaultAddress,!0),this.config.priceOracle.getBTCPriceConsensus()]),n=W({termManagerAddress:this.config.termManagerAddress,loanOpsManagerAddress:this.config.loanOpsManagerAddress,liquidationManagerAddress:this.config.liquidationManagerAddress,chain:this.config.chain,chainId:this.config.chainId||1,rpcUrl:this.config.rpcUrl}),a=this.config.termOverride??e.selectedTerm,[s,c,l]=await Promise.all([n.getLiquidationThreshold(),n.getMaxEscalatedThreshold(),n.getTermFees(a)]),u=L(e.termStartTimestamp,e.selectedTerm),d=F(u.isExpired,u.daysIntoGracePeriod,s,c),h=_(o.availableBalance,i,e.ucdDebt),p=h.collateralRatioBps<d,g=h.collateralRatioBps-d;return{positionId:e.positionId,pkpId:e.pkpId,borrower:e.borrower,vaultAddress:e.vaultAddress,ucdDebt:e.ucdDebt,termStartTimestamp:e.termStartTimestamp,selectedTerm:e.selectedTerm,status:e.status,expiryAt:e.expiryAt,previousExpiryAt:e.previousExpiryAt,totalTerm:e.totalTerm,totalBTCSats:o.totalBalance,totalUTXOs:o.totalUTXOs,authorizedSpendsSats:o.authorizedBalance,authorizedSpendsHash:o.authorizedSpendsHash,availableBTCSats:o.availableBalance,availableUTXOs:o.availableUTXOs,btcPriceUsd:i,collateralValueUsd:h.collateralValueUsd,collateralRatioBps:h.collateralRatioBps,termDurationDays:u.termDurationDays,termLengthDays:u.termLengthDays,isExpired:u.isExpired,daysUntilExpiry:u.daysUntilExpiry,daysIntoGracePeriod:u.daysIntoGracePeriod,currentLiquidationThreshold:d,isLiquidatable:p,marginToLiquidationBps:g,liquidationThresholdBps:s,originationFeeBps:l.originationFeeBps,extensionFeeBps:l.extensionFeeBps,timestamp:Date.now()}}buildStubbedBtcSnapshotInputs(t){const e=BigInt(this.config.debugOverrides?.stubbedAvailableBtcSats??"10000000"),r=BigInt(this.config.debugOverrides?.stubbedBtcPriceUsd??"5000000000000");return[{totalUTXOs:[],totalBalance:e,authorizedUTXOs:[],authorizedBalance:0n,authorizedSpendsHash:this.config.debugOverrides?.stubbedAuthorizedSpendsHash??ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["bytes32","bytes32[]"],[t.positionId,[]])),availableUTXOs:[],availableBalance:e,vaultAddress:t.vaultAddress,positionId:t.positionId,timestamp:Date.now()},r]}async queryPositionState(t){const e=t.startsWith("0x")?t:`0x${t.padStart(64,"0")}`;let r;r=this.config.rpcUrl?this.config.rpcUrl:await Lit.Actions.getRpcUrl({chain:this.config.chain});const o=new ethers.providers.StaticJsonRpcProvider({url:r,timeout:g},this.config.chainId),i=new ethers.Contract(this.config.contractAddress,[{inputs:[],name:"core",outputs:[{internalType:"address",name:"",type:"address"}],stateMutability:"view",type:"function"}],o),n=await i.core(),a=new ethers.Contract(n,[{inputs:[{internalType:"bytes32",name:"positionId",type:"bytes32"}],name:"getPositionDetails",outputs:[{components:[{internalType:"bytes32",name:"positionId",type:"bytes32"},{internalType:"bytes32",name:"pkpId",type:"bytes32"},{internalType:"uint256",name:"ucdDebt",type:"uint256"},{internalType:"string",name:"vaultAddress",type:"string"},{internalType:"address",name:"borrower",type:"address"},{internalType:"uint40",name:"createdAt",type:"uint40"},{internalType:"uint40",name:"lastUpdated",type:"uint40"},{internalType:"uint16",name:"selectedTerm",type:"uint16"},{internalType:"uint40",name:"expiryAt",type:"uint40"},{internalType:"enum LoanStatusLib.LoanStatus",name:"status",type:"uint8"},{internalType:"uint40",name:"previousExpiryAt",type:"uint40"},{internalType:"uint16",name:"totalTerm",type:"uint16"}],internalType:"struct IPositionManagerCore.Position",name:"",type:"tuple"}],stateMutability:"view",type:"function"}],o),s=await a.getPositionDetails(e),c=Number(s.status);if(c<0||c>7)throw console.error("[VaultSnapshot] INVALID STATUS - ABI decoding error detected"),console.error(" Position ID:",e),console.error(" Contract:",this.config.contractAddress),console.error(" Status decoded:",c,"(expected 0-7)"),console.error(" Full position:",JSON.stringify(s,null,2)),new Error(`Invalid position status decoded from contract: ${c} (expected 0-7). This indicates an ABI decoding issue. Position: ${e}`);const l=Number(s.expiryAt),u=Number(s.selectedTerm),d=Number(s.totalTerm),h=Number(s.previousExpiryAt),p=(w=u,0===(m=l)?0:m-30*w*86400);var m,w;return{positionId:s.positionId,pkpId:s.pkpId,borrower:s.borrower,vaultAddress:this.parseVaultAddress(s.vaultAddress,S(this.config.chain)),ucdDebt:BigInt(s.ucdDebt.toString()),termStartTimestamp:p,selectedTerm:u,status:c,expiryAt:l,previousExpiryAt:h,totalTerm:d}}parseVaultAddress(t,e){try{const r=JSON.parse(t);if("object"==typeof r&&null!==r){if("sepolia"===e.toLowerCase())return r.regtest||r.testnet||r.mainnet;const t=function(t){return b[t]}(e);return"testnet"===t&&(r.testnet||r.regtest)||r.mainnet}}catch(t){}return t}async isLiquidatable(t){return(await this.getVaultSnapshot(t)).isLiquidatable}async getCollateralRatio(t){return(await this.getVaultSnapshot(t)).collateralRatioBps}async getAvailableBalance(t){return(await this.getVaultSnapshot(t)).availableBTCSats}async hasSufficientCollateral(t,e,r){const o=await this.getVaultSnapshot(t);return function(t,e,r,o){const i=e+r;return 0n===i||Number(t*s*10000n/i)>=o}(o.collateralValueUsd,o.ucdDebt,e,r)}};var G="function getProtocolPauseStatus() view returns (tuple(bool positionManagerPaused, bool positionManagerLiquidationsPaused, bool positionManagerCorePaused, bool loanOperationsPaused, bool collateralManagerPaused, bool liquidationManagerPaused, bool circuitBreakerPaused, bool ucdControllerPaused, bool ucdTokenPaused, bool simplePsmPaused))",K={mintUcd:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","circuitBreakerPaused","ucdControllerPaused","ucdTokenPaused","simplePsmPaused"],withdrawBtc:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","collateralManagerPaused","circuitBreakerPaused","ucdControllerPaused","ucdTokenPaused","simplePsmPaused"],processPayment:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","circuitBreakerPaused","ucdControllerPaused","ucdTokenPaused"],extendPosition:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","circuitBreakerPaused","ucdControllerPaused","ucdTokenPaused","simplePsmPaused"],liquidation:["positionManagerLiquidationsPaused","liquidationManagerPaused","circuitBreakerPaused"],adminLiquidation:["positionManagerLiquidationsPaused","liquidationManagerPaused","circuitBreakerPaused"],btcTransactionSign:["positionManagerPaused","positionManagerCorePaused","loanOperationsPaused","collateralManagerPaused","circuitBreakerPaused"]};function J(t){return{positionManagerPaused:t.positionManagerPaused,positionManagerLiquidationsPaused:t.positionManagerLiquidationsPaused,positionManagerCorePaused:t.positionManagerCorePaused,loanOperationsPaused:t.loanOperationsPaused,collateralManagerPaused:t.collateralManagerPaused,liquidationManagerPaused:t.liquidationManagerPaused,circuitBreakerPaused:t.circuitBreakerPaused,ucdControllerPaused:t.ucdControllerPaused,ucdTokenPaused:t.ucdTokenPaused,simplePsmPaused:t.simplePsmPaused}}var Q=new ethers.utils.Interface(["function views() view returns (address)","function paused() view returns (bool)","function liquidationPaused() view returns (bool)","function simplePsm() view returns (address)"]),Y=new ethers.utils.Interface(["function core() view returns (address)","function loanOps() view returns (address)","function collateralManager() view returns (address)","function liquidationManager() view returns (address)","function circuitBreaker() view returns (address)"]),Z=new ethers.utils.Interface(["function getUcdController() view returns (address)","function ucdToken() view returns (address)"]),tt=new ethers.utils.Interface(["function paused() view returns (bool)"]);async function et(t,e,r){return t.call({to:e,data:r})}async function rt(t,e){const r=new ethers.utils.Interface([G]).encodeFunctionData("getProtocolPauseStatus",[]);let o;try{return function(t){const e=new ethers.utils.Interface([G]).decodeFunctionResult("getProtocolPauseStatus",t)[0];return Array.isArray(e)?J({positionManagerPaused:e[0],positionManagerLiquidationsPaused:e[1],positionManagerCorePaused:e[2],loanOperationsPaused:e[3],collateralManagerPaused:e[4],liquidationManagerPaused:e[5],circuitBreakerPaused:e[6],ucdControllerPaused:e[7],ucdTokenPaused:e[8],simplePsmPaused:e[9]}):J(e)}(await t.call({to:e,data:r}))}catch(t){o=t}try{return await async function(t,e){const r=await et(t,e,Q.encodeFunctionData("views",[])),[o]=Q.decodeFunctionResult("views",r),[i,n,a,s,c,l,u,d]=await Promise.all([et(t,e,Q.encodeFunctionData("paused",[])),et(t,e,Q.encodeFunctionData("liquidationPaused",[])),et(t,e,Q.encodeFunctionData("simplePsm",[])),et(t,o,Y.encodeFunctionData("core",[])),et(t,o,Y.encodeFunctionData("loanOps",[])),et(t,o,Y.encodeFunctionData("collateralManager",[])),et(t,o,Y.encodeFunctionData("liquidationManager",[])),et(t,o,Y.encodeFunctionData("circuitBreaker",[]))]),h=Q.decodeFunctionResult("paused",i)[0],p=Q.decodeFunctionResult("liquidationPaused",n)[0],g=Q.decodeFunctionResult("simplePsm",a)[0],m=Y.decodeFunctionResult("core",s)[0],w=Y.decodeFunctionResult("loanOps",c)[0],f=Y.decodeFunctionResult("collateralManager",l)[0],y=Y.decodeFunctionResult("liquidationManager",u)[0],b=Y.decodeFunctionResult("circuitBreaker",d)[0],T=await et(t,w,Z.encodeFunctionData("getUcdController",[])),v=await et(t,w,Z.encodeFunctionData("ucdToken",[])),S=Z.decodeFunctionResult("getUcdController",T)[0],P=Z.decodeFunctionResult("ucdToken",v)[0],E=async e=>{if(!e||e===ethers.constants.AddressZero)return!1;try{const r=await et(t,e,tt.encodeFunctionData("paused",[]));return tt.decodeFunctionResult("paused",r)[0]}catch{return!1}},[$,A,I,C,B,U,M,x]=await Promise.all([E(m),E(w),E(f),E(y),E(b),E(S),E(P),E(g)]);return J({positionManagerPaused:h,positionManagerLiquidationsPaused:p,positionManagerCorePaused:$,loanOperationsPaused:A,collateralManagerPaused:I,liquidationManagerPaused:C,circuitBreakerPaused:B,ucdControllerPaused:U,ucdTokenPaused:M,simplePsmPaused:x})}(t,e)}catch(t){const e=o instanceof Error?o.message:String(o),r=t instanceof Error?t.message:String(t);throw new Error(`getProtocolPauseStatus failed (aggregate: ${e}; decomposed: ${r})`)}}function ot(t){if("string"!=typeof t)throw new Error("positionId must be a string");const e=t.trim(),r=/^0x/i.test(e)?e.slice(2):e;if(0===r.length)throw new Error("positionId is empty");if(!/^[0-9a-fA-F]+$/.test(r))throw new Error("positionId must be hexadecimal (bytes32)");if(r.length>64)throw new Error("positionId exceeds 32 bytes");return"0x"+r.padStart(64,"0").toLowerCase()}var it={hardhat:{chain:"hardhat",chainId:v.hardhat,bitcoinNetwork:b.hardhat,allowArbitraryBitcoinProvider:!0,allowArbitraryEvmRpc:!0,minBitcoinConfirmations:1},sepolia:{chain:"sepolia",chainId:v.sepolia,bitcoinNetwork:b.sepolia,allowArbitraryBitcoinProvider:!1,allowArbitraryEvmRpc:!1,minBitcoinConfirmations:1},ethereum:{chain:"ethereum",chainId:v.ethereum,bitcoinNetwork:b.ethereum,allowArbitraryBitcoinProvider:!1,allowArbitraryEvmRpc:!1,minBitcoinConfirmations:6}};var nt,at=[{inputs:[{internalType:"uint256",name:"chainId",type:"uint256"}],name:"getProviders",outputs:[{internalType:"bytes32[]",name:"ids",type:"bytes32[]"},{components:[{internalType:"bytes",name:"ciphertext",type:"bytes"},{internalType:"bytes32",name:"pkpId",type:"bytes32"},{internalType:"uint64",name:"addedAt",type:"uint64"}],internalType:"struct BitcoinProviderRegistry.ProviderEntry[]",name:"entries",type:"tuple[]"}],stateMutability:"view",type:"function"}];async function st(t,e){const r=66===e.length?"0x"+e.slice(-40):e;try{const e=await Lit.Actions.Decrypt({pkpId:r,ciphertext:t}),o="string"==typeof e?e:String(e??"");if(!o)throw new Error("Decrypt returned empty plaintext");return o}catch(t){throw new Error(`Failed to decrypt Bitcoin provider URL (pkpId=${e}): ${t?.message??String(t)}`)}}async function ct(t){const{policy:e,bitcoinProviderUrl:r,ethersProvider:o,registryAddress:i}=t;if(!r||"string"!=typeof r)throw new Error("resolveBitcoinProviderForPolicy: bitcoinProviderUrl is required");if(e.allowArbitraryBitcoinProvider)return{name:"Custom Provider",url:r,minConfirmations:e.minBitcoinConfirmations,network:e.bitcoinNetwork};if(!i)throw new Error(`Bitcoin provider registry address is required on chain "${e.chain}" \u2014 set contractAddresses.BitcoinProviderRegistry. Hardcoded allowlists have been removed (see audit C-1/H-6 fix).`);const n=await async function(t,e,r){if(!r||"string"!=typeof r)throw new Error("fetchBitcoinProviderEntries: registryAddress (BitcoinProviderRegistry) is required");if(!e)throw new Error("fetchBitcoinProviderEntries: ethers provider is required");const o=new ethers.Contract(r,at,e),[i,n]=await o.getProviders(t),a=[];for(let t=0;t<i.length;t++)a.push({providerId:i[t],ciphertext:n[t].ciphertext,pkpId:n[t].pkpId,addedAt:Number(n[t].addedAt)});return a}(e.chainId,o,i);if(0===n.length)throw new Error(`No Bitcoin providers registered for chainId=${e.chainId} in ${i}. Admin must addProvider(...) via AdminModule before LIT Actions can sign.`);const a=await async function(t,e){if(!e)throw new Error("matchAllowedProviderUrl: candidateUrl is required");for(const r of t)if(await st(r.ciphertext,r.pkpId)===e)return r.providerId;return null}(n,r);if(!a)throw new Error(`Bitcoin provider URL not in any registered encrypted slot for chainId=${e.chainId}`);return{name:`Registry Provider ${a.slice(0,10)}`,url:r,minConfirmations:e.minBitcoinConfirmations,network:e.bitcoinNetwork}}function lt(t){if(/^(bc1|tb1|bcrt1)[0-9a-zA-Z]{11,87}$/.test(t)){const e=function(t){const e="qpzry9x8gf2tvdw0s3jn54khce6mua7l",r=t.lastIndexOf("1");if(r<1)throw new Error("No separator character for bech32");t.substring(0,r).toLowerCase();const o=t.substring(r+1).toLowerCase(),i=[];for(let t=0;t<o.length;t++){const r=e.indexOf(o[t]);if(-1===r)throw new Error(`Invalid bech32 character: ${o[t]}`);i.push(r)}const n=i.slice(0,-6),a=(n[0],function(t,e,r,o){let i=0,n=0;const a=[],s=(1<<r)-1;for(let o=0;o<t.length;o++){const c=t[o];if(c<0||c>>e)throw new Error("Invalid data for bit conversion");for(i=i<<e|c,n+=e;n>=r;)n-=r,a.push(i>>n&s)}if(o)n>0&&a.push(i<<r-n&s);else if(n>=e||i<<r-n&s)throw new Error("Invalid padding in bit conversion");return a}(n.slice(1),5,8,!1));return{witnessProgram:a.map((t=>t.toString(16).padStart(2,"0"))).join("")}}(t);return"0014"+e.witnessProgram}{const e=function(t){const e="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";let r=0n;for(let o=0;o<t.length;o++){const i=e.indexOf(t[o]);if(i<0)throw new Error(`Invalid Base58 character: ${t[o]}`);r=58n*r+BigInt(i)}let o=r.toString(16);o.length%2&&(o="0"+o);for(let e=0;e<t.length&&"1"===t[e];e++)o="00"+o;return o}(t);return"76a914"+e.slice(2,e.length-8)+"88ac"}}async function main(t){for(const[e,r]of Object.entries(t))globalThis[e]=r;const e=M.create("BTC Withdrawal Validator");console.log("[Step 0] Validating configuration..."),e.stepStart("0","Validate configuration parameters");const r=globalThis.chain,o=globalThis.bitcoinProviderUrl;if(!r)throw new Error('Missing required parameter: "chain". Must be "sepolia" or "ethereum"');if(!o)throw new Error('Missing required parameter: "bitcoinProviderUrl". Must be an approved Bitcoin RPC provider URL');const i=function(t){const e=S(t),r=it[e];if(!r)throw new Error(`No chain policy registered for "${t}"`);return r}(r),n=i.chain,a=i.bitcoinNetwork;let s;if(console.log(` \u2705 Chain: ${r} (${n})`),console.log(` \u2705 Bitcoin Network: ${a}`),!globalThis.contractAddresses||"object"!=typeof globalThis.contractAddresses)throw new Error('Required "contractAddresses" object with: PositionManager, LoanOperationsManagerModule, TermManagerModule');const p=globalThis.contractAddresses.PositionManager,g=globalThis.contractAddresses.LoanOperationsManagerModule,y=globalThis.contractAddresses.TermManagerModule,b=globalThis.contractAddresses.UCDController,v=globalThis.contractAddresses.LITActionValidator,E=globalThis.contractAddresses.LiquidationManagerModule??globalThis.contractAddresses.LiquidationManager??"",$=globalThis.contractAddresses.BTCSpendAuthorizer??"";if(!(p&&g&&y&&b&&E))throw new Error("All contract addresses are required: PositionManager, LoanOperationsManagerModule, TermManagerModule, UCDController, and LiquidationManager or LiquidationManagerModule");console.log(" \u2705 Contract addresses loaded and validated"),console.log(` PositionManager: ${p}`),console.log(` LoanOpsManager: ${g}`),e.stepEnd("0"),console.log("[Step 0.5] Critical system health checks..."),e.stepStart("0.5","Critical system health checks"),e.warn("0.5","System health checks temporarily disabled (SystemHealthModule not available)"),e.log("0.5","\u2705 System health checks complete (skipped)"),e.stepEnd("0.5");const I=globalThis.auth;if(!I||"object"!=typeof I)throw new Error('Missing or invalid "auth" parameter - must be an object');if(!I.positionId)throw new Error("auth.positionId is required");if("number"!=typeof I.timestamp)throw new Error("auth.timestamp must be a number");if(!I.signature)throw new Error("auth.signature is required");const C=BigInt(I.amount);if(C<=0n)throw new Error(`Withdrawal amount must be positive, got: ${C.toString()} sats`);const B=u;if(C<B)throw new Error(`Withdrawal amount ${C.toString()} sats is below minimum ${B.toString()} sats (Bitcoin dust limit). This amount is not economically viable for Bitcoin network transactions.`);const U=I.destinationAddress;if(!U||"string"!=typeof U)throw new Error('Missing or invalid "destinationAddress" parameter - must be a valid Bitcoin address');const D=x().publicKey;if(!D)throw new Error("publicKey must not be blank");if("string"!=typeof D||0===D.length)throw new Error("publicKey must not be blank");const O=D;if(!(()=>{try{const t=/^[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{26,35}$/.test(U),e=/^(bc1|tb1|bcrt1)[0-9a-zA-Z]{11,87}$/.test(U);return!(!t&&!e)&&("testnet"===a||"regtest"===a?U.startsWith("m")||U.startsWith("n")||U.startsWith("2")||U.startsWith("tb1")||U.startsWith("bcrt1"):"mainnet"===a&&(U.startsWith("1")||U.startsWith("3")||U.startsWith("bc1")))}catch(t){return!1}})())throw new Error(`Invalid Bitcoin address format for ${a} network: ${U}. Expected ${"mainnet"===a?"address starting with 1, 3, or bc1":"address starting with m, n, 2, tb1, or bcrt1"}`);console.log(` \u2705 Destination address validated: ${U} (${a})`);let N="0.5";try{console.log("[BTC Withdrawal] Started"),console.log(` Position: ${I.positionId}`),console.log(` Withdrawal Amount: ${C.toString()} sats`),console.log(` Destination Address: ${U}`);const t=new R(globalThis.priceProviders,void 0),a=globalThis.rpcUrl;let u;a&&"string"==typeof a?(!function(t,e){if(t.allowArbitraryEvmRpc)return;if(!e||"string"!=typeof e)throw new Error("validateEvmRpcForPolicy: rpcUrl must be a non-empty string");let r;try{r=new URL(e).hostname}catch(t){throw new Error(`Invalid rpcUrl: ${t?.message??String(t)}`)}if(!T.some((t=>r===t||r.endsWith(`.${t}`))))throw new Error(`Custom RPC domain "${r}" is not in the approved list: ${T.join(", ")}`)}(i,a),console.log(` Using RPC URL override: ${function(t){if(null==t||"string"!=typeof t)return"[missing]";let e=t.replace(/([?&])(dkey|apikey|api_key|key|token|secret|password|auth|authorization)=[^&]*/gi,"$1$2=[REDACTED]");try{const t=new URL(e);(t.username||t.password)&&(t.username="",t.password="",e=t.toString())}catch{}return e}(a)}`),u=a):(u=await Lit.Actions.getRpcUrl({chain:r}),console.log(` Using LIT-provided RPC URL for chain: ${r}`));const S=new ethers.providers.JsonRpcProvider(u);s=await ct({policy:i,bitcoinProviderUrl:o,ethersProvider:S,registryAddress:globalThis.contractAddresses.BitcoinProviderRegistry}),console.log(` \u2705 Bitcoin Provider: ${s.name} (min confs ${s.minConfirmations})`);const B=new k({providerUrl:s.url});!function(t,e){const r=K[t],o=[];for(const t of r)e[t]&&o.push(t);if(o.length>0)throw new Error(JSON.stringify({code:"PROTOCOL_PAUSED",operation:t,paused:o,status:e}))}("withdrawBtc",await rt(S,p));const M=(L={contractAddress:$||g,chain:r,chainId:P(n),rpcUrl:u,bitcoinProvider:B,minConfirmations:s.minConfirmations},new q(L));N="1",console.log("[Step 1] Getting vault snapshot..."),e.stepStart("1","Get vault snapshot");const x=function(t){return new j(t)}({contractAddress:p,termManagerAddress:y,loanOpsManagerAddress:g,liquidationManagerAddress:E,chain:r,chainId:P(n),rpcUrl:u,vaultBalance:M,priceOracle:t}),D=await x.getVaultSnapshot(I.positionId);console.log(` \u2705 Vault balance: ${D.availableBTCSats.toString()} sats`),console.log(` \u2705 Current debt: ${D.ucdDebt.toString()} wei`),e.stepEnd("1"),N="2",console.log("[Step 2] Authenticating caller..."),e.stepStart("2","Authenticate caller");const F=e.getElapsed();console.log(`[TIMING] Step 2 started at ${F}ms`);const _=P(n),H=new ethers.providers.StaticJsonRpcProvider(u,_);let W;if(5===D.status){if(!v)throw new Error("LITActionValidator address required for LIQUIDATED position withdrawals. Pass contractAddresses.LITActionValidator in jsParams.");const t=new ethers.Contract(v,["function pkpOwners(bytes32) view returns (address)"],H);if(W=await t.pkpOwners(D.pkpId),!W||W===ethers.constants.AddressZero)throw new Error("No PKP owner registered for this liquidated position in LITActionValidator");console.log(` \u2139\ufe0f LIQUIDATED position \u2014 verifying against PKP owner: ${W}`)}else W=D.borrower;if(!await A.verifyWithdrawAuthorization(I,W,H))throw new Error("Caller not authorized");console.log(" \u2705 Caller authorized"),e.stepEnd("2"),N="2.5",console.log("[Step 2.5] Validating position status..."),e.stepStart("2.5","Validate position status");const G=e.getElapsed();console.log(`[TIMING] Step 2.5 started at ${G}ms`);if(![0,1,2,6,5].includes(D.status))throw new Error(`Position status ${m(D.status)} does not allow withdrawal. Valid statuses: PENDING_DEPOSIT, PENDING_MINT, ACTIVE, REPAID, LIQUIDATED.`);console.log(` \u2705 Position status valid for withdrawal: ${m(D.status)}`),e.stepEnd("2.5"),N="3",console.log("[Step 3] Validating post-withdrawal collateral ratio..."),e.stepStart("3","Validate collateral ratio");const J=e.getElapsed();console.log(`[TIMING] Step 3 started at ${J}ms`);const Q=C;if(0n===D.ucdDebt)console.log(" \u2705 Position has zero debt - withdrawal allowed");else{if(D.btcPriceUsd<c||D.btcPriceUsd>l)throw new Error(`Bitcoin price ${D.btcPriceUsd} is outside acceptable range (${c} - ${l}). This may indicate oracle manipulation or stale price data. Please try again later.`);console.log(` \u2705 BTC price validation passed: $${(Number(D.btcPriceUsd)/1e8).toFixed(2)}`);const t=D.availableBTCSats-Q,e=X(z(t,D.btcPriceUsd),D.ucdDebt);if(e<D.liquidationThresholdBps)throw new Error(`Insufficient collateral: post-withdrawal ratio ${V(e)}% < liquidation threshold ${V(D.liquidationThresholdBps)}%. Withdrawal would result in insufficient collateralization.`);console.log(` \u2705 Post-withdrawal collateral ratio: ${V(e)}%`),console.log(` \u2705 Exceeds liquidation threshold: ${V(D.liquidationThresholdBps)}%`)}e.stepEnd("3"),N="4",console.log("[Step 4] Validating withdrawal amount and balance..."),e.stepStart("4","Validate withdrawal amount and balance");const Y=e.getElapsed();console.log(`[TIMING] Step 4 started at ${Y}ms`);const Z="string"==typeof I.amount?BigInt(I.amount):I.amount;if(Z!==C)throw new Error(`Authorization amount mismatch: auth.amount=${Z.toString()} sats, but requested withdrawal=${C.toString()} sats. The signed authorization must match the requested withdrawal amount.`);if(console.log(" \u2705 Authorization amount matches withdrawal amount"),Q>D.availableBTCSats)throw new Error(`Insufficient vault balance: need ${Q.toString()} sats but only ${D.availableBTCSats.toString()} sats available`);console.log(" \u2705 Total deduction is within available balance");const tt=D.availableBTCSats-Q,et=D.ucdDebt,it=z(tt,D.btcPriceUsd),nt=et>0n?X(it,et):void 0;if(console.log(` Post-withdrawal collateral: ${tt.toString()} sats`),console.log(` Post-withdrawal collateral value: $${(Number(it)/1e8).toFixed(2)}`),console.log(` Post-withdrawal debt: ${et.toString()} wei`),console.log(` Post-withdrawal collateral ratio: ${et>0n&&void 0!==nt?V(Number(nt)):"\u221e"}%`),tt<0n)throw new Error(`Withdrawal would result in negative balance: ${tt.toString()} sats`);console.log(" \u2705 Withdrawal validation passed"),e.stepEnd("4"),N="4.5",console.log("[Step 4.5] Querying vault UTXOs from Bitcoin network..."),e.stepStart("4.5","Query and select UTXO");const at=e.getElapsed();console.log(`[TIMING] Step 4.5 started at ${at}ms`);const st=D.vaultAddress;if(!st)throw new Error("Vault address not found in snapshot");console.log(` Vault address: ${st}`);let ut=[],dt=null;const ht=d,pt=h;for(let t=1;t<=ht;t++)try{console.log(` \ud83d\udd04 UTXO query attempt ${t}/${ht}...`),ut=await B.getUTXOs(st),console.log(` \u2705 UTXO query succeeded on attempt ${t}`),dt=null;break}catch(e){dt=e,console.error(` \u274c UTXO query failed on attempt ${t}:`,e.message),t<ht&&(console.log(` \u23f3 Waiting ${pt}ms before retry...`),await new Promise((t=>setTimeout(t,pt))))}if(dt)throw new Error(`Failed to query UTXOs after ${ht} attempts: ${dt.message}`);if(!ut||0===ut.length)throw new Error(`No UTXOs found in vault ${st}`);console.log(` \u2705 Found ${ut.length} UTXO(s) in vault`);const gt=s.minConfirmations,mt=ut.filter((t=>t.confirmations>=gt));if(0===mt.length)throw new Error(`No confirmed UTXOs found in vault. Required confirmations: ${gt}, found ${ut.length} UTXO(s) with insufficient confirmations.`);console.log(` \u2705 Found ${mt.length} confirmed UTXO(s)`);const wt=mt.filter((t=>t.satoshis>=Q));let ft;if(0===wt.length){const t=mt.reduce(((t,e)=>t+e.satoshis),0n);if(t<Q)throw new Error(`Insufficient vault balance for withdrawal. Need ${Q.toString()} sats, total across ${mt.length} UTXO(s): ${t.toString()} sats.`);ft=[...mt].sort(((t,e)=>Number(e.satoshis-t.satoshis)))[0],console.log(" \u2139\ufe0f No single UTXO covers withdrawal \u2014 multi-UTXO consolidation will be used in Phase 2."),console.log(` Primary UTXO (contract auth): ${ft.txid}:${ft.vout} (${ft.satoshis.toString()} sats)`)}else ft=wt.sort(((t,e)=>Number(t.satoshis-e.satoshis)))[0];console.log(` \u2705 Selected UTXO: ${ft.txid}:${ft.vout}`),console.log(` \u2705 UTXO value: ${ft.satoshis.toString()} sats`),console.log(` \u2705 UTXO confirmations: ${ft.confirmations}`);const yt=D.availableBTCSats;if(ft.satoshis<yt&&console.warn(` \u26a0\ufe0f Selected UTXO value (${ft.satoshis.toString()}) < calculated balance (${yt.toString()}). This is expected for multi-UTXO vaults where we select one UTXO.`),ft.satoshis<Q)throw new Error(`Selected UTXO value (${ft.satoshis.toString()} sats) < withdrawal amount (${Q.toString()} sats). This should never happen after eligibility filtering.`);console.log(" \u2705 UTXO validation passed"),console.log(" \ud83d\udd0d Verifying UTXO vout against Bitcoin transaction...");const bt=lt(st).toLowerCase(),Tt=await B.getTransactionOutputs(ft.txid);if(!Tt)throw new Error(`Could not fetch transaction outputs for ${ft.txid} \u2014 cannot canonicalize vout. Refusing to authorize potentially incorrect UTXO. Retry the withdrawal once the Bitcoin data provider is reachable.`);let vt=-1;for(const t of Tt){const e=(t.scriptpubkey??"").toLowerCase(),r=e.length>0&&e===bt,o=t.scriptpubkey_address===st;if(r||o){vt=t.index;break}}if(-1===vt)throw new Error(`Vault output not found in tx ${ft.txid}. Expected scriptPubKey ${bt} or address ${st}, but no output in the transaction matches. Refusing to authorize wrong UTXO.`);vt!==ft.vout?(console.log(` \u26a0\ufe0f Esplora API reported vout=${ft.vout} but vault output is at vout=${vt} (matched on hex scriptpubkey). Correcting.`),ft={...ft,vout:vt}):console.log(` \u2705 UTXO vout=${ft.vout} confirmed correct`),e.stepEnd("4.5"),N="5",console.log("[Step 5] Building authorization message..."),e.stepStart("5","Build authorization message");const St=e.getElapsed();console.log(`[TIMING] Step 5 started at ${St}ms`);const Pt=ethers.utils.keccak256(ethers.utils.toUtf8Bytes(I.action)),Et=D.authorizedSpendsHash,$t=ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["uint256"],[D.ucdDebt])),At=ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["address","address","address","address"],[p,g,y,b])),It=BigInt(I.timestamp),Ct=tt,Bt=D.btcPriceUsd;if(Bt<c||Bt>l)throw new Error(`BTC price ${Bt.toString()} (8 decimals) is outside acceptable range (${c.toString()} - ${l.toString()})`);console.log("[Step 5] DEBUG: Message Hash Parameters:"),console.log(" positionId:",I.positionId),console.log(" action:",I.action),console.log(" actionHash:",Pt),console.log(" authorizedSpendsHash:",Et),console.log(" ucdDebtHash:",$t),console.log(" withdrawalAddress:",U),console.log(" totalDeduction:",Q.toString()),console.log(" newCollateral:",Ct.toString()),console.log(" quantumTimestamp:",It.toString()),console.log(" btcPrice:",Bt.toString()),console.log(" utxoTxid:",ft.txid),console.log(" utxoVout:",ft.vout);const Ut=ot(I.positionId),Mt=P(n),xt={name:w,version:f,chainId:Mt,verifyingContract:ethers.utils.getAddress(g)},Dt={WithdrawalAuthorization:[{name:"positionId",type:"bytes32"},{name:"actionHash",type:"bytes32"},{name:"authorizedSpendsHash",type:"bytes32"},{name:"ucdDebtHash",type:"bytes32"},{name:"contractBundleHash",type:"bytes32"},{name:"withdrawalAddress",type:"string"},{name:"totalDeduction",type:"uint256"},{name:"newCollateral",type:"uint256"},{name:"quantumTimestamp",type:"uint256"},{name:"btcPrice",type:"uint256"},{name:"utxoTxid",type:"string"},{name:"utxoVout",type:"uint32"}]},Ot=ethers.utils._TypedDataEncoder.hash(xt,Dt,{positionId:Ut,actionHash:Pt,authorizedSpendsHash:Et,ucdDebtHash:$t,contractBundleHash:At,withdrawalAddress:U,totalDeduction:Q.toString(),newCollateral:Ct.toString(),quantumTimestamp:It.toString(),btcPrice:Bt.toString(),utxoTxid:ft.txid,utxoVout:ft.vout});console.log("[Step 5] Contract message hash for signing:",Ot),console.log("[Step 5] Message hash bytes length:",ethers.utils.arrayify(Ot).length),e.stepEnd("5"),N="6",console.log("[Step 6] Signing contract message hash..."),e.stepStart("6","Sign message");const kt=e.getElapsed();console.log(`[TIMING] Step 6 started at ${kt}ms`),e.log("6","========================================"),e.log("6","\ud83d\udd0d FINAL HASH INPUTS - ALL LIT NODES MUST MATCH"),e.log("6","========================================"),e.log("6",`Position ID: ${I.positionId}`),e.log("6",`Action Hash: ${Pt}`),e.log("6",`Authorized Spends Hash: ${Et}`),e.log("6",`UCD Debt Hash: ${$t}`),e.log("6",`Contract Bundle Hash: ${At}`),e.log("6",`Destination Address: ${U}`),e.log("6",`Total Deduction: ${Q.toString()}`),e.log("6",`New Collateral: ${Ct.toString()}`),e.log("6",`Quantum Timestamp: ${It.toString()}`),e.log("6",`BTC Price: ${Bt.toString()}`),e.log("6",`Selected UTXO Txid: ${ft.txid}`),e.log("6",`Selected UTXO Vout: ${ft.vout}`),e.log("6",`Selected UTXO Satoshis: ${ft.satoshis.toString()}`),e.log("6",`Selected UTXO Confirmations: ${ft.confirmations}`),e.log("6","---"),e.log("6",`\ud83d\udcdd FINAL CONTRACT MESSAGE HASH: ${Ot}`),e.log("6","========================================"),e.log("6","Preparing signEcdsa call"),e.log("6",`contractMessageHash: ${Ot}`),e.log("6",`publicKey: ${O}`),e.log("6","publicKey with 0x prefix: "+("0x"+O));const Nt=ethers.utils.arrayify(Ot);e.log("6",`messageBytes length: ${Nt.length}`),e.log("6",`messageBytes: ${JSON.stringify(Array.from(Nt))}`),e.log("6","About to sign with wallet-derived key (Chipotle)...");const Rt=Date.now(),qt=globalThis.validatorWalletAddress;if(!qt||!qt.startsWith("0x"))throw new Error("validatorWalletAddress required \u2014 must be a createWallet-derived address");const Lt=await Lit.Actions.getPrivateKey({pkpId:qt}),Ft="string"==typeof Lt?Lt.startsWith("0x")?Lt:`0x${Lt}`:String(Lt),_t=new ethers.Wallet(Ft),zt=new ethers.utils.SigningKey(Ft);e.log("6",`Wallet-derived signer address: ${_t.address}`),e.log("6",`validatorWalletAddress: ${qt}`);const Xt=zt.signDigest(Ot),Vt=ethers.utils.joinSignature(Xt),Ht=Date.now()-Rt;e.log("6",`Chipotle signature created in ${Ht}ms`),e.log("6",`signature: ${Vt}`);const Wt=globalThis.contractAddresses.BTCSpendAuthorizer?.trim()||"";let jt=null;if(Wt){const t=ot(I.positionId),r=P(n),o=Ct+Q,i={name:w,version:f,chainId:r,verifyingContract:ethers.utils.getAddress(Wt)},a={BtcSpendAuth:[{name:"positionId",type:"bytes32"},{name:"txid",type:"string"},{name:"vout",type:"uint32"},{name:"satoshis",type:"uint256"},{name:"targetAddress",type:"string"},{name:"targetAmount",type:"uint256"}]},s=ethers.utils._TypedDataEncoder.hash(i,a,{positionId:t,txid:ft.txid,vout:ft.vout,satoshis:o.toString(),targetAddress:U,targetAmount:Q.toString()});e.log("6",`EIP-712 BtcSpendAuth digest: ${s}`),jt=await _t._signTypedData(i,a,{positionId:t,txid:ft.txid,vout:ft.vout,satoshis:o.toString(),targetAddress:U,targetAmount:Q.toString()}),e.log("6",`btcSpendAuth signature: ${jt}`)}e.stepEnd("6"),console.log("[BTC Withdrawal] \u2705 Complete"),e.summary();const Gt={approved:!0,positionId:I.positionId,actionHash:Pt,authorizedSpendsHash:Et,ucdDebtHash:$t,contractBundleHash:At,totalDeduction:Q.toString(),remainingCollateral:tt.toString(),newCollateralRatioBps:et>0n&&void 0!==nt?Number(nt):void 0,destinationAddress:U,signature:Vt,btcSpendAuthSignature:jt,timestamp:It.toString(),btcPrice:Bt.toString(),utxoTxid:ft.txid,utxoVout:ft.vout,utxoSatoshis:ft.satoshis.toString()};return console.log("[BTC Withdrawal] \ud83d\udd0d Response data before JSON.stringify:"),console.log(" totalDeduction:",Q,"type:",typeof Q,"toString():",Q.toString()),console.log(" remainingCollateral:",tt,"type:",typeof tt,"toString():",tt.toString()),console.log(" btcPrice:",Bt,"type:",typeof Bt,"toString():",Bt.toString()),console.log(" timestamp:",It,"type:",typeof It,"toString():",It.toString()),console.log(" Full response object:",JSON.stringify(Gt,null,2)),Gt}catch(t){return console.error("[BTC Withdrawal] \u274c Failed:",t.message),console.error(`[BTC Withdrawal] Failed at step: ${N}`),e.error("error",`Failed: ${t.message}`),{approved:!1,reason:t.message||t.toString(),positionId:I?.positionId,timestamp:Date.now()}}var L}return nt=i,((i,n,a,s)=>{if(n&&"object"==typeof n||"function"==typeof n)for(let c of r(n))o.call(i,c)||c===a||t(i,c,{get:()=>n[c],enumerable:!(s=e(n,c))||s.enumerable});return i})(t({},"__esModule",{value:!0}),nt)})();if("object"==typeof _LIT_ACTION_)if("function"==typeof _LIT_ACTION_.main)var main=_LIT_ACTION_.main;else"function"==typeof _LIT_ACTION_.go&&_LIT_ACTION_.go();
@@ -1 +1 @@
1
- 1b85e8e2951fb7cc7368981949f024c453528dac7eff0b505ef470a470b3c15e
1
+ 5d2d3672dfa4027fd17d6bf4740995561ccc4dbe1ed388be19c241ecf5f4018f
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "actionName": "btc-withdrawal",
3
- "originalSize": 162838,
4
- "minifiedSize": 70563,
5
- "compressionRatio": 0.566667485476363,
6
- "hash": "1b85e8e2951fb7cc7368981949f024c453528dac7eff0b505ef470a470b3c15e",
7
- "buildTime": 1777471361161,
3
+ "originalSize": 166220,
4
+ "minifiedSize": 72236,
5
+ "compressionRatio": 0.5654193237877512,
6
+ "hash": "5d2d3672dfa4027fd17d6bf4740995561ccc4dbe1ed388be19c241ecf5f4018f",
7
+ "buildTime": 1777481711779,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 832,
5
5
  "compressionRatio": 0.5026897788404064,
6
6
  "hash": "700f8992a20357ac718df78f82a75641e892d24bcb925357087cf062cf521ae0",
7
- "buildTime": 1777471361169,
7
+ "buildTime": 1777481711785,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 60870,
5
5
  "compressionRatio": 0.5872660699755898,
6
6
  "hash": "624cbc2514b8be7b2e8cc3a509dce282db9213e43a7675f058ecebe4eb9faa40",
7
- "buildTime": 1777471361327,
7
+ "buildTime": 1777481711924,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 54907,
5
5
  "compressionRatio": 0.5623056932863543,
6
6
  "hash": "7a5a63dc80fad2258a0361f767f3efae3a62ec391c34b0927ca770411bf4de3e",
7
- "buildTime": 1777471361623,
7
+ "buildTime": 1777481712149,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 44293,
5
5
  "compressionRatio": 0.5770259172253098,
6
6
  "hash": "70b009f01b9051dee2db1e4030dd17d08dc53728d30b5e24cffd11d07acfcaf0",
7
- "buildTime": 1777471361776,
7
+ "buildTime": 1777481712294,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 3999,
5
5
  "compressionRatio": 0.5142128279883382,
6
6
  "hash": "baba8c31b73dbfe6425d8f9fd69c61f41a573e189a185962382b815a15fddb24",
7
- "buildTime": 1777471361796,
7
+ "buildTime": 1777481712313,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 11531,
5
5
  "compressionRatio": 0.5730366201355204,
6
6
  "hash": "a49e9a4875e68a1b8f1c37bcc8284a28e0995652a7df8bad4f1853408d1c81c8",
7
- "buildTime": 1777471361825,
7
+ "buildTime": 1777481712373,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 2139,
5
5
  "compressionRatio": 0.45153846153846156,
6
6
  "hash": "6d5742652cd9a2c562db3f69663a133d38b95330cbb89b5e84876644c1c10d0a",
7
- "buildTime": 1777471361831,
7
+ "buildTime": 1777481712396,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 61413,
5
5
  "compressionRatio": 0.5780683192261185,
6
6
  "hash": "2ffbd15b1429edb7ddc7587ea8d30d45d4182a2bd3fc22e5986f9b4850440a9b",
7
- "buildTime": 1777471361946,
7
+ "buildTime": 1777481712742,
8
8
  "version": "0.1.0"
9
9
  }
@@ -4,6 +4,6 @@
4
4
  "minifiedSize": 65507,
5
5
  "compressionRatio": 0.576488918772143,
6
6
  "hash": "f079aa1fc53fe04b08508379feba5d55d2d334ab9ee21bee043c05cf592eced3",
7
- "buildTime": 1777471362090,
7
+ "buildTime": 1777481712971,
8
8
  "version": "0.1.0"
9
9
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gvnrdao/dh-lit-actions",
3
- "version": "0.0.282",
3
+ "version": "0.0.284",
4
4
  "type": "commonjs",
5
5
  "description": "Diamond Hands Protocol LIT Actions - Deterministic, Auditable Builds",
6
6
  "main": "pkg-dist/pkg-src/index.js",
@@ -739,17 +739,17 @@ var DH_LIT_ACTIONS_CHIPOTLE = {
739
739
  }
740
740
  },
741
741
  btcWithdrawal: {
742
- cid: "Qmds87V3zYoZJMDCNPjqrnYTWKwHQqZ2WqMTtV9F5c5NDc",
742
+ cid: "QmQC7QKobtNJKArGK7rgGj8ZCcEWt1pBKXPyd5SZ2fi4tt",
743
743
  authorizedCidHex: cidToHex(
744
- "Qmds87V3zYoZJMDCNPjqrnYTWKwHQqZ2WqMTtV9F5c5NDc"
744
+ "QmQC7QKobtNJKArGK7rgGj8ZCcEWt1pBKXPyd5SZ2fi4tt"
745
745
  ),
746
746
  name: "Btc Withdrawal",
747
747
  description: "Production Btc Withdrawal",
748
- version: "1.0.0",
748
+ version: "1.0.1",
749
749
  deployed: true,
750
- deployedAt: 1777311512905,
751
- size: 70563,
752
- hash: "1b85e8e2951fb7cc7368981949f024c453528dac7eff0b505ef470a470b3c15e",
750
+ deployedAt: 1777474196351,
751
+ size: 72236,
752
+ hash: "5d2d3672dfa4027fd17d6bf4740995561ccc4dbe1ed388be19c241ecf5f4018f",
753
753
  validatorWalletAddress: "0xbb137fbda353199e9419b698c57a742124d4987d",
754
754
  pkp: {
755
755
  publicKey: "0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../pkg-src/utils/chunks/debug-logger.ts", "../../pkg-src/utils/chunks/session-signature-cache.ts", "../../pkg-src/index.ts", "../../node_modules/base-x/src/esm/index.js", "../../node_modules/bs58/src/esm/index.js", "../../pkg-src/utils/chunks/cid-utils.ts", "../../pkg-src/constants/chunks/lit-actions-registry.ts", "../../pkg-src/utils/chunks/lit-action-helpers.ts", "../../pkg-src/utils/chunks/pkp-setup.ts", "../../pkg-src/utils/chunks/connection-helpers.ts", "../../pkg-src/utils/chunks/error-classification.ts", "../../pkg-src/utils/index.ts"],
4
- "sourcesContent": ["/**\n * Enhanced Debug Logger for LIT Protocol Operations\n * Provides detailed logging for debugging network and protocol issues\n */\n\nexport enum LogLevel {\n ERROR = 0,\n WARN = 1,\n INFO = 2,\n DEBUG = 3,\n TRACE = 4\n}\n\nexport interface DebugConfig {\n level: LogLevel;\n enableTimestamps: boolean;\n enablePerformanceMetrics: boolean;\n enableRequestLogging: boolean;\n enableNetworkMetrics: boolean;\n}\n\nexport const DEFAULT_DEBUG_CONFIG: DebugConfig = {\n level: LogLevel.INFO,\n enableTimestamps: true,\n enablePerformanceMetrics: true,\n enableRequestLogging: true,\n enableNetworkMetrics: true\n};\n\nlet debugConfig: DebugConfig = { ...DEFAULT_DEBUG_CONFIG };\n\n/**\n * Configure debug logging\n */\nexport function configureDebugLogging(config: Partial<DebugConfig>): void {\n debugConfig = { ...debugConfig, ...config };\n}\n\n/**\n * Get current timestamp string\n */\nfunction getTimestamp(): string {\n return new Date().toISOString();\n}\n\n/**\n * Format log message with metadata\n */\nfunction formatMessage(level: string, component: string, message: string, metadata?: any): string {\n const timestamp = debugConfig.enableTimestamps ? `[${getTimestamp()}] ` : '';\n const metadataStr = metadata ? ` ${JSON.stringify(metadata)}` : '';\n return `${timestamp}[${level}] [${component}] ${message}${metadataStr}`;\n}\n\n/**\n * Performance metrics tracker\n */\nexport class PerformanceTracker {\n private startTime: number;\n private markers: Map<string, number> = new Map();\n\n constructor(private operationName: string) {\n this.startTime = Date.now();\n this.log('PERF', `Started: ${operationName}`);\n }\n\n mark(label: string): void {\n const elapsed = Date.now() - this.startTime;\n this.markers.set(label, elapsed);\n this.log('PERF', `${this.operationName} - ${label}: ${elapsed}ms`);\n }\n\n end(success: boolean = true): number {\n const totalTime = Date.now() - this.startTime;\n const status = success ? 'SUCCESS' : 'FAILED';\n this.log('PERF', `${this.operationName} - ${status}: ${totalTime}ms`);\n\n if (debugConfig.enablePerformanceMetrics && this.markers.size > 0) {\n console.log(`\uD83D\uDCCA Performance Breakdown for ${this.operationName}:`);\n for (const [label, time] of this.markers) {\n console.log(` ${label}: ${time}ms`);\n }\n console.log(` Total: ${totalTime}ms`);\n }\n\n return totalTime;\n }\n\n private log(level: string, message: string): void {\n if (debugConfig.enablePerformanceMetrics) {\n console.log(formatMessage(level, 'PERFORMANCE', message));\n }\n }\n}\n\n/**\n * Network metrics collector\n */\nexport interface NetworkMetrics {\n requestCount: number;\n successCount: number;\n failureCount: number;\n averageLatency: number;\n lastError?: string;\n startTime: number;\n}\n\nclass NetworkMetricsCollector {\n private metrics: Map<string, NetworkMetrics> = new Map();\n\n getMetrics(operation: string): NetworkMetrics {\n if (!this.metrics.has(operation)) {\n this.metrics.set(operation, {\n requestCount: 0,\n successCount: 0,\n failureCount: 0,\n averageLatency: 0,\n startTime: Date.now()\n });\n }\n return this.metrics.get(operation)!;\n }\n\n recordRequest(operation: string, success: boolean, latency: number, error?: string): void {\n const metrics = this.getMetrics(operation);\n metrics.requestCount++;\n\n if (success) {\n metrics.successCount++;\n // Update average latency\n metrics.averageLatency = (metrics.averageLatency * (metrics.successCount - 1) + latency) / metrics.successCount;\n } else {\n metrics.failureCount++;\n if (error) metrics.lastError = error;\n }\n\n if (debugConfig.enableNetworkMetrics) {\n const successRate = ((metrics.successCount / metrics.requestCount) * 100).toFixed(1);\n debugLog('NETWORK', `${operation} - Success: ${success}, Latency: ${latency}ms, Success Rate: ${successRate}%`);\n }\n }\n\n printSummary(): void {\n if (!debugConfig.enableNetworkMetrics) return;\n\n console.log('\\n\uD83D\uDCC8 Network Metrics Summary:');\n for (const [operation, metrics] of this.metrics) {\n const successRate = ((metrics.successCount / metrics.requestCount) * 100).toFixed(1);\n const runtime = Date.now() - metrics.startTime;\n console.log(` ${operation}:`);\n console.log(` Requests: ${metrics.requestCount}`);\n console.log(` Success Rate: ${successRate}%`);\n console.log(` Avg Latency: ${metrics.averageLatency.toFixed(0)}ms`);\n console.log(` Runtime: ${runtime}ms`);\n if (metrics.lastError) {\n console.log(` Last Error: ${metrics.lastError}`);\n }\n }\n }\n}\n\nexport const networkMetrics = new NetworkMetricsCollector();\n\n/**\n * Debug logging functions\n */\nexport function debugError(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.ERROR) {\n console.error(formatMessage('ERROR', component, message, metadata));\n }\n}\n\nexport function debugWarn(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.WARN) {\n console.warn(formatMessage('WARN', component, message, metadata));\n }\n}\n\nexport function debugInfo(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.INFO) {\n console.log(formatMessage('INFO', component, message, metadata));\n }\n}\n\nexport function debugLog(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.DEBUG) {\n console.log(formatMessage('DEBUG', component, message, metadata));\n }\n}\n\nexport function debugTrace(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.TRACE) {\n console.log(formatMessage('TRACE', component, message, metadata));\n }\n}\n\n/**\n * Request/Response logger for LIT Protocol operations\n */\nexport function logRequest(component: string, operation: string, params: any): void {\n if (!debugConfig.enableRequestLogging) return;\n\n debugLog(component, `\uD83D\uDD04 Request: ${operation}`, {\n operation,\n params: JSON.stringify(params, null, 2)\n });\n}\n\nexport function logResponse(component: string, operation: string, response: any, duration: number): void {\n if (!debugConfig.enableRequestLogging) return;\n\n debugLog(component, `\u2705 Response: ${operation} (${duration}ms)`, {\n operation,\n duration,\n response: typeof response === 'object' ? JSON.stringify(response, null, 2) : response\n });\n}\n\nexport function logError(component: string, operation: string, error: any, duration?: number): void {\n const durationStr = duration ? ` (${duration}ms)` : '';\n debugError(component, `\u274C Error: ${operation}${durationStr}`, {\n operation,\n duration,\n error: error?.message || error?.toString() || 'Unknown error',\n stack: error?.stack\n });\n}\n\n/**\n * Network connection logger\n */\nexport function logConnectionAttempt(network: string, attempt: number, maxAttempts: number): void {\n debugInfo('CONNECTION', `\uD83D\uDD17 Connecting to ${network} (attempt ${attempt}/${maxAttempts})`);\n}\n\nexport function logConnectionSuccess(network: string, latency: number): void {\n debugInfo('CONNECTION', `\u2705 Connected to ${network} (${latency}ms)`);\n networkMetrics.recordRequest(`connection-${network}`, true, latency);\n}\n\nexport function logConnectionFailure(network: string, error: string, attempt: number): void {\n debugError('CONNECTION', `\u274C Connection failed to ${network} (attempt ${attempt})`, { error });\n networkMetrics.recordRequest(`connection-${network}`, false, 0, error);\n}\n\n/**\n * PKP operation logger\n */\nexport function logPkpOperation(operation: string, pkpId?: string, details?: any): void {\n const pkpStr = pkpId ? ` (PKP: ${pkpId.slice(0, 8)}...)` : '';\n debugInfo('PKP', `\uD83D\uDD11 ${operation}${pkpStr}`, details);\n}\n\n/**\n * Session signature logger\n */\nexport function logSessionSignatures(count: number, expiration: string): void {\n debugInfo('SESSION', `\uD83D\uDD10 Generated ${count} session signatures (expires: ${expiration})`);\n}\n\n/**\n * LIT Action execution logger\n */\nexport function logLitActionExecution(cid: string, params: any): void {\n debugInfo('LIT_ACTION', `\u26A1 Executing LIT Action: ${cid}`, {\n cid,\n params\n });\n}\n\nexport function logLitActionResult(cid: string, success: boolean, duration: number, result?: any): void {\n const status = success ? '\u2705' : '\u274C';\n debugInfo('LIT_ACTION', `${status} LIT Action completed: ${cid} (${duration}ms)`, {\n cid,\n success,\n duration,\n result: success && result ? JSON.stringify(result, null, 2) : undefined\n });\n}\n\n/**\n * Test lifecycle logger\n */\nexport function logTestStart(testName: string): PerformanceTracker {\n debugInfo('TEST', `\uD83E\uDDEA Starting test: ${testName}`);\n return new PerformanceTracker(testName);\n}\n\nexport function logTestEnd(testName: string, success: boolean, duration: number): void {\n const status = success ? '\u2705' : '\u274C';\n debugInfo('TEST', `${status} Test completed: ${testName} (${duration}ms)`);\n networkMetrics.printSummary();\n}", "/**\n * Session Signature Cache for PKP Operations\n * Provides intelligent caching of session signatures to avoid regeneration\n */\n\nimport { debugInfo, debugWarn, debugLog } from './debug-logger';\n\n/**\n * Cache entry for session signatures\n */\ninterface SessionSignatureCacheEntry {\n sessionSigs: any;\n expiration: Date;\n pkpTokenId: string;\n litActionCid: string;\n signerAddress: string;\n network: string;\n createdAt: Date;\n}\n\n/**\n * Session signature cache configuration\n */\nexport interface SessionSignatureCacheConfig {\n maxEntries: number;\n bufferTimeMs: number; // Time before expiration to consider entry stale\n enableLogging: boolean;\n}\n\nexport const DEFAULT_CACHE_CONFIG: SessionSignatureCacheConfig = {\n maxEntries: 50,\n bufferTimeMs: 60000, // 1 minute buffer before expiration\n enableLogging: true\n};\n\n/**\n * In-memory session signature cache\n */\nclass SessionSignatureCache {\n private cache = new Map<string, SessionSignatureCacheEntry>();\n private config: SessionSignatureCacheConfig;\n\n constructor(config: Partial<SessionSignatureCacheConfig> = {}) {\n this.config = { ...DEFAULT_CACHE_CONFIG, ...config };\n }\n\n /**\n * Generate cache key from PKP and context\n */\n private generateCacheKey(\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string\n ): string {\n return `${signerAddress}-${network}-${pkpTokenId}-${litActionCid}`;\n }\n\n /**\n * Check if cache entry is still valid\n */\n private isEntryValid(entry: SessionSignatureCacheEntry): boolean {\n const now = new Date();\n const expirationWithBuffer = new Date(\n entry.expiration.getTime() - this.config.bufferTimeMs\n );\n\n return now < expirationWithBuffer;\n }\n\n /**\n * Clean expired entries from cache\n */\n private cleanExpiredEntries(): void {\n const now = new Date();\n let cleanedCount = 0;\n\n for (const [key, entry] of this.cache.entries()) {\n if (now >= entry.expiration) {\n this.cache.delete(key);\n cleanedCount++;\n }\n }\n\n if (cleanedCount > 0 && this.config.enableLogging) {\n debugInfo('CACHE', `\uD83E\uDDF9 Cleaned ${cleanedCount} expired session signature entries`);\n }\n }\n\n /**\n * Enforce cache size limits\n */\n private enforceCacheSize(): void {\n if (this.cache.size <= this.config.maxEntries) {\n return;\n }\n\n // Sort entries by creation time and remove oldest\n const entries = Array.from(this.cache.entries())\n .sort(([, a], [, b]) => a.createdAt.getTime() - b.createdAt.getTime());\n\n const toRemove = entries.slice(0, this.cache.size - this.config.maxEntries);\n\n for (const [key] of toRemove) {\n this.cache.delete(key);\n }\n\n if (this.config.enableLogging) {\n debugInfo('CACHE', `\uD83D\uDCE6 Removed ${toRemove.length} oldest cache entries to maintain size limit`);\n }\n }\n\n /**\n * Get cached session signatures if valid\n */\n get(\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string\n ): any | null {\n this.cleanExpiredEntries();\n\n const cacheKey = this.generateCacheKey(pkpTokenId, litActionCid, signerAddress, network);\n const entry = this.cache.get(cacheKey);\n\n if (!entry) {\n if (this.config.enableLogging) {\n debugLog('CACHE', `\u274C Session signatures cache miss: ${cacheKey}`);\n }\n return null;\n }\n\n if (!this.isEntryValid(entry)) {\n this.cache.delete(cacheKey);\n if (this.config.enableLogging) {\n debugWarn('CACHE', `\u23F0 Session signatures expired: ${cacheKey}`);\n }\n return null;\n }\n\n if (this.config.enableLogging) {\n const timeUntilExpiry = entry.expiration.getTime() - Date.now();\n debugInfo('CACHE', `\u2705 Session signatures cache hit: ${cacheKey} (expires in ${Math.round(timeUntilExpiry/1000)}s)`);\n }\n\n return entry.sessionSigs;\n }\n\n /**\n * Cache session signatures\n */\n set(\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string,\n sessionSigs: any,\n expiration: Date\n ): void {\n const cacheKey = this.generateCacheKey(pkpTokenId, litActionCid, signerAddress, network);\n\n const entry: SessionSignatureCacheEntry = {\n sessionSigs,\n expiration,\n pkpTokenId,\n litActionCid,\n signerAddress,\n network,\n createdAt: new Date()\n };\n\n this.cache.set(cacheKey, entry);\n\n if (this.config.enableLogging) {\n const timeUntilExpiry = expiration.getTime() - Date.now();\n debugInfo('CACHE', `\uD83D\uDCBE Cached session signatures: ${cacheKey} (expires in ${Math.round(timeUntilExpiry/1000)}s)`);\n }\n\n this.enforceCacheSize();\n }\n\n /**\n * Clear all cached session signatures\n */\n clear(): void {\n const size = this.cache.size;\n this.cache.clear();\n\n if (this.config.enableLogging) {\n debugInfo('CACHE', `\uD83D\uDDD1\uFE0F Cleared ${size} cached session signature entries`);\n }\n }\n\n /**\n * Get cache statistics\n */\n getStats() {\n this.cleanExpiredEntries();\n\n return {\n size: this.cache.size,\n maxEntries: this.config.maxEntries,\n utilizationPercent: Math.round((this.cache.size / this.config.maxEntries) * 100)\n };\n }\n\n /**\n * Remove specific cache entry\n */\n delete(\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string\n ): boolean {\n const cacheKey = this.generateCacheKey(pkpTokenId, litActionCid, signerAddress, network);\n const deleted = this.cache.delete(cacheKey);\n\n if (deleted && this.config.enableLogging) {\n debugInfo('CACHE', `\uD83D\uDDD1\uFE0F Removed session signatures from cache: ${cacheKey}`);\n }\n\n return deleted;\n }\n}\n\n// Global session signature cache instance\nexport const sessionSignatureCache = new SessionSignatureCache();\n\n/**\n * Enhanced session signature generator with caching\n */\nexport async function generateSessionSignaturesWithCache(\n litNodeClient: any,\n sessionConfig: any,\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string = 'chipotle'\n): Promise<any> {\n // Check cache first\n const cached = sessionSignatureCache.get(pkpTokenId, litActionCid, signerAddress, network);\n if (cached) {\n return cached;\n }\n\n // Generate new session signatures\n debugInfo('CACHE', '\uD83D\uDD10 Generating new session signatures (cache miss)...');\n const sessionSigs = await litNodeClient.getSessionSigs(sessionConfig);\n\n // Extract expiration from config\n const expiration = new Date(sessionConfig.expiration);\n\n // Cache the result\n sessionSignatureCache.set(pkpTokenId, litActionCid, signerAddress, network, sessionSigs, expiration);\n\n const sigCount = Object.keys(sessionSigs).length;\n debugInfo('CACHE', `\u2705 Generated and cached ${sigCount} session signatures`);\n\n return sessionSigs;\n}\n\n/**\n * Configure the global session signature cache\n */\nexport function configureSessionSignatureCache(config: Partial<SessionSignatureCacheConfig>): void {\n Object.assign(sessionSignatureCache['config'], config);\n}\n\n/**\n * Clear the global session signature cache\n */\nexport function clearSessionSignatureCache(): void {\n sessionSignatureCache.clear();\n}\n\n/**\n * Get session signature cache statistics\n */\nexport function getSessionSignatureCacheStats() {\n return sessionSignatureCache.getStats();\n}", "/**\n * dh-lit-actions Package\n * Diamond Hands Protocol LIT Actions Registry\n *\n * This package exports deployed LIT Action CIDs and metadata\n * for consumption by the Diamond Hands SDK and other applications.\n */\n\n// Export interfaces\nexport * from \"./interfaces\";\n\n// Export constants from registry\nexport * from \"./constants/chunks/lit-actions-registry\";\n\n// Export utilities\nexport * from \"./utils\";\n\n// Export NOLA executors (commented out - executors import from src/ which is outside rootDir)\n// export * from \"./executors\";\n\n// Default export\nexport { DH_LIT_ACTIONS_CHIPOTLE, CHIPOTLE_DEPLOYMENTS } from \"./constants/chunks/lit-actions-registry\";\n", "// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\nfunction base (ALPHABET) {\n if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }\n const BASE_MAP = new Uint8Array(256)\n for (let j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255\n }\n for (let i = 0; i < ALPHABET.length; i++) {\n const x = ALPHABET.charAt(i)\n const xc = x.charCodeAt(0)\n if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }\n BASE_MAP[xc] = i\n }\n const BASE = ALPHABET.length\n const LEADER = ALPHABET.charAt(0)\n const FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up\n const iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up\n function encode (source) {\n // eslint-disable-next-line no-empty\n if (source instanceof Uint8Array) { } else if (ArrayBuffer.isView(source)) {\n source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength)\n } else if (Array.isArray(source)) {\n source = Uint8Array.from(source)\n }\n if (!(source instanceof Uint8Array)) { throw new TypeError('Expected Uint8Array') }\n if (source.length === 0) { return '' }\n // Skip & count leading zeroes.\n let zeroes = 0\n let length = 0\n let pbegin = 0\n const pend = source.length\n while (pbegin !== pend && source[pbegin] === 0) {\n pbegin++\n zeroes++\n }\n // Allocate enough space in big-endian base58 representation.\n const size = ((pend - pbegin) * iFACTOR + 1) >>> 0\n const b58 = new Uint8Array(size)\n // Process the bytes.\n while (pbegin !== pend) {\n let carry = source[pbegin]\n // Apply \"b58 = b58 * 256 + ch\".\n let i = 0\n for (let it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {\n carry += (256 * b58[it1]) >>> 0\n b58[it1] = (carry % BASE) >>> 0\n carry = (carry / BASE) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n pbegin++\n }\n // Skip leading zeroes in base58 result.\n let it2 = size - length\n while (it2 !== size && b58[it2] === 0) {\n it2++\n }\n // Translate the result into a string.\n let str = LEADER.repeat(zeroes)\n for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }\n return str\n }\n function decodeUnsafe (source) {\n if (typeof source !== 'string') { throw new TypeError('Expected String') }\n if (source.length === 0) { return new Uint8Array() }\n let psz = 0\n // Skip and count leading '1's.\n let zeroes = 0\n let length = 0\n while (source[psz] === LEADER) {\n zeroes++\n psz++\n }\n // Allocate enough space in big-endian base256 representation.\n const size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.\n const b256 = new Uint8Array(size)\n // Process the characters.\n while (psz < source.length) {\n // Find code of next character\n const charCode = source.charCodeAt(psz)\n // Base map can not be indexed using char code\n if (charCode > 255) { return }\n // Decode character\n let carry = BASE_MAP[charCode]\n // Invalid character\n if (carry === 255) { return }\n let i = 0\n for (let it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {\n carry += (BASE * b256[it3]) >>> 0\n b256[it3] = (carry % 256) >>> 0\n carry = (carry / 256) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n psz++\n }\n // Skip leading zeroes in b256.\n let it4 = size - length\n while (it4 !== size && b256[it4] === 0) {\n it4++\n }\n const vch = new Uint8Array(zeroes + (size - it4))\n let j = zeroes\n while (it4 !== size) {\n vch[j++] = b256[it4++]\n }\n return vch\n }\n function decode (string) {\n const buffer = decodeUnsafe(string)\n if (buffer) { return buffer }\n throw new Error('Non-base' + BASE + ' character')\n }\n return {\n encode,\n decodeUnsafe,\n decode\n }\n}\nexport default base\n", "import basex from 'base-x';\nvar ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\nexport default basex(ALPHABET);\n", "import bs58 from \"bs58\";\n\n/**\n * Convert IPFS CID from base58 to hex format for contract authorization\n * This matches the format expected by LIT Protocol smart contracts\n */\nexport function cidToHex(cid: string): string {\n try {\n if (cid.startsWith(\"Qm\")) {\n // v0 CID - convert base58 to hex\n const bytes = bs58.decode(cid);\n return \"0x\" + Buffer.from(bytes).toString(\"hex\");\n } else if (cid.startsWith(\"0x\")) {\n // Already in hex format\n return cid;\n } else {\n // Unknown format - FAIL FAST\n throw new Error(`Unsupported CID format: ${cid}. Only CIDv0 (Qm...) and hex (0x...) formats are supported.`);\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes('Unsupported CID format')) {\n // Re-throw our own errors\n throw error;\n }\n // bs58 decode or other conversion errors\n throw new Error(`Failed to convert CID ${cid} to hex: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n", "import { DiamondHandsLitActions } from \"../../interfaces\";\nimport { cidToHex } from \"../../utils/chunks/cid-utils\";\n\nexport type SupportedLitNetwork = \"chipotle\";\n\n/**\n * Diamond Hands LIT Actions Registry \u2014 Chipotle (new REST API)\n * Contains all deployed LIT Actions with their IPFS CIDs and PKP metadata\n */\nexport const DH_LIT_ACTIONS_CHIPOTLE: Partial<DiamondHandsLitActions> = {\n authorizationDummy: {\n cid: \"QmXPh5RTReLqjqZDRNhgVKi1TWMJK2vS9QSRPkWPhLBQJN\",\n authorizedCidHex: cidToHex(\n \"QmXPh5RTReLqjqZDRNhgVKi1TWMJK2vS9QSRPkWPhLBQJN\",\n ),\n name: \"Authorization Dummy\",\n description: \"Production Authorization Dummy\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1776707622939,\n size: 2026,\n hash: \"349d51aa096d56b394f82de75ed34cd4eef72719969f7e5fe584f4582b2745fa\",\n },\n authorizationDummyB: {\n cid: \"QmQXTcAU9tr4YAVrzHujEJw9moJgM1o5gnJU2ojcvhigua\",\n authorizedCidHex: cidToHex(\n \"QmQXTcAU9tr4YAVrzHujEJw9moJgM1o5gnJU2ojcvhigua\",\n ),\n name: \"Authorization Dummy B\",\n description: \"Production Authorization Dummy B\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1776707632987,\n size: 1695,\n hash: \"def4576ba6c382d145f996c4f950b5e39e58792415ee7fdd749e0d2bc61e8f0b\",\n },\n pkpValidator: {\n cid: \"QmTqsmXkjib7CRGFcEhmCs61Z3EZTaRPznaZDDLk5Wq9NX\",\n authorizedCidHex: cidToHex(\n \"QmTqsmXkjib7CRGFcEhmCs61Z3EZTaRPznaZDDLk5Wq9NX\",\n ),\n name: \"Pkp Validator\",\n description: \"Production Pkp Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311468630,\n size: 3999,\n hash: \"baba8c31b73dbfe6425d8f9fd69c61f41a573e189a185962382b815a15fddb24\",\n validatorWalletAddress: \"0x9ee56687f7a984d5df7ab79330271a619ef56ddd\",\n pkp: {\n publicKey:\n \"0x04ec0e3acc40884e3f366ca469d08899eb640ad5259fa196b0238075086208a9f8732a3175704f35f0bcc28e07406cfb24c254efd1e7355640577330f0d2dd755f\",\n ethAddress: \"0x9eE56687F7a984D5DF7aB79330271a619ef56DdD\",\n },\n },\n btcTransactionSigner: {\n cid: \"QmYSvuDcn2EPjRoDsPBLK2e3PGYEUHtWAPxwB51s4unkaG\",\n authorizedCidHex: cidToHex(\n \"QmYSvuDcn2EPjRoDsPBLK2e3PGYEUHtWAPxwB51s4unkaG\",\n ),\n name: \"Btc Transaction Signer\",\n description: \"Production Btc Transaction Signer\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1776767100453,\n size: 25657,\n hash: \"422311d10447a806bf435a1df440ff00d4eee986c019ccdb4af15bdbfd8019cf\",\n },\n ucdMintValidator: {\n cid: \"QmbYWJkLBdxTCNUkYTVmBzcp4CFhAn7ZcCyMZjhhbjAUMB\",\n authorizedCidHex: cidToHex(\n \"QmbYWJkLBdxTCNUkYTVmBzcp4CFhAn7ZcCyMZjhhbjAUMB\",\n ),\n name: \"Ucd Mint Validator\",\n description: \"Production Ucd Mint Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311478949,\n size: 65507,\n hash: \"f079aa1fc53fe04b08508379feba5d55d2d334ab9ee21bee043c05cf592eced3\",\n validatorWalletAddress: \"0x36f3dd61c4c08a56d29ed2fd6d5f111b67b6a7a1\",\n pkp: {\n publicKey:\n \"0x041ab17cd91fc5c0b761eea6092d032807561b621b82c488826776e04a9158d61ba64d809a4729f0501289d980732cb06d8dfd06999dd9c8efd2f495dad78b31bb\",\n ethAddress: \"0x4D9299055093938d0CD2F26C42A87260CB50adD8\",\n },\n },\n processPaymentValidator: {\n cid: \"Qmc9gkDVY1SK9vvyQ9cXa3PSSuv8q6Ki9o9rsG87qpXCYi\",\n authorizedCidHex: cidToHex(\n \"Qmc9gkDVY1SK9vvyQ9cXa3PSSuv8q6Ki9o9rsG87qpXCYi\",\n ),\n name: \"Process Payment Validator\",\n description: \"Production Process Payment Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311488810,\n size: 61413,\n hash: \"2ffbd15b1429edb7ddc7587ea8d30d45d4182a2bd3fc22e5986f9b4850440a9b\",\n validatorWalletAddress: \"0xc2ed5a59bd81eb4d1a19a0147b86ab69aa4c28ba\",\n pkp: {\n publicKey:\n \"0x04cfccb9b6c7addc79469c0e9fafebef4c70801302c62cdb26b610723a9b8527d23f98a40158c7340d83fd0e62d02b5ec74c12f7a86d98e8c6973b4811110f19ad\",\n ethAddress: \"0x440Fd7B157766b95eb551825C06DF4f92E41D55b\",\n },\n },\n extendPositionValidator: {\n cid: \"Qmc5MDW6ZxTRe3nXJEKa5KKUCVXFznV9vDqFL4n7ayRZ4p\",\n authorizedCidHex: cidToHex(\n \"Qmc5MDW6ZxTRe3nXJEKa5KKUCVXFznV9vDqFL4n7ayRZ4p\",\n ),\n name: \"Extend Position Validator\",\n description: \"Production Extend Position Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311498958,\n size: 60870,\n hash: \"624cbc2514b8be7b2e8cc3a509dce282db9213e43a7675f058ecebe4eb9faa40\",\n validatorWalletAddress: \"0xb3f4271c475887a86a2f21446f0968c30cc74c97\",\n pkp: {\n publicKey:\n \"0x04e52338f6a0c3362800f1a94c4c8f08be5030dde0fa217388c53d1c1a4790f4443c9f2886b2d2d8f4b75a9a156e9b028011b1a1cf7648da0e556aa980ec692836\",\n ethAddress: \"0x4cb7651Ba27610991A5775486B5F4487F3Dd7cDA\",\n },\n },\n btcWithdrawal: {\n cid: \"Qmds87V3zYoZJMDCNPjqrnYTWKwHQqZ2WqMTtV9F5c5NDc\",\n authorizedCidHex: cidToHex(\n \"Qmds87V3zYoZJMDCNPjqrnYTWKwHQqZ2WqMTtV9F5c5NDc\",\n ),\n name: \"Btc Withdrawal\",\n description: \"Production Btc Withdrawal\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311512905,\n size: 70563,\n hash: \"1b85e8e2951fb7cc7368981949f024c453528dac7eff0b505ef470a470b3c15e\",\n validatorWalletAddress: \"0xbb137fbda353199e9419b698c57a742124d4987d\",\n pkp: {\n publicKey:\n \"0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d\",\n ethAddress: \"0x7b9316cAA00B257F7CE30F7F6979bd6867BA9eE2\",\n },\n },\n liquidationValidator: {\n cid: \"QmZscQTKzwqWDZwYfaE57vdG4vYoNeQMkC2DwgJsnRNgQf\",\n authorizedCidHex: cidToHex(\n \"QmZscQTKzwqWDZwYfaE57vdG4vYoNeQMkC2DwgJsnRNgQf\",\n ),\n name: \"Liquidation Validator\",\n description: \"Production Liquidation Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311523132,\n size: 54907,\n hash: \"7a5a63dc80fad2258a0361f767f3efae3a62ec391c34b0927ca770411bf4de3e\",\n validatorWalletAddress: \"0x1542f863ee0340f6a067573e80ae66dd9b3838fa\",\n pkp: {\n publicKey:\n \"0x041a241de58976c13e3d7ca5a18e494f7330151e3818706135d50176e78ffb673e58b11f0b67a87c73fade6c6b27d6e7a7377ea9f4c10bf31880f1d725f18cc6f8\",\n ethAddress: \"0x8770470620Db25bBf2BFBca1eF7Bdd6CF91ab1b5\",\n },\n },\n priceOracle: {\n cid: \"Qma6vTTnn3AFy3A4u3A7T5tT6eEp26vXt7rPHSWpmBpdsp\",\n authorizedCidHex: cidToHex(\n \"Qma6vTTnn3AFy3A4u3A7T5tT6eEp26vXt7rPHSWpmBpdsp\",\n ),\n name: \"Price Oracle\",\n description: \"Production Price Oracle (Chipotle main+getPrivateKey)\",\n version: \"1.1.0\",\n deployed: true,\n deployedAt: 1777311530589,\n size: 11531,\n hash: \"a49e9a4875e68a1b8f1c37bcc8284a28e0995652a7df8bad4f1853408d1c81c8\",\n validatorWalletAddress: \"0x831ddf3048547b983efe3ccbbb35a45a53191651\",\n pkp: {\n publicKey:\n \"0x043beaa1da47875601a8d6f430b1438ee2d4732eefd06e5c63a474bbdaf9e7df1797b1b951e041b627c2bf839788164825324c9cbd1e2d6f740fdd4bff69b1900b\",\n ethAddress: \"0x831DdF3048547B983EFE3ccBBB35a45a53191651\",\n },\n },\n loanVaultBtcBalance: {\n cid: \"QmWGEg79snhDQ5Fkm9pLhNmLKUJY5uXfp3t3276Jybritq\",\n authorizedCidHex: cidToHex(\n \"QmWGEg79snhDQ5Fkm9pLhNmLKUJY5uXfp3t3276Jybritq\",\n ),\n name: \"Loan Vault Btc Balance\",\n description: \"Production Loan Vault Btc Balance\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311539409,\n size: 44293,\n hash: \"70b009f01b9051dee2db1e4030dd17d08dc53728d30b5e24cffd11d07acfcaf0\",\n validatorWalletAddress: \"0x47feea74c8739d24b44faa67217f2f99970e15e7\",\n pkp: {\n publicKey:\n \"0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d\",\n ethAddress: \"0x7b9316cAA00B257F7CE30F7F6979bd6867BA9eE2\",\n },\n },\n adminLiquidationValidator: {\n cid: \"QmYJJFgFPF4BR4ts9GrAkwfEoQbVSXEwnrciZ5Jj9WTDgd\",\n authorizedCidHex: cidToHex(\n \"QmYJJFgFPF4BR4ts9GrAkwfEoQbVSXEwnrciZ5Jj9WTDgd\",\n ),\n name: \"Admin Liquidation Validator\",\n description: \"Production Admin Liquidation Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311549068,\n size: 51556,\n hash: \"8eb26b08623d6be2ded733579d61c389fe312eef8d12ae1e62166c9359bbd037\",\n validatorWalletAddress: \"0x2a83b78842d75358877deb8854ccc5bbbaa5012e\",\n pkp: {\n publicKey:\n \"0x04ee4316afb8538280ede6c56def9cbe791f18f96ccba97768b28e2966d9c46a9493a6b81f4571495c3ce56c2d0b33fe8cf63726cd12d395832ea54162b5c67801\",\n ethAddress: \"0x038B7a1918ae9121bC641236b7946a069BE21591\",\n },\n },\n alwaysSigner: {\n cid: \"QmXQjybSsdE19Da66to9Hh7X2dLFwpZPhjoqojxbpk7Nvs\",\n authorizedCidHex: cidToHex(\n \"QmXQjybSsdE19Da66to9Hh7X2dLFwpZPhjoqojxbpk7Nvs\",\n ),\n name: \"Always Signer\",\n description: \"Production Always Signer\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1776708176283,\n size: 4143,\n hash: \"25007f80b4ed3169470bf617d403971136be431eb29dfb09f78afe2494bf0138\",\n },\n};\n\nexport function getDeploymentsForNetwork(\n network: SupportedLitNetwork,\n): Partial<DiamondHandsLitActions> {\n if (network === \"chipotle\") return DH_LIT_ACTIONS_CHIPOTLE;\n throw new Error(`Unsupported LIT network: ${network}`);\n}\n\nexport const CHIPOTLE_DEPLOYMENTS = DH_LIT_ACTIONS_CHIPOTLE;\n", "import { LitActionConfig, LitActionName } from \"../../interfaces\";\nimport {\n getDeploymentsForNetwork,\n SupportedLitNetwork,\n} from \"../../constants/chunks/lit-actions-registry\";\n\n/**\n * Get LIT Action CID by name\n * @param actionName - Name of the LIT Action\n * @returns IPFS CID of the deployed action\n * @throws Error if action is not deployed\n */\nexport function getLitActionCID(\n litNetwork: SupportedLitNetwork = \"chipotle\",\n actionName: LitActionName,\n): string {\n const deployments = getDeploymentsForNetwork(litNetwork);\n const action = deployments[actionName];\n\n if (!action || !action.deployed || !action.cid) {\n throw new Error(\n `LIT Action '${actionName}' not deployed on network '${litNetwork}'. Check deployment status.`,\n );\n }\n return action.cid;\n}\n\n/**\n * Get LIT Action configuration by name\n * @param actionName - Name of the LIT Action\n * @returns Complete LIT Action configuration\n */\nexport function getLitActionConfig(\n actionName: LitActionName,\n litNetwork: SupportedLitNetwork = \"chipotle\",\n): LitActionConfig {\n const deployments = getDeploymentsForNetwork(litNetwork);\n const action = deployments[actionName];\n if (!action) {\n throw new Error(\n `LIT Action '${actionName}' not found in registry for network '${litNetwork}'.`,\n );\n }\n return action;\n}\n\n/**\n * Check if a LIT Action is deployed and ready to use\n * @param actionName - Name of the LIT Action\n * @returns True if deployed, false otherwise\n */\nexport function isLitActionDeployed(\n actionName: LitActionName,\n litNetwork: SupportedLitNetwork = \"chipotle\",\n): boolean {\n const deployments = getDeploymentsForNetwork(litNetwork);\n const action = deployments[actionName];\n return !!(action && action.deployed && action.cid);\n}\n\n/**\n * Validate that all required actions are deployed\n * @param requiredActions - Array of required action names\n * @returns True if all actions are deployed\n */\nexport function validateDeployedActions(\n requiredActions: LitActionName[],\n litNetwork: SupportedLitNetwork = \"chipotle\",\n): boolean {\n return requiredActions.every((actionName) =>\n isLitActionDeployed(actionName, litNetwork),\n );\n}\n\n/**\n * Get all deployed LIT Actions\n * @returns Array of deployed LIT Action configurations\n */\nexport function getDeployedActions(\n litNetwork: SupportedLitNetwork = \"chipotle\",\n): LitActionConfig[] {\n const deployments = getDeploymentsForNetwork(litNetwork);\n return Object.values(deployments).filter(\n (action) => action && action.deployed,\n );\n}\n", "import {\n getDeploymentsForNetwork,\n SupportedLitNetwork,\n} from \"../../constants/chunks/lit-actions-registry\";\n/**\n * Get the complete setup for PKP Validator testing\n * Returns both the LIT Action config and its associated PKP\n */\nexport function getPKPValidatorSetup(\n litNetwork: SupportedLitNetwork = \"chipotle\"\n) {\n const deployments = getDeploymentsForNetwork(litNetwork);\n const litAction = deployments.pkpValidator;\n\n if (!litAction || !litAction.pkp) {\n throw new Error(\n `PKP validator setup is not available for litNetwork='${litNetwork}'. ` +\n `Ensure the pkpValidator action (with pkp attached) is defined in the registry.`\n );\n }\n\n return {\n litAction,\n pkp: litAction.pkp!,\n };\n}\n", "/**\n * LIT Protocol Connection Helpers\n * Provides retry logic, error handling, and connection validation utilities\n * for robust LIT Protocol operations\n */\n\nimport {\n debugInfo,\n debugWarn,\n debugError,\n logConnectionAttempt,\n logConnectionSuccess,\n logConnectionFailure,\n logRequest,\n logResponse,\n logError,\n logPkpOperation,\n logLitActionExecution,\n logLitActionResult,\n networkMetrics,\n PerformanceTracker\n} from './debug-logger';\nimport {\n classifyError,\n getRetryConfigFromClassification,\n createErrorReport,\n litProtocolErrors\n} from './error-classification';\n\n/**\n * Retry configuration options\n */\nexport interface RetryConfig {\n maxAttempts: number;\n initialDelayMs: number;\n maxDelayMs: number;\n backoffMultiplier: number;\n retryableErrors: string[];\n}\n\n/**\n * Default retry configuration optimized for LIT Protocol operations\n */\nexport const DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxAttempts: 5, // Increased from 3 for PKP operations\n initialDelayMs: 2000, // Increased from 1000ms for PKP operations\n maxDelayMs: 60000, // Increased from 30000ms for PKP operations\n backoffMultiplier: 2,\n retryableErrors: [\n 'request_timeout',\n 'network error',\n 'connection failed',\n 'ENOTFOUND',\n 'ECONNREFUSED',\n 'ETIMEDOUT',\n 'socket hang up',\n 'timeout',\n // PKP-specific errors\n 'signing shares',\n 'There was an error getting the signing shares',\n 'PKP validation',\n 'pkp validation failed',\n 'resource validation',\n 'ipfs propagation',\n 'session.*expired',\n 'NodeError',\n 'Response from the nodes',\n 'consensus',\n 'threshold'\n ]\n};\n\n/**\n * Connection validation result\n */\nexport interface ConnectionValidationResult {\n isValid: boolean;\n error?: string;\n latencyMs?: number;\n}\n\n/**\n * Sleep utility for retry delays\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Check if an error is retryable using enhanced classification system\n */\nexport function isRetryableError(error: any, retryableErrors: string[] = DEFAULT_RETRY_CONFIG.retryableErrors): boolean {\n if (!error) return false;\n\n // Use enhanced error classification for LIT Protocol specific errors\n const classification = classifyError(error);\n\n // If classification determined retryability, use that\n if (classification.isRetryable !== undefined) {\n debugInfo('ERROR_CLASSIFICATION', `Error classified as: ${classification.category} (retryable: ${classification.isRetryable})`);\n return classification.isRetryable;\n }\n\n // Fallback to legacy pattern matching\n const errorMessage = error.message || error.toString() || '';\n const errorLower = errorMessage.toLowerCase();\n\n return retryableErrors.some(pattern =>\n errorLower.includes(pattern.toLowerCase())\n );\n}\n\n/**\n * Calculate exponential backoff delay with jitter\n */\nexport function calculateDelay(attempt: number, config: RetryConfig): number {\n const exponentialDelay = Math.min(\n config.initialDelayMs * Math.pow(config.backoffMultiplier, attempt - 1),\n config.maxDelayMs\n );\n\n // Add jitter (\u00B125%) to avoid thundering herd\n const jitter = exponentialDelay * 0.25 * (Math.random() - 0.5);\n return Math.max(100, exponentialDelay + jitter);\n}\n\n/**\n * Enhanced retry wrapper with intelligent error classification\n */\nexport async function withRetry<T>(\n operation: () => Promise<T>,\n config: Partial<RetryConfig> = {},\n operationName: string = 'operation'\n): Promise<T> {\n let finalConfig = { ...DEFAULT_RETRY_CONFIG, ...config };\n const tracker = new PerformanceTracker(`Retry ${operationName}`);\n let lastError: any;\n let errorClassification: any = null;\n\n for (let attempt = 1; attempt <= finalConfig.maxAttempts; attempt++) {\n try {\n debugInfo('RETRY', `\uD83D\uDD04 [${operationName}] Attempt ${attempt}/${finalConfig.maxAttempts}`);\n const startTime = Date.now();\n const result = await operation();\n const duration = Date.now() - startTime;\n\n debugInfo('RETRY', `\u2705 [${operationName}] Success after ${duration}ms (attempt ${attempt})`);\n networkMetrics.recordRequest(operationName, true, duration);\n tracker.end(true);\n return result;\n } catch (error) {\n lastError = error;\n const errorMessage = (error as any)?.message || (error as any)?.toString() || 'Unknown error';\n\n // Classify error and potentially adjust retry strategy\n errorClassification = classifyError(error);\n\n // Update config with intelligent retry settings if this is the first error\n if (attempt === 1 && errorClassification) {\n const intelligentConfig = getRetryConfigFromClassification(errorClassification);\n finalConfig = {\n ...finalConfig,\n ...intelligentConfig,\n maxAttempts: Math.min(finalConfig.maxAttempts, intelligentConfig.maxAttempts)\n };\n\n debugInfo('RETRY', `\uD83E\uDDE0 Intelligent retry strategy applied: ${errorClassification.category} (${errorClassification.retryStrategy})`);\n debugInfo('RETRY', `\uD83D\uDCCA Adjusted config: max=${finalConfig.maxAttempts}, delay=${finalConfig.initialDelayMs}ms`);\n }\n\n debugWarn('RETRY', `\u26A0\uFE0F [${operationName}] Attempt ${attempt} failed:`, {\n error: errorMessage,\n attempt,\n category: errorClassification.category,\n retryable: errorClassification.isRetryable\n });\n networkMetrics.recordRequest(operationName, false, 0, errorMessage);\n\n // Check if we've exceeded the (possibly adjusted) max attempts\n if (attempt >= finalConfig.maxAttempts) {\n debugError('RETRY', `\u274C [${operationName}] All attempts failed. Last error:`, { error: errorMessage });\n\n // Generate detailed error report\n if (errorClassification) {\n const errorReport = createErrorReport(error);\n debugError('RETRY', `\uD83D\uDCCB Error Analysis Report:\\n${errorReport}`);\n }\n\n tracker.end(false);\n break;\n }\n\n if (!errorClassification.isRetryable) {\n debugError('RETRY', `\uD83D\uDEAB [${operationName}] Non-retryable error (${errorClassification.category}):`, { error: errorMessage });\n\n // Show troubleshooting tips for non-retryable errors\n if (errorClassification.troubleshooting) {\n debugInfo('RETRY', `\uD83D\uDCA1 Troubleshooting suggestions:\\n ${errorClassification.troubleshooting.join('\\n ')}`);\n }\n\n tracker.end(false);\n break;\n }\n\n const delayMs = calculateDelay(attempt, finalConfig);\n debugInfo('RETRY', `\u23F3 [${operationName}] Waiting ${delayMs}ms before retry... (${errorClassification.retryStrategy} strategy)`);\n await sleep(delayMs);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Enhanced LIT Node Client connector with retry logic and readiness validation\n */\nexport async function connectLitNodeClient(\n litNodeClient: any,\n config: Partial<RetryConfig> = {}\n): Promise<void> {\n const network = litNodeClient?.config?.litNetwork || 'unknown';\n\n return withRetry(\n async () => {\n if (!litNodeClient) {\n throw new Error('LIT Node Client is null or undefined');\n }\n\n const startTime = Date.now();\n logConnectionAttempt(network, 1, config.maxAttempts || DEFAULT_RETRY_CONFIG.maxAttempts);\n\n // First connect to the network\n await litNodeClient.connect();\n\n // Wait for client to be ready\n debugInfo('CONNECTION', `\u23F3 Waiting for LIT Node Client to be ready...`);\n const readyTimeout = 30000; // 30 seconds timeout for readiness\n const readyStartTime = Date.now();\n\n while (!litNodeClient.ready && (Date.now() - readyStartTime) < readyTimeout) {\n await sleep(500); // Check every 500ms\n }\n\n if (!litNodeClient.ready) {\n throw new Error(`LIT Node Client failed to become ready within ${readyTimeout}ms`);\n }\n\n const latency = Date.now() - startTime;\n debugInfo('CONNECTION', `\u2705 LIT Node Client is ready (${litNodeClient.ready})`);\n logConnectionSuccess(network, latency);\n },\n config,\n 'LIT Node Client Connection'\n );\n}\n\n/**\n * Enhanced LIT Contracts connector with retry logic\n */\nexport async function connectLitContracts(\n litContracts: any,\n config: Partial<RetryConfig> = {}\n): Promise<void> {\n return withRetry(\n async () => {\n if (!litContracts) {\n throw new Error('LIT Contracts is null or undefined');\n }\n\n console.log(`\uD83D\uDD17 Connecting to LIT Contracts: ${litContracts.network || 'unknown'}`);\n await litContracts.connect();\n console.log('\u2705 LIT Contracts connected successfully');\n },\n config,\n 'LIT Contracts Connection'\n );\n}\n\n/**\n * Validate LIT Node Client connection health\n */\nexport async function validateLitNodeConnection(litNodeClient: any): Promise<ConnectionValidationResult> {\n try {\n const startTime = Date.now();\n\n if (!litNodeClient) {\n return { isValid: false, error: 'LIT Node Client is null or undefined' };\n }\n\n // Try to get the latest block hash as a health check\n await litNodeClient.getLatestBlockhash();\n\n const latencyMs = Date.now() - startTime;\n return { isValid: true, latencyMs };\n } catch (error) {\n return {\n isValid: false,\n error: (error as any)?.message || (error as any)?.toString() || 'Unknown validation error'\n };\n }\n}\n\n/**\n * Enhanced session signature generator with retry logic and caching\n */\nexport async function generateSessionSignatures(\n litNodeClient: any,\n sessionConfig: any,\n config: Partial<RetryConfig> = {},\n pkpTokenId?: string,\n litActionCid?: string,\n signerAddress?: string,\n network: string = 'chipotle'\n): Promise<any> {\n // If caching parameters are provided, try cache first\n if (pkpTokenId && litActionCid && signerAddress) {\n const { sessionSignatureCache } = await import('./session-signature-cache');\n\n const cached = sessionSignatureCache.get(pkpTokenId, litActionCid, signerAddress, network);\n if (cached) {\n const sigCount = Object.keys(cached).length;\n debugInfo('SESSION', `\uD83D\uDD04 Using cached session signatures (${sigCount} sigs)`);\n return cached;\n }\n }\n\n return withRetry(\n async () => {\n debugInfo('SESSION', '\uD83D\uDD10 Generating new session signatures...');\n const sessionSigs = await litNodeClient.getSessionSigs(sessionConfig);\n const sigCount = Object.keys(sessionSigs).length;\n\n // Cache if parameters provided\n if (pkpTokenId && litActionCid && signerAddress) {\n const { sessionSignatureCache } = await import('./session-signature-cache');\n const expiration = new Date(sessionConfig.expiration);\n sessionSignatureCache.set(pkpTokenId, litActionCid, signerAddress, network, sessionSigs, expiration);\n }\n\n debugInfo('SESSION', `\u2705 Generated ${sigCount} session signatures`);\n return sessionSigs;\n },\n config,\n 'Session Signature Generation'\n );\n}\n\n/**\n * Validate LIT Node Client readiness before operations\n */\nexport async function validateLitNodeReadiness(litNodeClient: any): Promise<void> {\n if (!litNodeClient) {\n throw new Error('LIT Node Client is null or undefined');\n }\n\n // Check if client is connected\n if (!litNodeClient.ready) {\n debugWarn('CONNECTION', '\u26A0\uFE0F LIT Node Client not ready, attempting to reconnect...');\n await litNodeClient.connect();\n\n // Wait for readiness with timeout\n const readyTimeout = 15000; // 15 seconds\n const startTime = Date.now();\n\n while (!litNodeClient.ready && (Date.now() - startTime) < readyTimeout) {\n await sleep(500);\n }\n\n if (!litNodeClient.ready) {\n throw new Error('LIT Node Client is not ready for operations');\n }\n }\n\n debugInfo('CONNECTION', '\u2705 LIT Node Client readiness validated');\n}\n\n/**\n * Enhanced LIT Action executor with retry logic and readiness validation\n */\nexport async function executeLitAction(\n litNodeClient: any,\n executionConfig: any,\n config: Partial<RetryConfig> = {}\n): Promise<any> {\n const cid = executionConfig.ipfsId;\n\n return withRetry(\n async () => {\n const startTime = Date.now();\n\n // Validate client readiness before execution\n await validateLitNodeReadiness(litNodeClient);\n\n logLitActionExecution(cid, executionConfig.jsParams);\n logRequest('LIT_ACTION', 'executeJs', executionConfig);\n\n const result = await litNodeClient.executeJs(executionConfig);\n const duration = Date.now() - startTime;\n\n if (!result.response) {\n logError('LIT_ACTION', 'executeJs', new Error('No response from LIT Action'), duration);\n throw new Error('No response from LIT Action');\n }\n\n logResponse('LIT_ACTION', 'executeJs', result, duration);\n logLitActionResult(cid, true, duration, result);\n return result;\n },\n config,\n 'LIT Action Execution'\n );\n}\n\n/**\n * PKP operation wrapper with enhanced error handling\n */\nexport async function executePkpOperation<T>(\n operation: () => Promise<T>,\n operationName: string,\n config: Partial<RetryConfig> = {}\n): Promise<T> {\n const pkpConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n retryableErrors: [\n ...DEFAULT_RETRY_CONFIG.retryableErrors,\n 'pkp validation',\n 'signing shares',\n 'resource validation',\n 'ipfs propagation'\n ]\n };\n\n return withRetry(operation, pkpConfig, `PKP ${operationName}`);\n}\n\n/**\n * Network-specific timeout configurations\n */\nexport const NETWORK_TIMEOUTS = {\n chipotle: {\n connection: 60000,\n operation: 120000,\n pkpValidation: 180000,\n },\n} as const;\n\nexport function getNetworkTimeouts(network: string) {\n return NETWORK_TIMEOUTS[network as keyof typeof NETWORK_TIMEOUTS] || NETWORK_TIMEOUTS['chipotle'];\n}", "/**\n * Enhanced Error Classification for LIT Protocol Operations\n * Provides detailed error categorization and specific retry strategies\n */\n\n/**\n * Error categories for different types of failures\n */\nexport enum ErrorCategory {\n NETWORK = 'network',\n PROTOCOL = 'protocol',\n AUTHENTICATION = 'authentication',\n RESOURCE = 'resource',\n VALIDATION = 'validation',\n TIMEOUT = 'timeout',\n RATE_LIMIT = 'rate_limit',\n CONFIGURATION = 'configuration',\n UNKNOWN = 'unknown'\n}\n\n/**\n * Retry strategy types\n */\nexport enum RetryStrategy {\n AGGRESSIVE = 'aggressive', // Fast retries for transient issues\n CONSERVATIVE = 'conservative', // Slower retries for resource issues\n EXPONENTIAL = 'exponential', // Standard exponential backoff\n LINEAR = 'linear', // Linear delay increase\n NONE = 'none' // No retries\n}\n\n/**\n * Error classification result\n */\nexport interface ErrorClassification {\n category: ErrorCategory;\n retryStrategy: RetryStrategy;\n isRetryable: boolean;\n maxAttempts: number;\n baseDelayMs: number;\n maxDelayMs: number;\n description: string;\n troubleshooting?: string[];\n}\n\n/**\n * LIT Protocol specific error patterns\n */\nconst LIT_ERROR_PATTERNS = {\n // Network and connection errors\n network: [\n /network error/i,\n /connection failed/i,\n /connection refused/i,\n /connection timeout/i,\n /socket hang up/i,\n /enotfound/i,\n /econnrefused/i,\n /etimedout/i,\n /dns resolution failed/i,\n /request failed/i\n ],\n\n // Protocol specific errors\n protocol: [\n /lit protocol/i,\n /lit node/i,\n /signing shares/i,\n /node communication/i,\n /consensus/i,\n /threshold/i,\n /decryption/i,\n /signature verification/i,\n /There was an error getting the signing shares/i,\n /Response from the nodes/i,\n /NodeError/i,\n /PKP validation/i,\n /pkp validation failed/i\n ],\n\n // Authentication and authorization errors\n authentication: [\n /authentication/i,\n /authorization/i,\n /session.*expired/i,\n /invalid.*signature/i,\n /unauthorized/i,\n /access.*denied/i,\n /permission/i,\n /auth.*failed/i,\n /siwe/i,\n /session.*sig/i\n ],\n\n // Resource and validation errors\n resource: [\n /resource.*not.*found/i,\n /ipfs.*not.*found/i,\n /cid.*invalid/i,\n /pkp.*not.*found/i,\n /pkp.*validation/i,\n /resource.*validation/i,\n /action.*not.*permitted/i,\n /lit.*action.*not.*found/i\n ],\n\n // Validation errors\n validation: [\n /validation.*failed/i,\n /invalid.*input/i,\n /invalid.*parameter/i,\n /malformed/i,\n /schema.*validation/i,\n /type.*error/i,\n /missing.*required/i\n ],\n\n // Timeout specific errors\n timeout: [\n /timeout/i,\n /request.*timed.*out/i,\n /operation.*timed.*out/i,\n /deadline.*exceeded/i,\n /time.*limit.*exceeded/i\n ],\n\n // Rate limiting errors\n rateLimit: [\n /rate.*limit/i,\n /too.*many.*requests/i,\n /quota.*exceeded/i,\n /throttled/i,\n /429/,\n /rate.*exceeded/i\n ],\n\n // Configuration errors\n configuration: [\n /configuration/i,\n /config.*error/i,\n /environment/i,\n /missing.*env/i,\n /invalid.*config/i,\n /setup.*error/i\n ]\n};\n\n/**\n * Predefined retry strategies\n */\nconst RETRY_STRATEGIES = {\n [RetryStrategy.AGGRESSIVE]: {\n maxAttempts: 5,\n baseDelayMs: 500,\n maxDelayMs: 5000,\n multiplier: 1.5\n },\n [RetryStrategy.CONSERVATIVE]: {\n maxAttempts: 3,\n baseDelayMs: 3000,\n maxDelayMs: 30000,\n multiplier: 2.5\n },\n [RetryStrategy.EXPONENTIAL]: {\n maxAttempts: 4,\n baseDelayMs: 1000,\n maxDelayMs: 15000,\n multiplier: 2.0\n },\n [RetryStrategy.LINEAR]: {\n maxAttempts: 3,\n baseDelayMs: 2000,\n maxDelayMs: 10000,\n multiplier: 1.0\n },\n [RetryStrategy.NONE]: {\n maxAttempts: 1,\n baseDelayMs: 0,\n maxDelayMs: 0,\n multiplier: 1.0\n }\n};\n\n/**\n * Error classification rules\n */\nconst CLASSIFICATION_RULES: Record<ErrorCategory, ErrorClassification> = {\n [ErrorCategory.NETWORK]: {\n category: ErrorCategory.NETWORK,\n retryStrategy: RetryStrategy.AGGRESSIVE,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.AGGRESSIVE],\n description: 'Network connectivity or communication error',\n troubleshooting: [\n 'Check internet connection',\n 'Verify LIT Protocol network status',\n 'Check firewall and proxy settings',\n 'Try connecting to different node endpoints'\n ]\n },\n\n [ErrorCategory.PROTOCOL]: {\n category: ErrorCategory.PROTOCOL,\n retryStrategy: RetryStrategy.CONSERVATIVE,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.CONSERVATIVE],\n description: 'LIT Protocol specific operational error',\n troubleshooting: [\n 'Check LIT Protocol network status',\n 'Verify PKP configuration',\n 'Check signing shares availability',\n 'Wait for network consensus'\n ]\n },\n\n [ErrorCategory.AUTHENTICATION]: {\n category: ErrorCategory.AUTHENTICATION,\n retryStrategy: RetryStrategy.EXPONENTIAL,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.EXPONENTIAL],\n maxAttempts: 2, // Override: limited retries for auth issues\n description: 'Authentication or authorization error',\n troubleshooting: [\n 'Check session signatures validity',\n 'Regenerate authentication tokens',\n 'Verify wallet permissions',\n 'Check PKP authorization status'\n ]\n },\n\n [ErrorCategory.RESOURCE]: {\n category: ErrorCategory.RESOURCE,\n retryStrategy: RetryStrategy.LINEAR,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.LINEAR],\n maxAttempts: 2, // Override: limited retries for resource issues\n description: 'Resource not found or validation error',\n troubleshooting: [\n 'Verify resource CIDs are correct',\n 'Check IPFS availability',\n 'Confirm PKP exists and is accessible',\n 'Wait for resource propagation'\n ]\n },\n\n [ErrorCategory.VALIDATION]: {\n category: ErrorCategory.VALIDATION,\n retryStrategy: RetryStrategy.NONE,\n isRetryable: false,\n ...RETRY_STRATEGIES[RetryStrategy.NONE],\n description: 'Input validation or schema error',\n troubleshooting: [\n 'Check input parameters format',\n 'Verify required fields are provided',\n 'Validate data types and ranges',\n 'Review API documentation'\n ]\n },\n\n [ErrorCategory.TIMEOUT]: {\n category: ErrorCategory.TIMEOUT,\n retryStrategy: RetryStrategy.CONSERVATIVE,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.CONSERVATIVE],\n description: 'Operation timeout error',\n troubleshooting: [\n 'Increase timeout values',\n 'Check network latency',\n 'Verify system resources',\n 'Split operations into smaller chunks'\n ]\n },\n\n [ErrorCategory.RATE_LIMIT]: {\n category: ErrorCategory.RATE_LIMIT,\n retryStrategy: RetryStrategy.CONSERVATIVE,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.CONSERVATIVE],\n maxAttempts: 2, // Override: limited retries to avoid further rate limiting\n baseDelayMs: 5000, // Override: longer delays for rate limits\n description: 'Rate limit or quota exceeded',\n troubleshooting: [\n 'Reduce request frequency',\n 'Implement request batching',\n 'Check rate limit headers',\n 'Wait for quota reset'\n ]\n },\n\n [ErrorCategory.CONFIGURATION]: {\n category: ErrorCategory.CONFIGURATION,\n retryStrategy: RetryStrategy.NONE,\n isRetryable: false,\n ...RETRY_STRATEGIES[RetryStrategy.NONE],\n description: 'Configuration or setup error',\n troubleshooting: [\n 'Check environment variables',\n 'Verify configuration files',\n 'Review setup documentation',\n 'Check required dependencies'\n ]\n },\n\n [ErrorCategory.UNKNOWN]: {\n category: ErrorCategory.UNKNOWN,\n retryStrategy: RetryStrategy.EXPONENTIAL,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.EXPONENTIAL],\n maxAttempts: 2, // Override: conservative retries for unknown errors\n description: 'Unknown or unclassified error',\n troubleshooting: [\n 'Check logs for more details',\n 'Verify system status',\n 'Try again with debug logging',\n 'Contact support if persists'\n ]\n }\n};\n\n/**\n * Classify an error and determine retry strategy\n */\nexport function classifyError(error: any): ErrorClassification {\n const errorMessage = error?.message || error?.toString() || '';\n const errorLower = errorMessage.toLowerCase();\n\n // Check each error category\n for (const [category, patterns] of Object.entries(LIT_ERROR_PATTERNS)) {\n for (const pattern of patterns) {\n if (pattern.test(errorMessage) || pattern.test(errorLower)) {\n const classification = CLASSIFICATION_RULES[category as ErrorCategory];\n return {\n ...classification,\n description: `${classification.description}: ${errorMessage.slice(0, 100)}`\n };\n }\n }\n }\n\n // Default to unknown category\n const unknownClassification = CLASSIFICATION_RULES[ErrorCategory.UNKNOWN];\n return {\n ...unknownClassification,\n description: `${unknownClassification.description}: ${errorMessage.slice(0, 100)}`\n };\n}\n\n/**\n * Get retry configuration from error classification\n */\nexport function getRetryConfigFromClassification(classification: ErrorClassification) {\n return {\n maxAttempts: classification.maxAttempts,\n initialDelayMs: classification.baseDelayMs,\n maxDelayMs: classification.maxDelayMs,\n backoffMultiplier: RETRY_STRATEGIES[classification.retryStrategy].multiplier,\n retryableErrors: ['*'] // Classification already determined retryability\n };\n}\n\n/**\n * Enhanced error analyzer for detailed error information\n */\nexport function analyzeError(error: any) {\n const classification = classifyError(error);\n\n return {\n ...classification,\n originalError: error,\n errorMessage: error?.message || error?.toString() || 'Unknown error',\n errorStack: error?.stack,\n timestamp: new Date().toISOString(),\n retryConfig: getRetryConfigFromClassification(classification)\n };\n}\n\n/**\n * Create a human-readable error report\n */\nexport function createErrorReport(error: any) {\n const analysis = analyzeError(error);\n\n const report = [\n `\uD83D\uDD0D Error Analysis Report`,\n `=====================================`,\n `Category: ${analysis.category.toUpperCase()}`,\n `Retryable: ${analysis.isRetryable ? '\u2705 Yes' : '\u274C No'}`,\n `Strategy: ${analysis.retryStrategy}`,\n `Max Attempts: ${analysis.maxAttempts}`,\n `Description: ${analysis.description}`,\n `Timestamp: ${analysis.timestamp}`,\n ``,\n `Original Error: ${analysis.errorMessage}`,\n ``\n ];\n\n if (analysis.troubleshooting && analysis.troubleshooting.length > 0) {\n report.push(`\uD83D\uDEE0\uFE0F Troubleshooting Steps:`);\n analysis.troubleshooting.forEach((step, index) => {\n report.push(` ${index + 1}. ${step}`);\n });\n report.push('');\n }\n\n return report.join('\\n');\n}\n\n/**\n * LIT Protocol specific error matchers\n */\nexport const litProtocolErrors = {\n isNetworkError: (error: any) => classifyError(error).category === ErrorCategory.NETWORK,\n isProtocolError: (error: any) => classifyError(error).category === ErrorCategory.PROTOCOL,\n isAuthenticationError: (error: any) => classifyError(error).category === ErrorCategory.AUTHENTICATION,\n isResourceError: (error: any) => classifyError(error).category === ErrorCategory.RESOURCE,\n isTimeoutError: (error: any) => classifyError(error).category === ErrorCategory.TIMEOUT,\n isRateLimitError: (error: any) => classifyError(error).category === ErrorCategory.RATE_LIMIT,\n isConfigurationError: (error: any) => classifyError(error).category === ErrorCategory.CONFIGURATION,\n isRetryable: (error: any) => classifyError(error).isRetryable\n};", "/**\n * Diamond Hands LIT Actions Utilities\n * All utility functions for working with deployed LIT Actions\n */\n\nexport * from \"./chunks/lit-action-helpers\";\nexport * from \"./chunks/pkp-setup\";\nexport * from \"./chunks/cid-utils\";\nexport * from \"./chunks/connection-helpers\";\nexport * from \"./chunks/debug-logger\";\nexport * from \"./chunks/error-classification\";\nexport * from \"./chunks/session-signature-cache\";\n"],
4
+ "sourcesContent": ["/**\n * Enhanced Debug Logger for LIT Protocol Operations\n * Provides detailed logging for debugging network and protocol issues\n */\n\nexport enum LogLevel {\n ERROR = 0,\n WARN = 1,\n INFO = 2,\n DEBUG = 3,\n TRACE = 4\n}\n\nexport interface DebugConfig {\n level: LogLevel;\n enableTimestamps: boolean;\n enablePerformanceMetrics: boolean;\n enableRequestLogging: boolean;\n enableNetworkMetrics: boolean;\n}\n\nexport const DEFAULT_DEBUG_CONFIG: DebugConfig = {\n level: LogLevel.INFO,\n enableTimestamps: true,\n enablePerformanceMetrics: true,\n enableRequestLogging: true,\n enableNetworkMetrics: true\n};\n\nlet debugConfig: DebugConfig = { ...DEFAULT_DEBUG_CONFIG };\n\n/**\n * Configure debug logging\n */\nexport function configureDebugLogging(config: Partial<DebugConfig>): void {\n debugConfig = { ...debugConfig, ...config };\n}\n\n/**\n * Get current timestamp string\n */\nfunction getTimestamp(): string {\n return new Date().toISOString();\n}\n\n/**\n * Format log message with metadata\n */\nfunction formatMessage(level: string, component: string, message: string, metadata?: any): string {\n const timestamp = debugConfig.enableTimestamps ? `[${getTimestamp()}] ` : '';\n const metadataStr = metadata ? ` ${JSON.stringify(metadata)}` : '';\n return `${timestamp}[${level}] [${component}] ${message}${metadataStr}`;\n}\n\n/**\n * Performance metrics tracker\n */\nexport class PerformanceTracker {\n private startTime: number;\n private markers: Map<string, number> = new Map();\n\n constructor(private operationName: string) {\n this.startTime = Date.now();\n this.log('PERF', `Started: ${operationName}`);\n }\n\n mark(label: string): void {\n const elapsed = Date.now() - this.startTime;\n this.markers.set(label, elapsed);\n this.log('PERF', `${this.operationName} - ${label}: ${elapsed}ms`);\n }\n\n end(success: boolean = true): number {\n const totalTime = Date.now() - this.startTime;\n const status = success ? 'SUCCESS' : 'FAILED';\n this.log('PERF', `${this.operationName} - ${status}: ${totalTime}ms`);\n\n if (debugConfig.enablePerformanceMetrics && this.markers.size > 0) {\n console.log(`\uD83D\uDCCA Performance Breakdown for ${this.operationName}:`);\n for (const [label, time] of this.markers) {\n console.log(` ${label}: ${time}ms`);\n }\n console.log(` Total: ${totalTime}ms`);\n }\n\n return totalTime;\n }\n\n private log(level: string, message: string): void {\n if (debugConfig.enablePerformanceMetrics) {\n console.log(formatMessage(level, 'PERFORMANCE', message));\n }\n }\n}\n\n/**\n * Network metrics collector\n */\nexport interface NetworkMetrics {\n requestCount: number;\n successCount: number;\n failureCount: number;\n averageLatency: number;\n lastError?: string;\n startTime: number;\n}\n\nclass NetworkMetricsCollector {\n private metrics: Map<string, NetworkMetrics> = new Map();\n\n getMetrics(operation: string): NetworkMetrics {\n if (!this.metrics.has(operation)) {\n this.metrics.set(operation, {\n requestCount: 0,\n successCount: 0,\n failureCount: 0,\n averageLatency: 0,\n startTime: Date.now()\n });\n }\n return this.metrics.get(operation)!;\n }\n\n recordRequest(operation: string, success: boolean, latency: number, error?: string): void {\n const metrics = this.getMetrics(operation);\n metrics.requestCount++;\n\n if (success) {\n metrics.successCount++;\n // Update average latency\n metrics.averageLatency = (metrics.averageLatency * (metrics.successCount - 1) + latency) / metrics.successCount;\n } else {\n metrics.failureCount++;\n if (error) metrics.lastError = error;\n }\n\n if (debugConfig.enableNetworkMetrics) {\n const successRate = ((metrics.successCount / metrics.requestCount) * 100).toFixed(1);\n debugLog('NETWORK', `${operation} - Success: ${success}, Latency: ${latency}ms, Success Rate: ${successRate}%`);\n }\n }\n\n printSummary(): void {\n if (!debugConfig.enableNetworkMetrics) return;\n\n console.log('\\n\uD83D\uDCC8 Network Metrics Summary:');\n for (const [operation, metrics] of this.metrics) {\n const successRate = ((metrics.successCount / metrics.requestCount) * 100).toFixed(1);\n const runtime = Date.now() - metrics.startTime;\n console.log(` ${operation}:`);\n console.log(` Requests: ${metrics.requestCount}`);\n console.log(` Success Rate: ${successRate}%`);\n console.log(` Avg Latency: ${metrics.averageLatency.toFixed(0)}ms`);\n console.log(` Runtime: ${runtime}ms`);\n if (metrics.lastError) {\n console.log(` Last Error: ${metrics.lastError}`);\n }\n }\n }\n}\n\nexport const networkMetrics = new NetworkMetricsCollector();\n\n/**\n * Debug logging functions\n */\nexport function debugError(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.ERROR) {\n console.error(formatMessage('ERROR', component, message, metadata));\n }\n}\n\nexport function debugWarn(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.WARN) {\n console.warn(formatMessage('WARN', component, message, metadata));\n }\n}\n\nexport function debugInfo(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.INFO) {\n console.log(formatMessage('INFO', component, message, metadata));\n }\n}\n\nexport function debugLog(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.DEBUG) {\n console.log(formatMessage('DEBUG', component, message, metadata));\n }\n}\n\nexport function debugTrace(component: string, message: string, metadata?: any): void {\n if (debugConfig.level >= LogLevel.TRACE) {\n console.log(formatMessage('TRACE', component, message, metadata));\n }\n}\n\n/**\n * Request/Response logger for LIT Protocol operations\n */\nexport function logRequest(component: string, operation: string, params: any): void {\n if (!debugConfig.enableRequestLogging) return;\n\n debugLog(component, `\uD83D\uDD04 Request: ${operation}`, {\n operation,\n params: JSON.stringify(params, null, 2)\n });\n}\n\nexport function logResponse(component: string, operation: string, response: any, duration: number): void {\n if (!debugConfig.enableRequestLogging) return;\n\n debugLog(component, `\u2705 Response: ${operation} (${duration}ms)`, {\n operation,\n duration,\n response: typeof response === 'object' ? JSON.stringify(response, null, 2) : response\n });\n}\n\nexport function logError(component: string, operation: string, error: any, duration?: number): void {\n const durationStr = duration ? ` (${duration}ms)` : '';\n debugError(component, `\u274C Error: ${operation}${durationStr}`, {\n operation,\n duration,\n error: error?.message || error?.toString() || 'Unknown error',\n stack: error?.stack\n });\n}\n\n/**\n * Network connection logger\n */\nexport function logConnectionAttempt(network: string, attempt: number, maxAttempts: number): void {\n debugInfo('CONNECTION', `\uD83D\uDD17 Connecting to ${network} (attempt ${attempt}/${maxAttempts})`);\n}\n\nexport function logConnectionSuccess(network: string, latency: number): void {\n debugInfo('CONNECTION', `\u2705 Connected to ${network} (${latency}ms)`);\n networkMetrics.recordRequest(`connection-${network}`, true, latency);\n}\n\nexport function logConnectionFailure(network: string, error: string, attempt: number): void {\n debugError('CONNECTION', `\u274C Connection failed to ${network} (attempt ${attempt})`, { error });\n networkMetrics.recordRequest(`connection-${network}`, false, 0, error);\n}\n\n/**\n * PKP operation logger\n */\nexport function logPkpOperation(operation: string, pkpId?: string, details?: any): void {\n const pkpStr = pkpId ? ` (PKP: ${pkpId.slice(0, 8)}...)` : '';\n debugInfo('PKP', `\uD83D\uDD11 ${operation}${pkpStr}`, details);\n}\n\n/**\n * Session signature logger\n */\nexport function logSessionSignatures(count: number, expiration: string): void {\n debugInfo('SESSION', `\uD83D\uDD10 Generated ${count} session signatures (expires: ${expiration})`);\n}\n\n/**\n * LIT Action execution logger\n */\nexport function logLitActionExecution(cid: string, params: any): void {\n debugInfo('LIT_ACTION', `\u26A1 Executing LIT Action: ${cid}`, {\n cid,\n params\n });\n}\n\nexport function logLitActionResult(cid: string, success: boolean, duration: number, result?: any): void {\n const status = success ? '\u2705' : '\u274C';\n debugInfo('LIT_ACTION', `${status} LIT Action completed: ${cid} (${duration}ms)`, {\n cid,\n success,\n duration,\n result: success && result ? JSON.stringify(result, null, 2) : undefined\n });\n}\n\n/**\n * Test lifecycle logger\n */\nexport function logTestStart(testName: string): PerformanceTracker {\n debugInfo('TEST', `\uD83E\uDDEA Starting test: ${testName}`);\n return new PerformanceTracker(testName);\n}\n\nexport function logTestEnd(testName: string, success: boolean, duration: number): void {\n const status = success ? '\u2705' : '\u274C';\n debugInfo('TEST', `${status} Test completed: ${testName} (${duration}ms)`);\n networkMetrics.printSummary();\n}", "/**\n * Session Signature Cache for PKP Operations\n * Provides intelligent caching of session signatures to avoid regeneration\n */\n\nimport { debugInfo, debugWarn, debugLog } from './debug-logger';\n\n/**\n * Cache entry for session signatures\n */\ninterface SessionSignatureCacheEntry {\n sessionSigs: any;\n expiration: Date;\n pkpTokenId: string;\n litActionCid: string;\n signerAddress: string;\n network: string;\n createdAt: Date;\n}\n\n/**\n * Session signature cache configuration\n */\nexport interface SessionSignatureCacheConfig {\n maxEntries: number;\n bufferTimeMs: number; // Time before expiration to consider entry stale\n enableLogging: boolean;\n}\n\nexport const DEFAULT_CACHE_CONFIG: SessionSignatureCacheConfig = {\n maxEntries: 50,\n bufferTimeMs: 60000, // 1 minute buffer before expiration\n enableLogging: true\n};\n\n/**\n * In-memory session signature cache\n */\nclass SessionSignatureCache {\n private cache = new Map<string, SessionSignatureCacheEntry>();\n private config: SessionSignatureCacheConfig;\n\n constructor(config: Partial<SessionSignatureCacheConfig> = {}) {\n this.config = { ...DEFAULT_CACHE_CONFIG, ...config };\n }\n\n /**\n * Generate cache key from PKP and context\n */\n private generateCacheKey(\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string\n ): string {\n return `${signerAddress}-${network}-${pkpTokenId}-${litActionCid}`;\n }\n\n /**\n * Check if cache entry is still valid\n */\n private isEntryValid(entry: SessionSignatureCacheEntry): boolean {\n const now = new Date();\n const expirationWithBuffer = new Date(\n entry.expiration.getTime() - this.config.bufferTimeMs\n );\n\n return now < expirationWithBuffer;\n }\n\n /**\n * Clean expired entries from cache\n */\n private cleanExpiredEntries(): void {\n const now = new Date();\n let cleanedCount = 0;\n\n for (const [key, entry] of this.cache.entries()) {\n if (now >= entry.expiration) {\n this.cache.delete(key);\n cleanedCount++;\n }\n }\n\n if (cleanedCount > 0 && this.config.enableLogging) {\n debugInfo('CACHE', `\uD83E\uDDF9 Cleaned ${cleanedCount} expired session signature entries`);\n }\n }\n\n /**\n * Enforce cache size limits\n */\n private enforceCacheSize(): void {\n if (this.cache.size <= this.config.maxEntries) {\n return;\n }\n\n // Sort entries by creation time and remove oldest\n const entries = Array.from(this.cache.entries())\n .sort(([, a], [, b]) => a.createdAt.getTime() - b.createdAt.getTime());\n\n const toRemove = entries.slice(0, this.cache.size - this.config.maxEntries);\n\n for (const [key] of toRemove) {\n this.cache.delete(key);\n }\n\n if (this.config.enableLogging) {\n debugInfo('CACHE', `\uD83D\uDCE6 Removed ${toRemove.length} oldest cache entries to maintain size limit`);\n }\n }\n\n /**\n * Get cached session signatures if valid\n */\n get(\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string\n ): any | null {\n this.cleanExpiredEntries();\n\n const cacheKey = this.generateCacheKey(pkpTokenId, litActionCid, signerAddress, network);\n const entry = this.cache.get(cacheKey);\n\n if (!entry) {\n if (this.config.enableLogging) {\n debugLog('CACHE', `\u274C Session signatures cache miss: ${cacheKey}`);\n }\n return null;\n }\n\n if (!this.isEntryValid(entry)) {\n this.cache.delete(cacheKey);\n if (this.config.enableLogging) {\n debugWarn('CACHE', `\u23F0 Session signatures expired: ${cacheKey}`);\n }\n return null;\n }\n\n if (this.config.enableLogging) {\n const timeUntilExpiry = entry.expiration.getTime() - Date.now();\n debugInfo('CACHE', `\u2705 Session signatures cache hit: ${cacheKey} (expires in ${Math.round(timeUntilExpiry/1000)}s)`);\n }\n\n return entry.sessionSigs;\n }\n\n /**\n * Cache session signatures\n */\n set(\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string,\n sessionSigs: any,\n expiration: Date\n ): void {\n const cacheKey = this.generateCacheKey(pkpTokenId, litActionCid, signerAddress, network);\n\n const entry: SessionSignatureCacheEntry = {\n sessionSigs,\n expiration,\n pkpTokenId,\n litActionCid,\n signerAddress,\n network,\n createdAt: new Date()\n };\n\n this.cache.set(cacheKey, entry);\n\n if (this.config.enableLogging) {\n const timeUntilExpiry = expiration.getTime() - Date.now();\n debugInfo('CACHE', `\uD83D\uDCBE Cached session signatures: ${cacheKey} (expires in ${Math.round(timeUntilExpiry/1000)}s)`);\n }\n\n this.enforceCacheSize();\n }\n\n /**\n * Clear all cached session signatures\n */\n clear(): void {\n const size = this.cache.size;\n this.cache.clear();\n\n if (this.config.enableLogging) {\n debugInfo('CACHE', `\uD83D\uDDD1\uFE0F Cleared ${size} cached session signature entries`);\n }\n }\n\n /**\n * Get cache statistics\n */\n getStats() {\n this.cleanExpiredEntries();\n\n return {\n size: this.cache.size,\n maxEntries: this.config.maxEntries,\n utilizationPercent: Math.round((this.cache.size / this.config.maxEntries) * 100)\n };\n }\n\n /**\n * Remove specific cache entry\n */\n delete(\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string\n ): boolean {\n const cacheKey = this.generateCacheKey(pkpTokenId, litActionCid, signerAddress, network);\n const deleted = this.cache.delete(cacheKey);\n\n if (deleted && this.config.enableLogging) {\n debugInfo('CACHE', `\uD83D\uDDD1\uFE0F Removed session signatures from cache: ${cacheKey}`);\n }\n\n return deleted;\n }\n}\n\n// Global session signature cache instance\nexport const sessionSignatureCache = new SessionSignatureCache();\n\n/**\n * Enhanced session signature generator with caching\n */\nexport async function generateSessionSignaturesWithCache(\n litNodeClient: any,\n sessionConfig: any,\n pkpTokenId: string,\n litActionCid: string,\n signerAddress: string,\n network: string = 'chipotle'\n): Promise<any> {\n // Check cache first\n const cached = sessionSignatureCache.get(pkpTokenId, litActionCid, signerAddress, network);\n if (cached) {\n return cached;\n }\n\n // Generate new session signatures\n debugInfo('CACHE', '\uD83D\uDD10 Generating new session signatures (cache miss)...');\n const sessionSigs = await litNodeClient.getSessionSigs(sessionConfig);\n\n // Extract expiration from config\n const expiration = new Date(sessionConfig.expiration);\n\n // Cache the result\n sessionSignatureCache.set(pkpTokenId, litActionCid, signerAddress, network, sessionSigs, expiration);\n\n const sigCount = Object.keys(sessionSigs).length;\n debugInfo('CACHE', `\u2705 Generated and cached ${sigCount} session signatures`);\n\n return sessionSigs;\n}\n\n/**\n * Configure the global session signature cache\n */\nexport function configureSessionSignatureCache(config: Partial<SessionSignatureCacheConfig>): void {\n Object.assign(sessionSignatureCache['config'], config);\n}\n\n/**\n * Clear the global session signature cache\n */\nexport function clearSessionSignatureCache(): void {\n sessionSignatureCache.clear();\n}\n\n/**\n * Get session signature cache statistics\n */\nexport function getSessionSignatureCacheStats() {\n return sessionSignatureCache.getStats();\n}", "/**\n * dh-lit-actions Package\n * Diamond Hands Protocol LIT Actions Registry\n *\n * This package exports deployed LIT Action CIDs and metadata\n * for consumption by the Diamond Hands SDK and other applications.\n */\n\n// Export interfaces\nexport * from \"./interfaces\";\n\n// Export constants from registry\nexport * from \"./constants/chunks/lit-actions-registry\";\n\n// Export utilities\nexport * from \"./utils\";\n\n// Export NOLA executors (commented out - executors import from src/ which is outside rootDir)\n// export * from \"./executors\";\n\n// Default export\nexport { DH_LIT_ACTIONS_CHIPOTLE, CHIPOTLE_DEPLOYMENTS } from \"./constants/chunks/lit-actions-registry\";\n", "// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\nfunction base (ALPHABET) {\n if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }\n const BASE_MAP = new Uint8Array(256)\n for (let j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255\n }\n for (let i = 0; i < ALPHABET.length; i++) {\n const x = ALPHABET.charAt(i)\n const xc = x.charCodeAt(0)\n if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }\n BASE_MAP[xc] = i\n }\n const BASE = ALPHABET.length\n const LEADER = ALPHABET.charAt(0)\n const FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up\n const iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up\n function encode (source) {\n // eslint-disable-next-line no-empty\n if (source instanceof Uint8Array) { } else if (ArrayBuffer.isView(source)) {\n source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength)\n } else if (Array.isArray(source)) {\n source = Uint8Array.from(source)\n }\n if (!(source instanceof Uint8Array)) { throw new TypeError('Expected Uint8Array') }\n if (source.length === 0) { return '' }\n // Skip & count leading zeroes.\n let zeroes = 0\n let length = 0\n let pbegin = 0\n const pend = source.length\n while (pbegin !== pend && source[pbegin] === 0) {\n pbegin++\n zeroes++\n }\n // Allocate enough space in big-endian base58 representation.\n const size = ((pend - pbegin) * iFACTOR + 1) >>> 0\n const b58 = new Uint8Array(size)\n // Process the bytes.\n while (pbegin !== pend) {\n let carry = source[pbegin]\n // Apply \"b58 = b58 * 256 + ch\".\n let i = 0\n for (let it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {\n carry += (256 * b58[it1]) >>> 0\n b58[it1] = (carry % BASE) >>> 0\n carry = (carry / BASE) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n pbegin++\n }\n // Skip leading zeroes in base58 result.\n let it2 = size - length\n while (it2 !== size && b58[it2] === 0) {\n it2++\n }\n // Translate the result into a string.\n let str = LEADER.repeat(zeroes)\n for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]) }\n return str\n }\n function decodeUnsafe (source) {\n if (typeof source !== 'string') { throw new TypeError('Expected String') }\n if (source.length === 0) { return new Uint8Array() }\n let psz = 0\n // Skip and count leading '1's.\n let zeroes = 0\n let length = 0\n while (source[psz] === LEADER) {\n zeroes++\n psz++\n }\n // Allocate enough space in big-endian base256 representation.\n const size = (((source.length - psz) * FACTOR) + 1) >>> 0 // log(58) / log(256), rounded up.\n const b256 = new Uint8Array(size)\n // Process the characters.\n while (psz < source.length) {\n // Find code of next character\n const charCode = source.charCodeAt(psz)\n // Base map can not be indexed using char code\n if (charCode > 255) { return }\n // Decode character\n let carry = BASE_MAP[charCode]\n // Invalid character\n if (carry === 255) { return }\n let i = 0\n for (let it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {\n carry += (BASE * b256[it3]) >>> 0\n b256[it3] = (carry % 256) >>> 0\n carry = (carry / 256) >>> 0\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i\n psz++\n }\n // Skip leading zeroes in b256.\n let it4 = size - length\n while (it4 !== size && b256[it4] === 0) {\n it4++\n }\n const vch = new Uint8Array(zeroes + (size - it4))\n let j = zeroes\n while (it4 !== size) {\n vch[j++] = b256[it4++]\n }\n return vch\n }\n function decode (string) {\n const buffer = decodeUnsafe(string)\n if (buffer) { return buffer }\n throw new Error('Non-base' + BASE + ' character')\n }\n return {\n encode,\n decodeUnsafe,\n decode\n }\n}\nexport default base\n", "import basex from 'base-x';\nvar ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';\nexport default basex(ALPHABET);\n", "import bs58 from \"bs58\";\n\n/**\n * Convert IPFS CID from base58 to hex format for contract authorization\n * This matches the format expected by LIT Protocol smart contracts\n */\nexport function cidToHex(cid: string): string {\n try {\n if (cid.startsWith(\"Qm\")) {\n // v0 CID - convert base58 to hex\n const bytes = bs58.decode(cid);\n return \"0x\" + Buffer.from(bytes).toString(\"hex\");\n } else if (cid.startsWith(\"0x\")) {\n // Already in hex format\n return cid;\n } else {\n // Unknown format - FAIL FAST\n throw new Error(`Unsupported CID format: ${cid}. Only CIDv0 (Qm...) and hex (0x...) formats are supported.`);\n }\n } catch (error) {\n if (error instanceof Error && error.message.includes('Unsupported CID format')) {\n // Re-throw our own errors\n throw error;\n }\n // bs58 decode or other conversion errors\n throw new Error(`Failed to convert CID ${cid} to hex: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n", "import { DiamondHandsLitActions } from \"../../interfaces\";\nimport { cidToHex } from \"../../utils/chunks/cid-utils\";\n\nexport type SupportedLitNetwork = \"chipotle\";\n\n/**\n * Diamond Hands LIT Actions Registry \u2014 Chipotle (new REST API)\n * Contains all deployed LIT Actions with their IPFS CIDs and PKP metadata\n */\nexport const DH_LIT_ACTIONS_CHIPOTLE: Partial<DiamondHandsLitActions> = {\n authorizationDummy: {\n cid: \"QmXPh5RTReLqjqZDRNhgVKi1TWMJK2vS9QSRPkWPhLBQJN\",\n authorizedCidHex: cidToHex(\n \"QmXPh5RTReLqjqZDRNhgVKi1TWMJK2vS9QSRPkWPhLBQJN\",\n ),\n name: \"Authorization Dummy\",\n description: \"Production Authorization Dummy\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1776707622939,\n size: 2026,\n hash: \"349d51aa096d56b394f82de75ed34cd4eef72719969f7e5fe584f4582b2745fa\",\n },\n authorizationDummyB: {\n cid: \"QmQXTcAU9tr4YAVrzHujEJw9moJgM1o5gnJU2ojcvhigua\",\n authorizedCidHex: cidToHex(\n \"QmQXTcAU9tr4YAVrzHujEJw9moJgM1o5gnJU2ojcvhigua\",\n ),\n name: \"Authorization Dummy B\",\n description: \"Production Authorization Dummy B\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1776707632987,\n size: 1695,\n hash: \"def4576ba6c382d145f996c4f950b5e39e58792415ee7fdd749e0d2bc61e8f0b\",\n },\n pkpValidator: {\n cid: \"QmTqsmXkjib7CRGFcEhmCs61Z3EZTaRPznaZDDLk5Wq9NX\",\n authorizedCidHex: cidToHex(\n \"QmTqsmXkjib7CRGFcEhmCs61Z3EZTaRPznaZDDLk5Wq9NX\",\n ),\n name: \"Pkp Validator\",\n description: \"Production Pkp Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311468630,\n size: 3999,\n hash: \"baba8c31b73dbfe6425d8f9fd69c61f41a573e189a185962382b815a15fddb24\",\n validatorWalletAddress: \"0x9ee56687f7a984d5df7ab79330271a619ef56ddd\",\n pkp: {\n publicKey:\n \"0x04ec0e3acc40884e3f366ca469d08899eb640ad5259fa196b0238075086208a9f8732a3175704f35f0bcc28e07406cfb24c254efd1e7355640577330f0d2dd755f\",\n ethAddress: \"0x9eE56687F7a984D5DF7aB79330271a619ef56DdD\",\n },\n },\n btcTransactionSigner: {\n cid: \"QmYSvuDcn2EPjRoDsPBLK2e3PGYEUHtWAPxwB51s4unkaG\",\n authorizedCidHex: cidToHex(\n \"QmYSvuDcn2EPjRoDsPBLK2e3PGYEUHtWAPxwB51s4unkaG\",\n ),\n name: \"Btc Transaction Signer\",\n description: \"Production Btc Transaction Signer\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1776767100453,\n size: 25657,\n hash: \"422311d10447a806bf435a1df440ff00d4eee986c019ccdb4af15bdbfd8019cf\",\n },\n ucdMintValidator: {\n cid: \"QmbYWJkLBdxTCNUkYTVmBzcp4CFhAn7ZcCyMZjhhbjAUMB\",\n authorizedCidHex: cidToHex(\n \"QmbYWJkLBdxTCNUkYTVmBzcp4CFhAn7ZcCyMZjhhbjAUMB\",\n ),\n name: \"Ucd Mint Validator\",\n description: \"Production Ucd Mint Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311478949,\n size: 65507,\n hash: \"f079aa1fc53fe04b08508379feba5d55d2d334ab9ee21bee043c05cf592eced3\",\n validatorWalletAddress: \"0x36f3dd61c4c08a56d29ed2fd6d5f111b67b6a7a1\",\n pkp: {\n publicKey:\n \"0x041ab17cd91fc5c0b761eea6092d032807561b621b82c488826776e04a9158d61ba64d809a4729f0501289d980732cb06d8dfd06999dd9c8efd2f495dad78b31bb\",\n ethAddress: \"0x4D9299055093938d0CD2F26C42A87260CB50adD8\",\n },\n },\n processPaymentValidator: {\n cid: \"Qmc9gkDVY1SK9vvyQ9cXa3PSSuv8q6Ki9o9rsG87qpXCYi\",\n authorizedCidHex: cidToHex(\n \"Qmc9gkDVY1SK9vvyQ9cXa3PSSuv8q6Ki9o9rsG87qpXCYi\",\n ),\n name: \"Process Payment Validator\",\n description: \"Production Process Payment Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311488810,\n size: 61413,\n hash: \"2ffbd15b1429edb7ddc7587ea8d30d45d4182a2bd3fc22e5986f9b4850440a9b\",\n validatorWalletAddress: \"0xc2ed5a59bd81eb4d1a19a0147b86ab69aa4c28ba\",\n pkp: {\n publicKey:\n \"0x04cfccb9b6c7addc79469c0e9fafebef4c70801302c62cdb26b610723a9b8527d23f98a40158c7340d83fd0e62d02b5ec74c12f7a86d98e8c6973b4811110f19ad\",\n ethAddress: \"0x440Fd7B157766b95eb551825C06DF4f92E41D55b\",\n },\n },\n extendPositionValidator: {\n cid: \"Qmc5MDW6ZxTRe3nXJEKa5KKUCVXFznV9vDqFL4n7ayRZ4p\",\n authorizedCidHex: cidToHex(\n \"Qmc5MDW6ZxTRe3nXJEKa5KKUCVXFznV9vDqFL4n7ayRZ4p\",\n ),\n name: \"Extend Position Validator\",\n description: \"Production Extend Position Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311498958,\n size: 60870,\n hash: \"624cbc2514b8be7b2e8cc3a509dce282db9213e43a7675f058ecebe4eb9faa40\",\n validatorWalletAddress: \"0xb3f4271c475887a86a2f21446f0968c30cc74c97\",\n pkp: {\n publicKey:\n \"0x04e52338f6a0c3362800f1a94c4c8f08be5030dde0fa217388c53d1c1a4790f4443c9f2886b2d2d8f4b75a9a156e9b028011b1a1cf7648da0e556aa980ec692836\",\n ethAddress: \"0x4cb7651Ba27610991A5775486B5F4487F3Dd7cDA\",\n },\n },\n btcWithdrawal: {\n cid: \"QmQC7QKobtNJKArGK7rgGj8ZCcEWt1pBKXPyd5SZ2fi4tt\",\n authorizedCidHex: cidToHex(\n \"QmQC7QKobtNJKArGK7rgGj8ZCcEWt1pBKXPyd5SZ2fi4tt\",\n ),\n name: \"Btc Withdrawal\",\n description: \"Production Btc Withdrawal\",\n version: \"1.0.1\",\n deployed: true,\n deployedAt: 1777474196351,\n size: 72236,\n hash: \"5d2d3672dfa4027fd17d6bf4740995561ccc4dbe1ed388be19c241ecf5f4018f\",\n validatorWalletAddress: \"0xbb137fbda353199e9419b698c57a742124d4987d\",\n pkp: {\n publicKey:\n \"0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d\",\n ethAddress: \"0x7b9316cAA00B257F7CE30F7F6979bd6867BA9eE2\",\n },\n },\n liquidationValidator: {\n cid: \"QmZscQTKzwqWDZwYfaE57vdG4vYoNeQMkC2DwgJsnRNgQf\",\n authorizedCidHex: cidToHex(\n \"QmZscQTKzwqWDZwYfaE57vdG4vYoNeQMkC2DwgJsnRNgQf\",\n ),\n name: \"Liquidation Validator\",\n description: \"Production Liquidation Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311523132,\n size: 54907,\n hash: \"7a5a63dc80fad2258a0361f767f3efae3a62ec391c34b0927ca770411bf4de3e\",\n validatorWalletAddress: \"0x1542f863ee0340f6a067573e80ae66dd9b3838fa\",\n pkp: {\n publicKey:\n \"0x041a241de58976c13e3d7ca5a18e494f7330151e3818706135d50176e78ffb673e58b11f0b67a87c73fade6c6b27d6e7a7377ea9f4c10bf31880f1d725f18cc6f8\",\n ethAddress: \"0x8770470620Db25bBf2BFBca1eF7Bdd6CF91ab1b5\",\n },\n },\n priceOracle: {\n cid: \"Qma6vTTnn3AFy3A4u3A7T5tT6eEp26vXt7rPHSWpmBpdsp\",\n authorizedCidHex: cidToHex(\n \"Qma6vTTnn3AFy3A4u3A7T5tT6eEp26vXt7rPHSWpmBpdsp\",\n ),\n name: \"Price Oracle\",\n description: \"Production Price Oracle (Chipotle main+getPrivateKey)\",\n version: \"1.1.0\",\n deployed: true,\n deployedAt: 1777311530589,\n size: 11531,\n hash: \"a49e9a4875e68a1b8f1c37bcc8284a28e0995652a7df8bad4f1853408d1c81c8\",\n validatorWalletAddress: \"0x831ddf3048547b983efe3ccbbb35a45a53191651\",\n pkp: {\n publicKey:\n \"0x043beaa1da47875601a8d6f430b1438ee2d4732eefd06e5c63a474bbdaf9e7df1797b1b951e041b627c2bf839788164825324c9cbd1e2d6f740fdd4bff69b1900b\",\n ethAddress: \"0x831DdF3048547B983EFE3ccBBB35a45a53191651\",\n },\n },\n loanVaultBtcBalance: {\n cid: \"QmWGEg79snhDQ5Fkm9pLhNmLKUJY5uXfp3t3276Jybritq\",\n authorizedCidHex: cidToHex(\n \"QmWGEg79snhDQ5Fkm9pLhNmLKUJY5uXfp3t3276Jybritq\",\n ),\n name: \"Loan Vault Btc Balance\",\n description: \"Production Loan Vault Btc Balance\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311539409,\n size: 44293,\n hash: \"70b009f01b9051dee2db1e4030dd17d08dc53728d30b5e24cffd11d07acfcaf0\",\n validatorWalletAddress: \"0x47feea74c8739d24b44faa67217f2f99970e15e7\",\n pkp: {\n publicKey:\n \"0x043616787c5432415c24378c4ef48de2bcd6bb7b575b837e3cff09171802662da7105d79586c7659677a0ecbaddac4cce06cb2a11f69a16fa0c4d7002ac7d51a4d\",\n ethAddress: \"0x7b9316cAA00B257F7CE30F7F6979bd6867BA9eE2\",\n },\n },\n adminLiquidationValidator: {\n cid: \"QmYJJFgFPF4BR4ts9GrAkwfEoQbVSXEwnrciZ5Jj9WTDgd\",\n authorizedCidHex: cidToHex(\n \"QmYJJFgFPF4BR4ts9GrAkwfEoQbVSXEwnrciZ5Jj9WTDgd\",\n ),\n name: \"Admin Liquidation Validator\",\n description: \"Production Admin Liquidation Validator\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1777311549068,\n size: 51556,\n hash: \"8eb26b08623d6be2ded733579d61c389fe312eef8d12ae1e62166c9359bbd037\",\n validatorWalletAddress: \"0x2a83b78842d75358877deb8854ccc5bbbaa5012e\",\n pkp: {\n publicKey:\n \"0x04ee4316afb8538280ede6c56def9cbe791f18f96ccba97768b28e2966d9c46a9493a6b81f4571495c3ce56c2d0b33fe8cf63726cd12d395832ea54162b5c67801\",\n ethAddress: \"0x038B7a1918ae9121bC641236b7946a069BE21591\",\n },\n },\n alwaysSigner: {\n cid: \"QmXQjybSsdE19Da66to9Hh7X2dLFwpZPhjoqojxbpk7Nvs\",\n authorizedCidHex: cidToHex(\n \"QmXQjybSsdE19Da66to9Hh7X2dLFwpZPhjoqojxbpk7Nvs\",\n ),\n name: \"Always Signer\",\n description: \"Production Always Signer\",\n version: \"1.0.0\",\n deployed: true,\n deployedAt: 1776708176283,\n size: 4143,\n hash: \"25007f80b4ed3169470bf617d403971136be431eb29dfb09f78afe2494bf0138\",\n },\n};\n\nexport function getDeploymentsForNetwork(\n network: SupportedLitNetwork,\n): Partial<DiamondHandsLitActions> {\n if (network === \"chipotle\") return DH_LIT_ACTIONS_CHIPOTLE;\n throw new Error(`Unsupported LIT network: ${network}`);\n}\n\nexport const CHIPOTLE_DEPLOYMENTS = DH_LIT_ACTIONS_CHIPOTLE;\n", "import { LitActionConfig, LitActionName } from \"../../interfaces\";\nimport {\n getDeploymentsForNetwork,\n SupportedLitNetwork,\n} from \"../../constants/chunks/lit-actions-registry\";\n\n/**\n * Get LIT Action CID by name\n * @param actionName - Name of the LIT Action\n * @returns IPFS CID of the deployed action\n * @throws Error if action is not deployed\n */\nexport function getLitActionCID(\n litNetwork: SupportedLitNetwork = \"chipotle\",\n actionName: LitActionName,\n): string {\n const deployments = getDeploymentsForNetwork(litNetwork);\n const action = deployments[actionName];\n\n if (!action || !action.deployed || !action.cid) {\n throw new Error(\n `LIT Action '${actionName}' not deployed on network '${litNetwork}'. Check deployment status.`,\n );\n }\n return action.cid;\n}\n\n/**\n * Get LIT Action configuration by name\n * @param actionName - Name of the LIT Action\n * @returns Complete LIT Action configuration\n */\nexport function getLitActionConfig(\n actionName: LitActionName,\n litNetwork: SupportedLitNetwork = \"chipotle\",\n): LitActionConfig {\n const deployments = getDeploymentsForNetwork(litNetwork);\n const action = deployments[actionName];\n if (!action) {\n throw new Error(\n `LIT Action '${actionName}' not found in registry for network '${litNetwork}'.`,\n );\n }\n return action;\n}\n\n/**\n * Check if a LIT Action is deployed and ready to use\n * @param actionName - Name of the LIT Action\n * @returns True if deployed, false otherwise\n */\nexport function isLitActionDeployed(\n actionName: LitActionName,\n litNetwork: SupportedLitNetwork = \"chipotle\",\n): boolean {\n const deployments = getDeploymentsForNetwork(litNetwork);\n const action = deployments[actionName];\n return !!(action && action.deployed && action.cid);\n}\n\n/**\n * Validate that all required actions are deployed\n * @param requiredActions - Array of required action names\n * @returns True if all actions are deployed\n */\nexport function validateDeployedActions(\n requiredActions: LitActionName[],\n litNetwork: SupportedLitNetwork = \"chipotle\",\n): boolean {\n return requiredActions.every((actionName) =>\n isLitActionDeployed(actionName, litNetwork),\n );\n}\n\n/**\n * Get all deployed LIT Actions\n * @returns Array of deployed LIT Action configurations\n */\nexport function getDeployedActions(\n litNetwork: SupportedLitNetwork = \"chipotle\",\n): LitActionConfig[] {\n const deployments = getDeploymentsForNetwork(litNetwork);\n return Object.values(deployments).filter(\n (action) => action && action.deployed,\n );\n}\n", "import {\n getDeploymentsForNetwork,\n SupportedLitNetwork,\n} from \"../../constants/chunks/lit-actions-registry\";\n/**\n * Get the complete setup for PKP Validator testing\n * Returns both the LIT Action config and its associated PKP\n */\nexport function getPKPValidatorSetup(\n litNetwork: SupportedLitNetwork = \"chipotle\"\n) {\n const deployments = getDeploymentsForNetwork(litNetwork);\n const litAction = deployments.pkpValidator;\n\n if (!litAction || !litAction.pkp) {\n throw new Error(\n `PKP validator setup is not available for litNetwork='${litNetwork}'. ` +\n `Ensure the pkpValidator action (with pkp attached) is defined in the registry.`\n );\n }\n\n return {\n litAction,\n pkp: litAction.pkp!,\n };\n}\n", "/**\n * LIT Protocol Connection Helpers\n * Provides retry logic, error handling, and connection validation utilities\n * for robust LIT Protocol operations\n */\n\nimport {\n debugInfo,\n debugWarn,\n debugError,\n logConnectionAttempt,\n logConnectionSuccess,\n logConnectionFailure,\n logRequest,\n logResponse,\n logError,\n logPkpOperation,\n logLitActionExecution,\n logLitActionResult,\n networkMetrics,\n PerformanceTracker\n} from './debug-logger';\nimport {\n classifyError,\n getRetryConfigFromClassification,\n createErrorReport,\n litProtocolErrors\n} from './error-classification';\n\n/**\n * Retry configuration options\n */\nexport interface RetryConfig {\n maxAttempts: number;\n initialDelayMs: number;\n maxDelayMs: number;\n backoffMultiplier: number;\n retryableErrors: string[];\n}\n\n/**\n * Default retry configuration optimized for LIT Protocol operations\n */\nexport const DEFAULT_RETRY_CONFIG: RetryConfig = {\n maxAttempts: 5, // Increased from 3 for PKP operations\n initialDelayMs: 2000, // Increased from 1000ms for PKP operations\n maxDelayMs: 60000, // Increased from 30000ms for PKP operations\n backoffMultiplier: 2,\n retryableErrors: [\n 'request_timeout',\n 'network error',\n 'connection failed',\n 'ENOTFOUND',\n 'ECONNREFUSED',\n 'ETIMEDOUT',\n 'socket hang up',\n 'timeout',\n // PKP-specific errors\n 'signing shares',\n 'There was an error getting the signing shares',\n 'PKP validation',\n 'pkp validation failed',\n 'resource validation',\n 'ipfs propagation',\n 'session.*expired',\n 'NodeError',\n 'Response from the nodes',\n 'consensus',\n 'threshold'\n ]\n};\n\n/**\n * Connection validation result\n */\nexport interface ConnectionValidationResult {\n isValid: boolean;\n error?: string;\n latencyMs?: number;\n}\n\n/**\n * Sleep utility for retry delays\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/**\n * Check if an error is retryable using enhanced classification system\n */\nexport function isRetryableError(error: any, retryableErrors: string[] = DEFAULT_RETRY_CONFIG.retryableErrors): boolean {\n if (!error) return false;\n\n // Use enhanced error classification for LIT Protocol specific errors\n const classification = classifyError(error);\n\n // If classification determined retryability, use that\n if (classification.isRetryable !== undefined) {\n debugInfo('ERROR_CLASSIFICATION', `Error classified as: ${classification.category} (retryable: ${classification.isRetryable})`);\n return classification.isRetryable;\n }\n\n // Fallback to legacy pattern matching\n const errorMessage = error.message || error.toString() || '';\n const errorLower = errorMessage.toLowerCase();\n\n return retryableErrors.some(pattern =>\n errorLower.includes(pattern.toLowerCase())\n );\n}\n\n/**\n * Calculate exponential backoff delay with jitter\n */\nexport function calculateDelay(attempt: number, config: RetryConfig): number {\n const exponentialDelay = Math.min(\n config.initialDelayMs * Math.pow(config.backoffMultiplier, attempt - 1),\n config.maxDelayMs\n );\n\n // Add jitter (\u00B125%) to avoid thundering herd\n const jitter = exponentialDelay * 0.25 * (Math.random() - 0.5);\n return Math.max(100, exponentialDelay + jitter);\n}\n\n/**\n * Enhanced retry wrapper with intelligent error classification\n */\nexport async function withRetry<T>(\n operation: () => Promise<T>,\n config: Partial<RetryConfig> = {},\n operationName: string = 'operation'\n): Promise<T> {\n let finalConfig = { ...DEFAULT_RETRY_CONFIG, ...config };\n const tracker = new PerformanceTracker(`Retry ${operationName}`);\n let lastError: any;\n let errorClassification: any = null;\n\n for (let attempt = 1; attempt <= finalConfig.maxAttempts; attempt++) {\n try {\n debugInfo('RETRY', `\uD83D\uDD04 [${operationName}] Attempt ${attempt}/${finalConfig.maxAttempts}`);\n const startTime = Date.now();\n const result = await operation();\n const duration = Date.now() - startTime;\n\n debugInfo('RETRY', `\u2705 [${operationName}] Success after ${duration}ms (attempt ${attempt})`);\n networkMetrics.recordRequest(operationName, true, duration);\n tracker.end(true);\n return result;\n } catch (error) {\n lastError = error;\n const errorMessage = (error as any)?.message || (error as any)?.toString() || 'Unknown error';\n\n // Classify error and potentially adjust retry strategy\n errorClassification = classifyError(error);\n\n // Update config with intelligent retry settings if this is the first error\n if (attempt === 1 && errorClassification) {\n const intelligentConfig = getRetryConfigFromClassification(errorClassification);\n finalConfig = {\n ...finalConfig,\n ...intelligentConfig,\n maxAttempts: Math.min(finalConfig.maxAttempts, intelligentConfig.maxAttempts)\n };\n\n debugInfo('RETRY', `\uD83E\uDDE0 Intelligent retry strategy applied: ${errorClassification.category} (${errorClassification.retryStrategy})`);\n debugInfo('RETRY', `\uD83D\uDCCA Adjusted config: max=${finalConfig.maxAttempts}, delay=${finalConfig.initialDelayMs}ms`);\n }\n\n debugWarn('RETRY', `\u26A0\uFE0F [${operationName}] Attempt ${attempt} failed:`, {\n error: errorMessage,\n attempt,\n category: errorClassification.category,\n retryable: errorClassification.isRetryable\n });\n networkMetrics.recordRequest(operationName, false, 0, errorMessage);\n\n // Check if we've exceeded the (possibly adjusted) max attempts\n if (attempt >= finalConfig.maxAttempts) {\n debugError('RETRY', `\u274C [${operationName}] All attempts failed. Last error:`, { error: errorMessage });\n\n // Generate detailed error report\n if (errorClassification) {\n const errorReport = createErrorReport(error);\n debugError('RETRY', `\uD83D\uDCCB Error Analysis Report:\\n${errorReport}`);\n }\n\n tracker.end(false);\n break;\n }\n\n if (!errorClassification.isRetryable) {\n debugError('RETRY', `\uD83D\uDEAB [${operationName}] Non-retryable error (${errorClassification.category}):`, { error: errorMessage });\n\n // Show troubleshooting tips for non-retryable errors\n if (errorClassification.troubleshooting) {\n debugInfo('RETRY', `\uD83D\uDCA1 Troubleshooting suggestions:\\n ${errorClassification.troubleshooting.join('\\n ')}`);\n }\n\n tracker.end(false);\n break;\n }\n\n const delayMs = calculateDelay(attempt, finalConfig);\n debugInfo('RETRY', `\u23F3 [${operationName}] Waiting ${delayMs}ms before retry... (${errorClassification.retryStrategy} strategy)`);\n await sleep(delayMs);\n }\n }\n\n throw lastError;\n}\n\n/**\n * Enhanced LIT Node Client connector with retry logic and readiness validation\n */\nexport async function connectLitNodeClient(\n litNodeClient: any,\n config: Partial<RetryConfig> = {}\n): Promise<void> {\n const network = litNodeClient?.config?.litNetwork || 'unknown';\n\n return withRetry(\n async () => {\n if (!litNodeClient) {\n throw new Error('LIT Node Client is null or undefined');\n }\n\n const startTime = Date.now();\n logConnectionAttempt(network, 1, config.maxAttempts || DEFAULT_RETRY_CONFIG.maxAttempts);\n\n // First connect to the network\n await litNodeClient.connect();\n\n // Wait for client to be ready\n debugInfo('CONNECTION', `\u23F3 Waiting for LIT Node Client to be ready...`);\n const readyTimeout = 30000; // 30 seconds timeout for readiness\n const readyStartTime = Date.now();\n\n while (!litNodeClient.ready && (Date.now() - readyStartTime) < readyTimeout) {\n await sleep(500); // Check every 500ms\n }\n\n if (!litNodeClient.ready) {\n throw new Error(`LIT Node Client failed to become ready within ${readyTimeout}ms`);\n }\n\n const latency = Date.now() - startTime;\n debugInfo('CONNECTION', `\u2705 LIT Node Client is ready (${litNodeClient.ready})`);\n logConnectionSuccess(network, latency);\n },\n config,\n 'LIT Node Client Connection'\n );\n}\n\n/**\n * Enhanced LIT Contracts connector with retry logic\n */\nexport async function connectLitContracts(\n litContracts: any,\n config: Partial<RetryConfig> = {}\n): Promise<void> {\n return withRetry(\n async () => {\n if (!litContracts) {\n throw new Error('LIT Contracts is null or undefined');\n }\n\n console.log(`\uD83D\uDD17 Connecting to LIT Contracts: ${litContracts.network || 'unknown'}`);\n await litContracts.connect();\n console.log('\u2705 LIT Contracts connected successfully');\n },\n config,\n 'LIT Contracts Connection'\n );\n}\n\n/**\n * Validate LIT Node Client connection health\n */\nexport async function validateLitNodeConnection(litNodeClient: any): Promise<ConnectionValidationResult> {\n try {\n const startTime = Date.now();\n\n if (!litNodeClient) {\n return { isValid: false, error: 'LIT Node Client is null or undefined' };\n }\n\n // Try to get the latest block hash as a health check\n await litNodeClient.getLatestBlockhash();\n\n const latencyMs = Date.now() - startTime;\n return { isValid: true, latencyMs };\n } catch (error) {\n return {\n isValid: false,\n error: (error as any)?.message || (error as any)?.toString() || 'Unknown validation error'\n };\n }\n}\n\n/**\n * Enhanced session signature generator with retry logic and caching\n */\nexport async function generateSessionSignatures(\n litNodeClient: any,\n sessionConfig: any,\n config: Partial<RetryConfig> = {},\n pkpTokenId?: string,\n litActionCid?: string,\n signerAddress?: string,\n network: string = 'chipotle'\n): Promise<any> {\n // If caching parameters are provided, try cache first\n if (pkpTokenId && litActionCid && signerAddress) {\n const { sessionSignatureCache } = await import('./session-signature-cache');\n\n const cached = sessionSignatureCache.get(pkpTokenId, litActionCid, signerAddress, network);\n if (cached) {\n const sigCount = Object.keys(cached).length;\n debugInfo('SESSION', `\uD83D\uDD04 Using cached session signatures (${sigCount} sigs)`);\n return cached;\n }\n }\n\n return withRetry(\n async () => {\n debugInfo('SESSION', '\uD83D\uDD10 Generating new session signatures...');\n const sessionSigs = await litNodeClient.getSessionSigs(sessionConfig);\n const sigCount = Object.keys(sessionSigs).length;\n\n // Cache if parameters provided\n if (pkpTokenId && litActionCid && signerAddress) {\n const { sessionSignatureCache } = await import('./session-signature-cache');\n const expiration = new Date(sessionConfig.expiration);\n sessionSignatureCache.set(pkpTokenId, litActionCid, signerAddress, network, sessionSigs, expiration);\n }\n\n debugInfo('SESSION', `\u2705 Generated ${sigCount} session signatures`);\n return sessionSigs;\n },\n config,\n 'Session Signature Generation'\n );\n}\n\n/**\n * Validate LIT Node Client readiness before operations\n */\nexport async function validateLitNodeReadiness(litNodeClient: any): Promise<void> {\n if (!litNodeClient) {\n throw new Error('LIT Node Client is null or undefined');\n }\n\n // Check if client is connected\n if (!litNodeClient.ready) {\n debugWarn('CONNECTION', '\u26A0\uFE0F LIT Node Client not ready, attempting to reconnect...');\n await litNodeClient.connect();\n\n // Wait for readiness with timeout\n const readyTimeout = 15000; // 15 seconds\n const startTime = Date.now();\n\n while (!litNodeClient.ready && (Date.now() - startTime) < readyTimeout) {\n await sleep(500);\n }\n\n if (!litNodeClient.ready) {\n throw new Error('LIT Node Client is not ready for operations');\n }\n }\n\n debugInfo('CONNECTION', '\u2705 LIT Node Client readiness validated');\n}\n\n/**\n * Enhanced LIT Action executor with retry logic and readiness validation\n */\nexport async function executeLitAction(\n litNodeClient: any,\n executionConfig: any,\n config: Partial<RetryConfig> = {}\n): Promise<any> {\n const cid = executionConfig.ipfsId;\n\n return withRetry(\n async () => {\n const startTime = Date.now();\n\n // Validate client readiness before execution\n await validateLitNodeReadiness(litNodeClient);\n\n logLitActionExecution(cid, executionConfig.jsParams);\n logRequest('LIT_ACTION', 'executeJs', executionConfig);\n\n const result = await litNodeClient.executeJs(executionConfig);\n const duration = Date.now() - startTime;\n\n if (!result.response) {\n logError('LIT_ACTION', 'executeJs', new Error('No response from LIT Action'), duration);\n throw new Error('No response from LIT Action');\n }\n\n logResponse('LIT_ACTION', 'executeJs', result, duration);\n logLitActionResult(cid, true, duration, result);\n return result;\n },\n config,\n 'LIT Action Execution'\n );\n}\n\n/**\n * PKP operation wrapper with enhanced error handling\n */\nexport async function executePkpOperation<T>(\n operation: () => Promise<T>,\n operationName: string,\n config: Partial<RetryConfig> = {}\n): Promise<T> {\n const pkpConfig = {\n ...DEFAULT_RETRY_CONFIG,\n ...config,\n retryableErrors: [\n ...DEFAULT_RETRY_CONFIG.retryableErrors,\n 'pkp validation',\n 'signing shares',\n 'resource validation',\n 'ipfs propagation'\n ]\n };\n\n return withRetry(operation, pkpConfig, `PKP ${operationName}`);\n}\n\n/**\n * Network-specific timeout configurations\n */\nexport const NETWORK_TIMEOUTS = {\n chipotle: {\n connection: 60000,\n operation: 120000,\n pkpValidation: 180000,\n },\n} as const;\n\nexport function getNetworkTimeouts(network: string) {\n return NETWORK_TIMEOUTS[network as keyof typeof NETWORK_TIMEOUTS] || NETWORK_TIMEOUTS['chipotle'];\n}", "/**\n * Enhanced Error Classification for LIT Protocol Operations\n * Provides detailed error categorization and specific retry strategies\n */\n\n/**\n * Error categories for different types of failures\n */\nexport enum ErrorCategory {\n NETWORK = 'network',\n PROTOCOL = 'protocol',\n AUTHENTICATION = 'authentication',\n RESOURCE = 'resource',\n VALIDATION = 'validation',\n TIMEOUT = 'timeout',\n RATE_LIMIT = 'rate_limit',\n CONFIGURATION = 'configuration',\n UNKNOWN = 'unknown'\n}\n\n/**\n * Retry strategy types\n */\nexport enum RetryStrategy {\n AGGRESSIVE = 'aggressive', // Fast retries for transient issues\n CONSERVATIVE = 'conservative', // Slower retries for resource issues\n EXPONENTIAL = 'exponential', // Standard exponential backoff\n LINEAR = 'linear', // Linear delay increase\n NONE = 'none' // No retries\n}\n\n/**\n * Error classification result\n */\nexport interface ErrorClassification {\n category: ErrorCategory;\n retryStrategy: RetryStrategy;\n isRetryable: boolean;\n maxAttempts: number;\n baseDelayMs: number;\n maxDelayMs: number;\n description: string;\n troubleshooting?: string[];\n}\n\n/**\n * LIT Protocol specific error patterns\n */\nconst LIT_ERROR_PATTERNS = {\n // Network and connection errors\n network: [\n /network error/i,\n /connection failed/i,\n /connection refused/i,\n /connection timeout/i,\n /socket hang up/i,\n /enotfound/i,\n /econnrefused/i,\n /etimedout/i,\n /dns resolution failed/i,\n /request failed/i\n ],\n\n // Protocol specific errors\n protocol: [\n /lit protocol/i,\n /lit node/i,\n /signing shares/i,\n /node communication/i,\n /consensus/i,\n /threshold/i,\n /decryption/i,\n /signature verification/i,\n /There was an error getting the signing shares/i,\n /Response from the nodes/i,\n /NodeError/i,\n /PKP validation/i,\n /pkp validation failed/i\n ],\n\n // Authentication and authorization errors\n authentication: [\n /authentication/i,\n /authorization/i,\n /session.*expired/i,\n /invalid.*signature/i,\n /unauthorized/i,\n /access.*denied/i,\n /permission/i,\n /auth.*failed/i,\n /siwe/i,\n /session.*sig/i\n ],\n\n // Resource and validation errors\n resource: [\n /resource.*not.*found/i,\n /ipfs.*not.*found/i,\n /cid.*invalid/i,\n /pkp.*not.*found/i,\n /pkp.*validation/i,\n /resource.*validation/i,\n /action.*not.*permitted/i,\n /lit.*action.*not.*found/i\n ],\n\n // Validation errors\n validation: [\n /validation.*failed/i,\n /invalid.*input/i,\n /invalid.*parameter/i,\n /malformed/i,\n /schema.*validation/i,\n /type.*error/i,\n /missing.*required/i\n ],\n\n // Timeout specific errors\n timeout: [\n /timeout/i,\n /request.*timed.*out/i,\n /operation.*timed.*out/i,\n /deadline.*exceeded/i,\n /time.*limit.*exceeded/i\n ],\n\n // Rate limiting errors\n rateLimit: [\n /rate.*limit/i,\n /too.*many.*requests/i,\n /quota.*exceeded/i,\n /throttled/i,\n /429/,\n /rate.*exceeded/i\n ],\n\n // Configuration errors\n configuration: [\n /configuration/i,\n /config.*error/i,\n /environment/i,\n /missing.*env/i,\n /invalid.*config/i,\n /setup.*error/i\n ]\n};\n\n/**\n * Predefined retry strategies\n */\nconst RETRY_STRATEGIES = {\n [RetryStrategy.AGGRESSIVE]: {\n maxAttempts: 5,\n baseDelayMs: 500,\n maxDelayMs: 5000,\n multiplier: 1.5\n },\n [RetryStrategy.CONSERVATIVE]: {\n maxAttempts: 3,\n baseDelayMs: 3000,\n maxDelayMs: 30000,\n multiplier: 2.5\n },\n [RetryStrategy.EXPONENTIAL]: {\n maxAttempts: 4,\n baseDelayMs: 1000,\n maxDelayMs: 15000,\n multiplier: 2.0\n },\n [RetryStrategy.LINEAR]: {\n maxAttempts: 3,\n baseDelayMs: 2000,\n maxDelayMs: 10000,\n multiplier: 1.0\n },\n [RetryStrategy.NONE]: {\n maxAttempts: 1,\n baseDelayMs: 0,\n maxDelayMs: 0,\n multiplier: 1.0\n }\n};\n\n/**\n * Error classification rules\n */\nconst CLASSIFICATION_RULES: Record<ErrorCategory, ErrorClassification> = {\n [ErrorCategory.NETWORK]: {\n category: ErrorCategory.NETWORK,\n retryStrategy: RetryStrategy.AGGRESSIVE,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.AGGRESSIVE],\n description: 'Network connectivity or communication error',\n troubleshooting: [\n 'Check internet connection',\n 'Verify LIT Protocol network status',\n 'Check firewall and proxy settings',\n 'Try connecting to different node endpoints'\n ]\n },\n\n [ErrorCategory.PROTOCOL]: {\n category: ErrorCategory.PROTOCOL,\n retryStrategy: RetryStrategy.CONSERVATIVE,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.CONSERVATIVE],\n description: 'LIT Protocol specific operational error',\n troubleshooting: [\n 'Check LIT Protocol network status',\n 'Verify PKP configuration',\n 'Check signing shares availability',\n 'Wait for network consensus'\n ]\n },\n\n [ErrorCategory.AUTHENTICATION]: {\n category: ErrorCategory.AUTHENTICATION,\n retryStrategy: RetryStrategy.EXPONENTIAL,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.EXPONENTIAL],\n maxAttempts: 2, // Override: limited retries for auth issues\n description: 'Authentication or authorization error',\n troubleshooting: [\n 'Check session signatures validity',\n 'Regenerate authentication tokens',\n 'Verify wallet permissions',\n 'Check PKP authorization status'\n ]\n },\n\n [ErrorCategory.RESOURCE]: {\n category: ErrorCategory.RESOURCE,\n retryStrategy: RetryStrategy.LINEAR,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.LINEAR],\n maxAttempts: 2, // Override: limited retries for resource issues\n description: 'Resource not found or validation error',\n troubleshooting: [\n 'Verify resource CIDs are correct',\n 'Check IPFS availability',\n 'Confirm PKP exists and is accessible',\n 'Wait for resource propagation'\n ]\n },\n\n [ErrorCategory.VALIDATION]: {\n category: ErrorCategory.VALIDATION,\n retryStrategy: RetryStrategy.NONE,\n isRetryable: false,\n ...RETRY_STRATEGIES[RetryStrategy.NONE],\n description: 'Input validation or schema error',\n troubleshooting: [\n 'Check input parameters format',\n 'Verify required fields are provided',\n 'Validate data types and ranges',\n 'Review API documentation'\n ]\n },\n\n [ErrorCategory.TIMEOUT]: {\n category: ErrorCategory.TIMEOUT,\n retryStrategy: RetryStrategy.CONSERVATIVE,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.CONSERVATIVE],\n description: 'Operation timeout error',\n troubleshooting: [\n 'Increase timeout values',\n 'Check network latency',\n 'Verify system resources',\n 'Split operations into smaller chunks'\n ]\n },\n\n [ErrorCategory.RATE_LIMIT]: {\n category: ErrorCategory.RATE_LIMIT,\n retryStrategy: RetryStrategy.CONSERVATIVE,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.CONSERVATIVE],\n maxAttempts: 2, // Override: limited retries to avoid further rate limiting\n baseDelayMs: 5000, // Override: longer delays for rate limits\n description: 'Rate limit or quota exceeded',\n troubleshooting: [\n 'Reduce request frequency',\n 'Implement request batching',\n 'Check rate limit headers',\n 'Wait for quota reset'\n ]\n },\n\n [ErrorCategory.CONFIGURATION]: {\n category: ErrorCategory.CONFIGURATION,\n retryStrategy: RetryStrategy.NONE,\n isRetryable: false,\n ...RETRY_STRATEGIES[RetryStrategy.NONE],\n description: 'Configuration or setup error',\n troubleshooting: [\n 'Check environment variables',\n 'Verify configuration files',\n 'Review setup documentation',\n 'Check required dependencies'\n ]\n },\n\n [ErrorCategory.UNKNOWN]: {\n category: ErrorCategory.UNKNOWN,\n retryStrategy: RetryStrategy.EXPONENTIAL,\n isRetryable: true,\n ...RETRY_STRATEGIES[RetryStrategy.EXPONENTIAL],\n maxAttempts: 2, // Override: conservative retries for unknown errors\n description: 'Unknown or unclassified error',\n troubleshooting: [\n 'Check logs for more details',\n 'Verify system status',\n 'Try again with debug logging',\n 'Contact support if persists'\n ]\n }\n};\n\n/**\n * Classify an error and determine retry strategy\n */\nexport function classifyError(error: any): ErrorClassification {\n const errorMessage = error?.message || error?.toString() || '';\n const errorLower = errorMessage.toLowerCase();\n\n // Check each error category\n for (const [category, patterns] of Object.entries(LIT_ERROR_PATTERNS)) {\n for (const pattern of patterns) {\n if (pattern.test(errorMessage) || pattern.test(errorLower)) {\n const classification = CLASSIFICATION_RULES[category as ErrorCategory];\n return {\n ...classification,\n description: `${classification.description}: ${errorMessage.slice(0, 100)}`\n };\n }\n }\n }\n\n // Default to unknown category\n const unknownClassification = CLASSIFICATION_RULES[ErrorCategory.UNKNOWN];\n return {\n ...unknownClassification,\n description: `${unknownClassification.description}: ${errorMessage.slice(0, 100)}`\n };\n}\n\n/**\n * Get retry configuration from error classification\n */\nexport function getRetryConfigFromClassification(classification: ErrorClassification) {\n return {\n maxAttempts: classification.maxAttempts,\n initialDelayMs: classification.baseDelayMs,\n maxDelayMs: classification.maxDelayMs,\n backoffMultiplier: RETRY_STRATEGIES[classification.retryStrategy].multiplier,\n retryableErrors: ['*'] // Classification already determined retryability\n };\n}\n\n/**\n * Enhanced error analyzer for detailed error information\n */\nexport function analyzeError(error: any) {\n const classification = classifyError(error);\n\n return {\n ...classification,\n originalError: error,\n errorMessage: error?.message || error?.toString() || 'Unknown error',\n errorStack: error?.stack,\n timestamp: new Date().toISOString(),\n retryConfig: getRetryConfigFromClassification(classification)\n };\n}\n\n/**\n * Create a human-readable error report\n */\nexport function createErrorReport(error: any) {\n const analysis = analyzeError(error);\n\n const report = [\n `\uD83D\uDD0D Error Analysis Report`,\n `=====================================`,\n `Category: ${analysis.category.toUpperCase()}`,\n `Retryable: ${analysis.isRetryable ? '\u2705 Yes' : '\u274C No'}`,\n `Strategy: ${analysis.retryStrategy}`,\n `Max Attempts: ${analysis.maxAttempts}`,\n `Description: ${analysis.description}`,\n `Timestamp: ${analysis.timestamp}`,\n ``,\n `Original Error: ${analysis.errorMessage}`,\n ``\n ];\n\n if (analysis.troubleshooting && analysis.troubleshooting.length > 0) {\n report.push(`\uD83D\uDEE0\uFE0F Troubleshooting Steps:`);\n analysis.troubleshooting.forEach((step, index) => {\n report.push(` ${index + 1}. ${step}`);\n });\n report.push('');\n }\n\n return report.join('\\n');\n}\n\n/**\n * LIT Protocol specific error matchers\n */\nexport const litProtocolErrors = {\n isNetworkError: (error: any) => classifyError(error).category === ErrorCategory.NETWORK,\n isProtocolError: (error: any) => classifyError(error).category === ErrorCategory.PROTOCOL,\n isAuthenticationError: (error: any) => classifyError(error).category === ErrorCategory.AUTHENTICATION,\n isResourceError: (error: any) => classifyError(error).category === ErrorCategory.RESOURCE,\n isTimeoutError: (error: any) => classifyError(error).category === ErrorCategory.TIMEOUT,\n isRateLimitError: (error: any) => classifyError(error).category === ErrorCategory.RATE_LIMIT,\n isConfigurationError: (error: any) => classifyError(error).category === ErrorCategory.CONFIGURATION,\n isRetryable: (error: any) => classifyError(error).isRetryable\n};", "/**\n * Diamond Hands LIT Actions Utilities\n * All utility functions for working with deployed LIT Actions\n */\n\nexport * from \"./chunks/lit-action-helpers\";\nexport * from \"./chunks/pkp-setup\";\nexport * from \"./chunks/cid-utils\";\nexport * from \"./chunks/connection-helpers\";\nexport * from \"./chunks/debug-logger\";\nexport * from \"./chunks/error-classification\";\nexport * from \"./chunks/session-signature-cache\";\n"],
5
5
  "mappings": "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",
6
6
  "names": ["LogLevel", "ALPHABET", "esm_default", "esm_default", "ErrorCategory", "RetryStrategy", "sessionSignatureCache"]
7
7
  }