@oracle-agent/oracle 0.35.20 → 0.35.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/skills/oracle-desk-product/SKILL.md +23 -17
- package/dist/assets/skills/oracle-mcp-install/SKILL.md +17 -22
- package/dist/assets/skills/protocol-api-key-integration/SKILL.md +14 -11
- package/dist/assets/skills/self-custodial-onchain-execution/SKILL.md +14 -13
- package/dist/assets/skills/trade-loop-circuit-breaker/SKILL.md +1 -1
- package/dist/bin/desk-server.mjs +30 -30
- package/dist/bin/oracle-data-mcp.mjs +17 -17
- package/dist/bin/oracle-public-server.mjs +5 -5
- package/dist/cli/commands/chat.mjs +200 -200
- package/dist/cli/commands/doctor.mjs +7 -7
- package/dist/cli/commands/eval.mjs +113 -113
- package/dist/cli/commands/extension-policy.mjs +1 -1
- package/dist/cli/commands/governance-prepare.mjs +5 -0
- package/dist/cli/commands/model.mjs +204 -204
- package/dist/cli/commands/portfolio-risk.mjs +4 -0
- package/dist/cli/commands/position-health.mjs +4 -0
- package/dist/cli/commands/safety-intelligence.mjs +4 -0
- package/dist/cli/commands/swap.mjs +13 -13
- package/dist/cli/commands/tax-lots.mjs +4 -0
- package/dist/data/desk-data.mjs +26 -26
- package/dist/index.mjs +40 -40
- package/package.json +1 -1
- package/public/eval-report.json +2 -2
- package/public/oracle-splash/index.html +1 -1
- package/server.json +2 -2
- package/dist/assets/skills/oracle-best-execution.md +0 -27
- package/dist/assets/skills/oracle-desk.md +0 -27
- package/dist/assets/skills/oracle-receipts.md +0 -29
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
var z=Object.freeze({assetHighPct:50,assetMediumPct:25,chainHighPct:75,venueHighPct:60,stablecoinHighPct:70}),R=new Set(["USDC","USDT","USDT0","DAI","FRAX","LUSD","TUSD","USDP","GUSD","PYUSD","USDE"]);function x(n){if(n===null||n===""||n===void 0)return null;let e=Number(n);return Number.isFinite(e)&&e>=0?e:null}function v(n){return Math.round((n+Number.EPSILON)*1e8)/1e8}function $(n,e){return e>0?v(n/e*100):null}function E(n){return n.address||n.owner||n.walletAddress||n.wallet?.address||null}function q(n){let e=Array.isArray(n)?n:Array.isArray(n?.entries)?n.entries:[],i=new Map;for(let t of e){if(!t?.address)continue;let r=String(t.address).toLowerCase();i.has(r)||i.set(r,t)}return i}function m(n,e,i={}){if(!e||typeof e!="object")return;let t=String(e.symbol??e.coin??e.name??e.collection??e.tokenId??"unknown"),r=x(e.usdValue??e.valueUsd??e.knownUsd??e.estimatedValueUsd??e.floorValueUsd),s=e.kind==="nft"||e.type==="nft"||e.collection||e.tokenId!=null?"nft":"fungible";n.push({symbol:t,usdValue:r,chain:String(e.chain??e.chainName??i.chain??"unknown"),venue:String(e.venue??e.protocol??e.platform??i.venue??"wallet"),address:e.address??i.address??null,kind:s,stablecoin:e.stablecoin===!0||R.has(t.toUpperCase())})}function B(n){let e=[],i=E(n);for(let t of n.assets||n.holdings||[])m(e,t,{address:i,chain:n.chain,venue:n.venue});for(let t of n.chains||[]){let r=t.chain??t.name??t.slug??(t.chainId!=null?String(t.chainId):t.family)??"unknown",s={address:t.address??i,chain:r,venue:t.venue};t.native&&(t.native.amount==null||Number(t.native.amount)!==0)&&m(e,{...t.native,symbol:t.native.symbol??t.symbol??r},s);for(let a of t.assets||t.fungibleTokens?.assets||[])m(e,a,s);for(let a of t.collectibles?.assets||t.nfts||[])m(e,{...a,kind:"nft"},s);for(let a of t.spot?.balances||[])m(e,a,{...s,venue:"Hyperliquid spot"});let l=x(t.perps?.accountValueUsd);l!=null&&m(e,{symbol:"perps account",usdValue:l},{...s,venue:"Hyperliquid perps"})}for(let t of n.inventory?.items||n.nfts?.items||[])m(e,{...t,kind:"nft"},{address:i,chain:t.chain??n.chain,venue:t.marketplace??n.venue});return e}function _(n,e){let i=E(n),t=n.chain??n.chainId??n.family??"*";return i?`${String(i).toLowerCase()}|${String(t).toLowerCase()}`:`snapshot:${e}`}function O(n,e,i){let t=new Map;for(let r of n){if(r.usdValue==null)continue;let s=r[e];t.set(s,(t.get(s)||0)+r.usdValue)}return[...t].map(([r,s])=>({name:r,knownUsd:v(s),percentOfKnown:$(s,i)})).sort((r,s)=>s.knownUsd-r.knownUsd||r.name.localeCompare(s.name))}function T(n={},e={}){let i=Array.isArray(n)?n:Array.isArray(n.snapshots)?n.snapshots:n.snapshot?[n.snapshot]:[],t=q(e.labels??e.addressBook??n.labels??n.addressBook),r={...z,...n.thresholds||{},...e.thresholds||{}},s=[],l=new Set,a=0;i.forEach((o,c)=>{if(!o||typeof o!="object")return;let I=_(o,c);l.has(I)?a+=1:(l.add(I),s.push(o))});let h=s.flatMap(B),u=h.filter(o=>o.usdValue!=null),j=h.filter(o=>o.usdValue==null),F=s.reduce((o,c)=>o+Number(c.valuation?.unpricedNonzeroItems||c.unpricedNonzeroItems||0),0),f=v(u.reduce((o,c)=>o+c.usdValue,0)),g=j.length+F,y=O(u,"chain",f),w=O(u,"venue",f),k=O(u,"symbol",f);for(let o of y)o.chain=o.name;for(let o of w)o.venue=o.name;for(let o of k)o.asset=o.name,o.symbol=o.name;let S=v(u.filter(o=>o.stablecoin).reduce((o,c)=>o+c.usdValue,0)),b=h.filter(o=>o.kind==="nft"),P=s.reduce((o,c)=>o+Number(c.valuation?.nftUnvaluedItems||0),0),A=b.filter(o=>o.usdValue==null).length+P,J=b.filter(o=>o.usdValue!=null).length,d=k[0]||null,U=d?d.percentOfKnown>=r.assetHighPct?"high":d.percentOfKnown>=r.assetMediumPct?"medium":"low":"unknown",p=[];g&&p.push(`${g} nonzero holding(s) have unknown USD value; they are excluded from totals and percentages.`),A&&p.push("NFT valuation coverage is partial; estimates are not executable bids and unvalued NFTs are not treated as zero."),a&&p.push(`${a} duplicate address/chain snapshot(s) were ignored.`),d&&U!=="low"&&p.push(`Asset concentration is ${U}: ${d.name} is ${d.percentOfKnown}% of known value.`),y[0]?.percentOfKnown>=r.chainHighPct&&p.push(`Chain concentration is high: ${y[0].name} is ${y[0].percentOfKnown}% of known value.`),w[0]?.percentOfKnown>=r.venueHighPct&&p.push(`Venue concentration is high: ${w[0].name} is ${w[0].percentOfKnown}% of known value.`);let M=s.map(E).filter(Boolean).map(o=>{let c=t.get(String(o).toLowerCase());return{address:o,label:c?.label??null,who:c?.who??null,role:c?.role??null}});return{totalKnownUsd:f,coverage:{complete:s.length>0&&g===0&&s.every(o=>o.valuation?.complete!==!1&&o.coverage?.complete!==!1),label:g===0&&s.length&&s.every(o=>o.valuation?.complete!==!1&&o.coverage?.complete!==!1)?"complete for the supplied snapshots":"known priced value only; portfolio coverage is partial or unverified",unknownUsd:g?null:0,pricedItemCount:u.length,unknownItemCount:g,snapshotCount:s.length,duplicatesIgnored:a},chainExposures:y,venueExposures:w,topAssets:k.slice(0,Math.max(1,Number(e.topAssets??n.topAssets??10))),concentrationRisk:{level:U,topAsset:d?.name??null,topAssetPercent:d?.percentOfKnown??null,thresholds:{mediumPct:r.assetMediumPct,highPct:r.assetHighPct}},stablecoinExposure:{knownUsd:S,percentOfKnown:$(S,f),high:f>0&&$(S,f)>=r.stablecoinHighPct},nftCoverage:{status:b.length||P?A?"partial":"valued":"not-observed",valuedItems:J,unvaluedItems:A,knownUsd:v(b.filter(o=>o.usdValue!=null).reduce((o,c)=>o+c.usdValue,0))},addresses:M,warnings:[...new Set(p)]}}import V from"node:fs";var C=1024*1024;function K(n=[],e={}){let i=[],t={};for(let r=0;r<n.length;r+=1){let s=n[r];if(!s.startsWith("--")){i.push(s);continue}let l=s.indexOf("="),a=s.slice(2,l===-1?void 0:l),h=e[a];if(!h)throw new TypeError(`unknown option --${a}`);if(Object.hasOwn(t,a))throw new TypeError(`duplicate option --${a}`);if(h==="boolean"){if(l!==-1)throw new TypeError(`option --${a} does not take a value`);t[a]=!0;continue}let u=l===-1?n[++r]:s.slice(l+1);if(u==null||u===""||u.startsWith("--"))throw new TypeError(`option --${a} requires a value`);t[a]=u}return{positionals:i,options:t}}function D(n,e="input"){if(!n)throw new TypeError(`${e} JSON path or - is required`);let i=n==="-"?V.readFileSync(0):V.readFileSync(n);if(i.length>C)throw new RangeError(`${e} exceeds ${C} bytes`);let t;try{t=JSON.parse(i.toString("utf8"))}catch(r){throw new TypeError(`${e} must be valid JSON: ${r.message}`)}if(!t||typeof t!="object"||Array.isArray(t)||Object.getPrototypeOf(t)!==Object.prototype)throw new TypeError(`${e} must be a JSON object`);return t}function H(n,e=process.stdout){e.write(`${JSON.stringify(n,null,2)}
|
|
2
|
+
`)}function L(n,e=process.stderr){return e.write(`oracle: ${n instanceof Error?n.message:String(n)}
|
|
3
|
+
`),2}var N="oracle portfolio-risk <input.json|->",Z={name:"portfolio-risk",summary:"summarize supplied portfolio concentration and coverage",group:"read",usage:N,async run(n){let e=n.argv??[];if(e.length===0||e.includes("--help")||e.includes("-h"))return process.stdout.write(`${N}
|
|
4
|
+
`),0;try{let{positionals:i}=K(e);if(i.length!==1)throw new TypeError(N);return H(T(D(i[0]))),0}catch(i){return L(i)}}};export{Z as default};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{wordlists as se}from"ethers";var ie=new Set(["privatekey","privkey","secretkey","seedphrase","seed","mnemonic","passphrase","password","keystore","keymaterial","wif","xprv","xpriv","bearer","authorization","signature","apikey","credential"]),ae=[/\b[5KL][1-9A-HJ-NP-Za-km-z]{50,51}\b/,/\bxprv[0-9A-Za-z]{50,}\b/],ce=new Set([12,15,18,21,24]);function le(t){let r=String(t).trim().toLowerCase().split(/\s+/).filter(Boolean);return ce.has(r.length)&&r.every(e=>se.en.getWordIndex(e)>=0)}var de=/^\s*(?:0x)?[0-9a-fA-F]{64}\s*$/,ue=/(hash|digest|root|salt|nonce|proof|commitment|sig|id)(?:e?s)?$/i,fe=new Set(["calldata","data","publickey","pubkey","message","payload","input","extradata"]);function pe(t){let r=C(t);return fe.has(r)||ue.test(r)}var B=class extends Error{constructor(r){super(`action receipt refused: secret-bearing field at ${r}`),this.name="ActionReceiptSecretError",this.code="ACTION_RECEIPT_SECRET"}};function C(t){return String(t).replace(/[^a-z0-9]/gi,"").toLowerCase()}function me(t){let r=C(t);return[...ie].some(e=>r.includes(e))}function he(t,r,e){if(typeof r=="string"){if(ae.some(o=>o.test(r))||le(r))throw new B(e);if(de.test(r)&&!pe(t))throw new B(e)}}function H(t,r="$",e=""){if(t==null||typeof t=="boolean")return t;if(typeof t=="string")return he(e,t,r),t;if(typeof t=="number"){if(!Number.isFinite(t))throw new TypeError(`action receipt: non-finite number at ${r}`);return t}if(typeof t=="bigint")return t.toString();if(Array.isArray(t))return t.map((n,i)=>H(n,`${r}[${i}]`,e));if(typeof t!="object"||Object.getPrototypeOf(t)!==Object.prototype)throw new TypeError(`action receipt: JSON-like value required at ${r}`);let o={};for(let n of Object.keys(t).sort()){let i=`${r}.${n}`;if(me(n))throw new B(i);t[n]!==void 0&&(o[n]=H(t[n],i,n))}return o}function g(t){return H(t)}var J=1,K="Alert findings only; not an execution signal and not a live oracle.";var ye=Object.freeze(["aave-v3","morpho","compound","solend","spark","farming","generic"]),v=Object.freeze({criticalHealthFactorWad:"1050000000000000000",warningHealthFactorWad:"1250000000000000000"}),be=new Set(ye),ge=Object.freeze({aave:"aave-v3",aavev3:"aave-v3","aave-v3":"aave-v3",morpho:"morpho",compound:"compound","compound-v2":"compound","compound-v3":"compound",solend:"solend",save:"solend",spark:"spark","spark-lend":"spark",farming:"farming",farm:"farming",yield:"farming",generic:"generic",lending:"generic"}),Ae=new Set(["complete","incomplete","unknown","stale"]),we=/[\u0000-\u001f\u007f]/,E=10n**18n,R=36,j=64,W=128,q=class extends Error{constructor(r,e="POSITION_HEALTH_INVALID"){super(`position health: ${r}`),this.name="PositionHealthValidationError",this.code=e}};function d(t,r){throw new q(t,r)}function I(t,r){return t<r?-1:t>r?1:0}function w(t){if(t&&typeof t=="object"&&!Object.isFrozen(t)){for(let r of Object.values(t))w(r);Object.freeze(t)}return t}function m(t,r){return(!t||typeof t!="object"||Array.isArray(t)||Object.getPrototypeOf(t)!==Object.prototype)&&d(`${r} must be a plain object`),t}function S(t,r,{optional:e=!1,lower:o=!1}={}){if(t==null&&e)return null;typeof t!="string"&&d(`${r} must be a string`);let n=t.trim();return n||d(`${r} is required`),we.test(n)&&d(`${r} contains control characters`),n.length>512&&d(`${r} is too long`),o?n.toLowerCase():n}function A(t,r,{optional:e=!1,positive:o=!1}={}){if(t==null&&e)return null;typeof t=="number"&&d(`${r} must be an exact decimal string or BigInt; Number coercion is refused`,"POSITION_HEALTH_UNSAFE_NUMBER");let n;typeof t=="bigint"?n=t.toString():typeof t=="string"?n=t.trim():d(`${r} must be an exact decimal string or BigInt`),/^\d+$/.test(n)||d(`${r} must be a non-negative base-10 integer string`);let i=BigInt(n);return o&&i===0n&&d(`${r} must be positive`),i.toString()}function Q(t,r){t==null&&d(`${r} is required`,"POSITION_HEALTH_MISSING_DECIMALS"),typeof t=="number"&&d(`${r} must be an exact decimal string or BigInt; Number coercion is refused`,"POSITION_HEALTH_UNSAFE_NUMBER");let e=A(t,r),o=BigInt(e);return o>BigInt(R)&&d(`${r} exceeds ${R}`),Number(o)}function _(t,r){return t==null?null:S(t,r)}function Te(t,r){return t==null&&d(`${r} is required`),typeof t=="bigint"?t.toString():typeof t=="number"?((!Number.isInteger(t)||!Number.isSafeInteger(t)||t<0)&&d(`${r} must be a safe non-negative integer, decimal string, or slug`),String(t)):S(String(t),r,{lower:!0})}function c(t,r){for(let e of r)if(t[e]!==void 0)return t[e]}function Se(t,r="protocol"){if(t==null)return"generic";let e=S(t,r,{lower:!0}),o=ge[e]||e;return be.has(o)||d(`${r} must be a supported lending or yield protocol`),o}function G(t){return t.protocol!=null?Se(t.protocol):t.marketId!=null||t.lltv!=null||t.loanAsset&&t.collateralAsset?"morpho":t.cToken!=null||t.underlying_symbol!=null||t.collateralFactor!=null?"compound":t.borrowedAmountWads!=null||t.lendingMarket!=null||t.mintDecimals!=null?"solend":t.recipe!=null||t.farmingMethod!=null||t.methodId!=null?"farming":t.spark!=null||t.savingsVault!=null?"spark":t.userReserves!=null||t.reserves!=null||t.liquidationThreshold!=null?"aave-v3":"generic"}function Ie(t,r="evidence"){if(t==null)return w({status:"unknown",references:[]});let e=m(t,r),o=S(e.status??"unknown",`${r}.status`,{lower:!0});Ae.has(o)||d(`${r}.status must be complete, incomplete, unknown, or stale`),e.references!=null&&!Array.isArray(e.references)&&d(`${r}.references must be an array`);let n=(e.references||[]).map((a,s)=>{let l=m(a,`${r}.references[${s}]`);return{kind:S(l.kind??l.type,`${r}.references[${s}].kind`,{lower:!0}),id:S(l.id??l.receiptId??l.txHash,`${r}.references[${s}].id`)}}).sort((a,s)=>I(a.kind,s.kind)||I(a.id,s.id)),i=[];for(let a of n)i.some(s=>s.kind===a.kind&&s.id===a.id)||i.push(a);return w({status:o,references:i})}function X(t,r){if(t==null)return null;if(typeof t=="number"&&d(`${r} must be an exact integer string or BigInt; Number coercion is refused`,"POSITION_HEALTH_UNSAFE_NUMBER"),typeof t=="object"){let n=m(t,r);if(n.bps!=null)return X(n.bps,`${r}.bps`);if(n.ray!=null)return P(n.ray,`${r}.ray`);if(n.wad!=null)return z(n.wad,`${r}.wad`);if(n.raw!=null)return P(n.raw,`${r}.raw`);n.value!=null&&d(`${r}.value is not an exact integer threshold; supply bps, wad, or ray`,"POSITION_HEALTH_UNSAFE_NUMBER"),d(`${r} must include bps, wad, or ray`)}let e=typeof t=="bigint"?t.toString():String(t).trim();/^\d+$/.test(e)||d(`${r} must be a non-negative base-10 integer string`);let o=BigInt(e);return o<=10000n?o.toString():o<=E?z(o,r):P(o,r)}function z(t,r){let o=BigInt(A(t,r))*10000n/E;return o>10000n&&d(`${r} exceeds 100%`),o.toString()}function P(t,r){let e=BigInt(A(t,r)),o=10n**27n,n=e*10000n/o;return n>10000n&&d(`${r} exceeds 100%`),n.toString()}function U(t,r,e){let o=`${e}[${r}]`,n=m(t,o),i=S(c(n,["asset","symbol","coin","underlying","underlyingToken","name"])??n.underlyingToken?.symbol??n.liquidityToken?.symbol,`${o}.asset`),a=_(c(n,["address","token","mint","underlyingAddress"])??n.underlyingToken?.address??n.liquidityToken?.mint,`${o}.address`),s=A(c(n,["amount","balance","aTokenBalance","supplyBalance","supplyAssets","collateral","deposited","shares"]),`${o}.amount`),l=Q(c(n,["decimals","tokenDecimals","mintDecimals"])??n.underlyingToken?.decimals??n.liquidityToken?.decimals,`${o}.decimals`),u=A(c(n,["price","priceQuoteMinor","oraclePrice","marketPrice"]),`${o}.price`),f=Q(c(n,["priceDecimals","oraclePriceDecimals","quoteDecimals"]),`${o}.priceDecimals`),y=null;if(e==="collateral"){let p=c(n,["liquidationThresholdBps","liquidationThreshold","lltv","ltvBps","collateralFactor","collateralFactorBps"])??n.supplyInfo?.liquidationThreshold;p==null&&d(`${o}.liquidationThresholdBps is required`,"POSITION_HEALTH_MISSING_THRESHOLD"),y=X(p,`${o}.liquidationThreshold`)}return w({asset:i,address:a,amount:s,decimals:String(l),price:u,priceDecimals:String(f),liquidationThresholdBps:y})}function N(t,r){return t==null?[]:(Array.isArray(t)||d(`${r} must be an array`),t.length>j&&d(`${r} exceeds ${j} assets`),t)}function ke(t){let r=c(t,["chain","chainId","network"]),e=t.market&&typeof t.market=="object"?t.market.chain?.chainId??(typeof t.market.chain=="string"||typeof t.market.chain=="bigint"?t.market.chain:null):null,o=Te(r??e,"chain"),n=S(c(t,["account","address","owner","user","wallet"]),"account"),i=c(t,["marketId","pool","vault"]);return typeof t.market=="string"||typeof t.market=="bigint"?i=i??t.market:t.market&&typeof t.market=="object"&&(i=i??t.market.address??t.market.name??t.market.marketId??null),{chain:o,account:n,market:i==null?null:S(String(i),"market")}}function Oe(t,r){let e=A(r.asOf??t.asOf,"asOf"),o=A(c(t,["observedAt","fetchedAt","updatedAt","lastUpdate","asOfObserved"]),"observedAt"),n=A(c(t,["expiresAt","validUntil","staleAfter"]),"expiresAt");return{asOf:e,observedAt:o,expiresAt:n}}function Ee(t,r,e,o){return BigInt(o)<BigInt(r)?{status:"unknown",reason:"FUTURE_EVIDENCE"}:BigInt(o)>=BigInt(e)?{status:"stale",reason:"STALE_EVIDENCE"}:t.status==="stale"?{status:"stale",reason:"STALE_EVIDENCE"}:t.status==="unknown"?{status:"unknown",reason:"UNKNOWN_EVIDENCE"}:t.status==="incomplete"?{status:"incomplete",reason:"INCOMPLETE_EVIDENCE"}:{status:"complete",reason:null}}function D(t,r,e,o={}){return w({code:t,severity:r,message:e,...o})}function Y(t){let r={critical:0,warning:1,info:2};return[...t].sort((e,o)=>{let n=(r[e.severity]??9)-(r[o.severity]??9);return n||I(e.code,o.code)||I(e.message,o.message)})}function V(t,r,e,o,n,i){return BigInt(t)*BigInt(e)*10n**BigInt(n-r)*10n**BigInt(i-o)}function $e(t,r){let e=[...t,...r],o=e.reduce((h,O)=>Math.max(h,Number(O.decimals)),0),n=e.reduce((h,O)=>Math.max(h,Number(O.priceDecimals)),0),i=0n,a=0n,s=0n;for(let h of t){let O=V(h.amount,Number(h.decimals),h.price,Number(h.priceDecimals),o,n);a+=O,i+=O*BigInt(h.liquidationThresholdBps)}for(let h of r)s+=V(h.amount,Number(h.decimals),h.price,Number(h.priceDecimals),o,n);let l=10n**BigInt(o),u={tokenDecimals:String(o),priceDecimals:String(n),unit:"quote-minor = floor(scaledValue / 10^tokenDecimals) at priceDecimals"},f=(a/l).toString(),y=(s/l).toString(),p=(i/10000n/l).toString();if(s===0n)return w({healthFactorWad:null,healthFactorStatus:a===0n?"empty":"no-debt",totalCollateralQuoteMinor:f,totalDebtQuoteMinor:"0",weightedCollateralQuoteMinor:p,liquidationBufferQuoteMinor:p,quote:u});let T=(i*E/(s*10000n)).toString(),k=i/10000n-s,x=k<0n?"-":"",$=k<0n?-k:k;return w({healthFactorWad:T,healthFactorStatus:BigInt(T)<E?"liquidatable":"priced",totalCollateralQuoteMinor:f,totalDebtQuoteMinor:y,weightedCollateralQuoteMinor:p,liquidationBufferQuoteMinor:`${x}${($/l).toString()}`,quote:u})}function b(t,r={}){g(t),g(r);let e=m(t,"snapshot");m(r,"options");let o=G(e),{chain:n,account:i,market:a}=ke(e),s=Ie(e.evidence),{asOf:l,observedAt:u,expiresAt:f}=Oe(e,r),y=S(e.id??e.positionId??`${o}:${n}:${i}:${a??"default"}`,"id"),p=_(e.tenantId,"tenantId"),T=N(e.collateral??e.supplies??e.deposits,"collateral").map(($,h)=>U($,h,"collateral")),k=N(e.debt??e.borrows??e.liabilities,"debt").map(($,h)=>U($,h,"debt")),x={id:y,protocol:o,chain:n,account:i,market:a,observedAt:u,expiresAt:f,asOf:l,evidence:s,collateral:T,debt:k};return p&&(x.tenantId=p),w(x)}function Be(t){return c(t,["liquidationThresholdBps","liquidationThreshold","lltv"])??t.market?.lltv??t.state?.lltv}function De(t,r={}){return c(r,["collateralFactorBps","collateralFactor","liquidationThresholdBps","liquidationThreshold"])??c(t,["collateralFactorBps","collateralFactor","liquidationThresholdBps"])}function _e(t){return c(t,["price","priceQuoteMinor","oraclePrice","marketPrice"])}function xe(t,r={}){g(t);let e=m(t,"snapshot");if(Array.isArray(e.collateral)||Array.isArray(e.debt))return b({...e,protocol:"aave-v3"},r);let o=e.userReserves??e.reserves??e.market?.reserves;if(!Array.isArray(o))return b({...e,protocol:"aave-v3"},r);let n=[],i=[];for(let a of o){let s=m(a,"reserve"),l=m(s.underlyingToken??s.token??s,"reserve.token"),u={asset:l.symbol??s.symbol,address:l.address??s.address,decimals:l.decimals??s.decimals,price:c(s,["price","priceQuoteMinor","oraclePrice"])??s.size?.usd,priceDecimals:c(s,["priceDecimals","oraclePriceDecimals"]),liquidationThreshold:s.liquidationThresholdBps??s.liquidationThreshold??s.supplyInfo?.liquidationThreshold},f=c(s,["aTokenBalance","supplyBalance","collateral","amount","supplied"]),y=c(s,["variableDebtTokenBalance","stableDebtTokenBalance","borrowBalance","debt","borrowed"]);f!=null&&f!=="0"&&n.push({...u,amount:f}),y!=null&&y!=="0"&&i.push({...u,amount:y})}return b({...e,protocol:"aave-v3",collateral:e.collateral??n,debt:e.debt??i},r)}function Ne(t,r={}){g(t);let e=m(t,"snapshot");if(Array.isArray(e.collateral)||Array.isArray(e.debt))return b({...e,protocol:"morpho"},r);let o=Be(e),n=e.collateralAsset??e.market?.collateralAsset??{},i=e.loanAsset??e.market?.loanAsset??{},a=e.position??e.state??{},s=[{asset:n.symbol??e.collateralSymbol,address:n.address,decimals:n.decimals??e.collateralDecimals,amount:c(e,["collateral","collateralAmount","supplyAssets"])??a.collateral??a.supplyAssets,price:c(e,["collateralPrice","price","priceQuoteMinor"])??n.price,priceDecimals:c(e,["collateralPriceDecimals","priceDecimals"])??n.priceDecimals,liquidationThreshold:o}],l=e.debt??[{asset:i.symbol??e.loanSymbol,address:i.address,decimals:i.decimals??e.loanDecimals,amount:c(e,["borrowAssets","debt","borrowAmount"])??a.borrowAssets,price:c(e,["loanPrice","debtPrice"])??i.price,priceDecimals:c(e,["loanPriceDecimals","debtPriceDecimals"])??i.priceDecimals}],u=(Array.isArray(l)?l:[l]).filter(f=>f&&f.amount!=null&&f.amount!=="0"&&f.amount!==0n);return b({...e,protocol:"morpho",market:e.marketId??e.market?.marketId??e.market,collateral:Array.isArray(s)?s:[s],debt:u},r)}function He(t,r={}){g(t);let e=m(t,"snapshot"),o=e.markets??e.cTokens??(e.cToken||e.underlying?[e]:null);if(e.collateral||e.debt)return b({...e,protocol:"compound"},r);let n=[],i=[];for(let a of N(o??[],"markets")){let s=m(a,"market"),l={asset:s.underlying??s.underlying_symbol??s.symbol??s.asset,address:s.address??s.cToken,decimals:s.decimals??s.underlyingDecimals,price:s.price??s.priceQuoteMinor??s.oraclePrice,priceDecimals:s.priceDecimals,liquidationThreshold:De(e,s)},u=c(s,["supplyBalance","balance","amount","totalSupply"]),f=c(s,["borrowBalance","borrow","debt","totalBorrow"]);u!=null&&u!=="0"&&n.push({...l,amount:u}),f!=null&&f!=="0"&&i.push({...l,amount:f})}return b({...e,protocol:"compound",collateral:n,debt:i},r)}function Pe(t,r={}){g(t);let e=m(t,"snapshot");if(e.stale===!0||e.reserve?.lastUpdate?.stale===1)return b({...e,protocol:"solend",evidence:{...e.evidence||{},status:"stale"}},r);if(e.collateral||e.debt)return b({...e,protocol:"solend"},r);let o=e.reserves??e.obligation?.deposits??(e.mint||e.mintDecimals!=null?[e]:[]),n=[],i=[];for(let a of N(o,"reserves")){let s=m(a,"reserve"),l={asset:s.symbol??s.asset??s.liquidityToken?.symbol,address:s.mint??s.address??s.liquidityToken?.mint,decimals:s.mintDecimals??s.decimals??s.liquidityToken?.decimals,price:_e(s),priceDecimals:s.priceDecimals??s.oraclePriceDecimals,liquidationThreshold:s.liquidationThresholdBps??s.liquidationThreshold??s.loanToValueRatio??e.liquidationThresholdBps},u=c(s,["depositedAmount","collateral","amount","availableAmount"]),f=c(s,["borrowedAmount","borrowBalance","debt"]);if(f==null&&s.borrowedAmountWads!=null){let y=A(s.borrowedAmountWads,"borrowedAmountWads");f=(BigInt(y)/10n**18n).toString()}u!=null&&u!=="0"&&n.push({...l,amount:u}),f!=null&&f!=="0"&&i.push({...l,amount:f})}return b({...e,protocol:"solend",collateral:n,debt:i},r)}function qe(t,r={}){g(t);let e=m(t,"snapshot");if(e.collateral||e.debt)return b({...e,protocol:"spark"},r);let o=e.vault??e.savingsVault??e.data?.vault??e,n=m(o,"vault"),i=[{asset:n.symbol??n.asset??e.token??"savings",address:n.address??e.address,decimals:n.decimals??e.decimals,amount:c(e,["amount","shares","balance"])??n.amount??n.shares,price:c(e,["price","priceQuoteMinor"])??n.price,priceDecimals:c(e,["priceDecimals"])??n.priceDecimals,liquidationThreshold:c(e,["liquidationThresholdBps","liquidationThreshold"])??"10000"}],a=c(e,["debt","borrowed","borrowAmount"]),s=a==null||a==="0"?[]:[{asset:e.debtAsset??e.borrowSymbol??"debt",address:e.debtAddress,decimals:e.debtDecimals??n.decimals??e.decimals,amount:a,price:e.debtPrice??e.price,priceDecimals:e.debtPriceDecimals??e.priceDecimals??n.priceDecimals}];return b({...e,protocol:"spark",collateral:i,debt:s},r)}function Fe(t,r={}){g(t);let e=m(t,"snapshot");if(e.tvlUsd!=null&&typeof e.tvlUsd=="number"&&d("farming tvlUsd Number is refused; supply exact collateral and debt amounts","POSITION_HEALTH_UNSAFE_NUMBER"),Array.isArray(e.collateral)||Array.isArray(e.debt)){let l=b({...e,protocol:"farming"},r),u=_(e.recipe??e.farmingMethod??e.methodId,"recipe");return w(u?{...l,recipe:u}:l)}let o=_(e.recipe??e.farmingMethod??e.methodId,"recipe"),n=[{asset:e.symbol??e.asset??e.project??"farm",address:e.pool??e.address,decimals:e.decimals,amount:c(e,["amount","deposited","shares","collateral"]),price:c(e,["price","priceQuoteMinor"]),priceDecimals:e.priceDecimals,liquidationThreshold:c(e,["liquidationThresholdBps","liquidationThreshold","lltv"])??"10000"}],i=c(e,["debt","borrowed","borrowAmount"]),a=i==null||i==="0"?[]:[{asset:e.debtAsset??e.borrowSymbol??"debt",decimals:e.debtDecimals??e.decimals,amount:i,price:e.debtPrice??e.price,priceDecimals:e.debtPriceDecimals??e.priceDecimals}],s=b({...e,protocol:"farming",collateral:n,debt:a},r);return w(o?{...s,recipe:o}:s)}var Me=Object.freeze({"aave-v3":xe,morpho:Ne,compound:He,solend:Pe,spark:qe,farming:Fe,generic:b});function Le(t,r={}){g(t);let e=m(t,"snapshot"),o=G(e);return Me[o]({...e,protocol:o},r)}function Ce(t){let r=t==null?{}:m(t,"thresholds"),e=A(r.criticalHealthFactorWad??v.criticalHealthFactorWad,"thresholds.criticalHealthFactorWad",{positive:!0}),o=A(r.warningHealthFactorWad??v.warningHealthFactorWad,"thresholds.warningHealthFactorWad",{positive:!0});BigInt(o)<BigInt(e)&&d("thresholds.warningHealthFactorWad must be >= criticalHealthFactorWad");let n=A(r.minLiquidationBufferQuoteMinor,"thresholds.minLiquidationBufferQuoteMinor",{optional:!0});return w({criticalHealthFactorWad:e,warningHealthFactorWad:o,minLiquidationBufferQuoteMinor:n})}function ve(t,r,e){let o=[];if(e.status!=="complete"){let s=e.reason||"UNKNOWN_EVIDENCE";return o.push(D(s,"critical","Position evidence is not current and complete; health fails closed.")),{healthStatus:e.status==="stale"?"stale":"unknown",findings:o,metrics:{healthFactorWad:null,totalCollateralQuoteMinor:null,totalDebtQuoteMinor:null,weightedCollateralQuoteMinor:null,liquidationBufferQuoteMinor:null,quote:null}}}let n=t;if(t.healthFactorStatus==="empty")return{healthStatus:"empty",findings:o,metrics:n};if(t.healthFactorStatus==="no-debt")return{healthStatus:"no-debt",findings:o,metrics:n};let i=BigInt(t.healthFactorWad);i<E?o.push(D("LIQUIDATABLE","critical","Health factor is below 1.0 wad; the position is at or past liquidation.")):i<BigInt(r.criticalHealthFactorWad)?o.push(D("HEALTH_FACTOR_CRITICAL","critical","Health factor is below the configured critical threshold.")):i<BigInt(r.warningHealthFactorWad)&&o.push(D("HEALTH_FACTOR_WARNING","warning","Health factor is below the configured warning threshold.")),r.minLiquidationBufferQuoteMinor!=null&&BigInt(t.liquidationBufferQuoteMinor)<BigInt(r.minLiquidationBufferQuoteMinor)&&o.push(D("LIQUIDATION_BUFFER_LOW",i<E?"critical":"warning","Liquidation buffer is below the configured quote-minor minimum."));let a="healthy";return o.some(s=>s.code==="LIQUIDATABLE")?a="liquidatable":o.some(s=>s.severity==="critical")?a="critical":o.length&&(a="warning"),{healthStatus:a,findings:o,metrics:n}}function F(t={},r={}){g(t),g(r),m(t,"input"),m(r,"options"),r.asOf==null&&t.asOf==null&&d("explicit asOf required","POSITION_HEALTH_MISSING_ASOF");let e=Le(t,r),o=Ce(r.thresholds??t.thresholds),n=Ee(e.evidence,e.observedAt,e.expiresAt,e.asOf),i=ve(n.status==="complete"?$e(e.collateral,e.debt):{healthFactorStatus:"unknown"},o,n),a={recordVersion:J,recordType:"position-health",label:K,posture:"alert-only",executionReady:!1,signingReady:!1,broadcastReady:!1,id:e.id,protocol:e.protocol,chain:e.chain,account:e.account,market:e.market,observedAt:e.observedAt,expiresAt:e.expiresAt,asOf:e.asOf,evidence:e.evidence,collateral:e.collateral,debt:e.debt,thresholds:o,healthStatus:i.healthStatus,healthFactorWad:i.metrics.healthFactorWad,totalCollateralQuoteMinor:i.metrics.totalCollateralQuoteMinor,totalDebtQuoteMinor:i.metrics.totalDebtQuoteMinor,weightedCollateralQuoteMinor:i.metrics.weightedCollateralQuoteMinor,liquidationBufferQuoteMinor:i.metrics.liquidationBufferQuoteMinor,quote:i.metrics.quote,findings:Y(i.findings)};return e.tenantId&&(a.tenantId=e.tenantId),e.recipe&&(a.recipe=e.recipe),w(a)}function Z(t={},r={}){g(t),g(r);let e=Array.isArray(t)?{snapshots:t}:m(t,"input"),o=e.snapshots??e.positions;Array.isArray(o)||d("snapshots must be an array"),o.length>W&&d(`snapshots exceed ${W}`);let n=A(r.asOf??e.asOf,"asOf"),i=r.thresholds??e.thresholds,a=_(e.tenantId,"tenantId"),s=o.map((p,T)=>F(a&&p?.tenantId==null?{...p,tenantId:a}:p,{...r,asOf:n,thresholds:i,index:T})).sort((p,T)=>I(p.chain,T.chain)||I(p.account,T.account)||I(p.id,T.id)),l=Y(s.flatMap(p=>p.findings.map(T=>({...T,positionId:p.id})))),u=s.filter(p=>p.healthStatus==="unknown"||p.healthStatus==="stale").length,f=s.filter(p=>p.findings.length>0).length,y={recordVersion:J,recordType:"position-health-book",label:K,posture:"alert-only",asOf:n,positionCount:String(s.length),alertCount:String(f),failClosedCount:String(u),positions:s,findings:l};return a&&(y.tenantId=a),w(y)}import ee from"node:fs";var te=1024*1024;function re(t=[],r={}){let e=[],o={};for(let n=0;n<t.length;n+=1){let i=t[n];if(!i.startsWith("--")){e.push(i);continue}let a=i.indexOf("="),s=i.slice(2,a===-1?void 0:a),l=r[s];if(!l)throw new TypeError(`unknown option --${s}`);if(Object.hasOwn(o,s))throw new TypeError(`duplicate option --${s}`);if(l==="boolean"){if(a!==-1)throw new TypeError(`option --${s} does not take a value`);o[s]=!0;continue}let u=a===-1?t[++n]:i.slice(a+1);if(u==null||u===""||u.startsWith("--"))throw new TypeError(`option --${s} requires a value`);o[s]=u}return{positionals:e,options:o}}function M(t,r="input"){if(!t)throw new TypeError(`${r} JSON path or - is required`);let e=t==="-"?ee.readFileSync(0):ee.readFileSync(t);if(e.length>te)throw new RangeError(`${r} exceeds ${te} bytes`);let o;try{o=JSON.parse(e.toString("utf8"))}catch(n){throw new TypeError(`${r} must be valid JSON: ${n.message}`)}if(!o||typeof o!="object"||Array.isArray(o)||Object.getPrototypeOf(o)!==Object.prototype)throw new TypeError(`${r} must be a JSON object`);return o}function oe(t,r=process.stdout){r.write(`${JSON.stringify(t,null,2)}
|
|
2
|
+
`)}function ne(t,r=process.stderr){return r.write(`oracle: ${t instanceof Error?t.message:String(t)}
|
|
3
|
+
`),2}var L="oracle position-health <evaluate|book> <input.json|-> --as-of <integer> [--thresholds <json>]",Ge={name:"position-health",summary:"evaluate supplied lending and farming position snapshots",group:"read",usage:L,async run(t){let r=t.argv??[];if(r.length===0||r.includes("--help")||r.includes("-h"))return process.stdout.write(`${L}
|
|
4
|
+
`),0;try{let{positionals:e,options:o}=re(r,{"as-of":"value",thresholds:"value"});if(e.length!==2||!["evaluate","book"].includes(e[0])||!o["as-of"])throw new TypeError(L);let n=M(e[1]),i=o.thresholds?M(o.thresholds,"thresholds"):void 0,a={asOf:o["as-of"],thresholds:i},s=e[0]==="book"?Z(n,a):F(n,a);return oe(s),0}catch(e){return ne(e)}}};export{Ge as default};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import{createHash as se}from"node:crypto";import{getAddress as oe,wordlists as ie}from"ethers";import{address as ae}from"@solana/addresses";import{base58check as ce,bech32 as W,bech32m as de}from"@scure/base";import{sha256 as le}from"@noble/hashes/sha2.js";var V=1,tt=Object.freeze({CLEAR:"CLEAR",UNKNOWN:"UNKNOWN",REVIEW:"REVIEW",BLOCK:"BLOCK"}),fe=Object.freeze(["sanctions","phishing","scam","address-poisoning"]),ye=Object.freeze(["sanctions","phishing","scam"]),he=new Set(fe),ge=128,me=256,S=512,we=4096,Ee=8,ue=2048,q=366*24*60*60*1e3,Ce=6e4,be=ce(le),Te=["privatekey","privkey","secretkey","secret","seedphrase","seed","mnemonic","passphrase","password","keystore","keymaterial","wif","xprv","xpriv","apikey","bearer","authorization","credential"],pe=/\b[5KL][1-9A-HJ-NP-Za-km-z]{50,51}\b/,ke=/\bxprv[0-9A-Za-z]{50,}\b/,Ie=/^\s*(?:0x)?[0-9a-fA-F]{64}\s*$/,ve=new Set([12,15,18,21,24]),Ae=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/,Ne=/^\d+$/,Se=String(Number.MAX_SAFE_INTEGER).length,Oe=new Set(["txhash","transactionhash","recordid","hash","digest","evidenceid","sourcerecordid","blockhash","receipthash","commithash","payloadhash","sha256","sha256hex","id"]),xe=Object.freeze({CLEAR:"CLEAR",NO_MATCH:"CLEAR",NOT_LISTED:"CLEAR",ABSENT:"CLEAR",REVIEW:"REVIEW",SUSPECTED:"REVIEW",POSSIBLE_MATCH:"REVIEW",INCONCLUSIVE:"REVIEW",BLOCK:"BLOCK",MATCH:"BLOCK",LISTED:"BLOCK",MALICIOUS:"BLOCK",PHISHING:"BLOCK",SCAM:"BLOCK",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNKNOWN",ERROR:"UNKNOWN"}),M=Object.freeze({BLOCK:0,REVIEW:1,UNKNOWN:2,INFO:3});function P(e){return String(e).replace(/[^a-z0-9]/gi,"").toLowerCase()}function Re(e){let t=P(e);return Te.some(r=>t.includes(r))}function $e(e){return Oe.has(P(e))}function _e(e){let t=String(e).trim().toLowerCase().split(/\s+/).filter(Boolean);return ve.has(t.length)&&t.every(r=>ie.en.getWordIndex(r)>=0)}function p(e){let t=new WeakSet,r=0;function s(n,o,a,d=""){if(r+=1,r>we)throw new RangeError("safety-intelligence: input is too large");if(a>Ee)throw new RangeError("safety-intelligence: input is too deep");if(n==null||typeof n=="boolean")return;if(typeof n=="string"){if(n.length>ue)throw new RangeError(`safety-intelligence: string too long at ${o}`);if(pe.test(n)||ke.test(n)||_e(n))throw new TypeError(`safety-intelligence: key material refused at ${o}`);if(Ie.test(n)&&!$e(d))throw new TypeError(`safety-intelligence: key material refused at ${o}`);return}if(typeof n=="number"){if(!Number.isFinite(n))throw new TypeError(`safety-intelligence: finite number required at ${o}`);return}if(typeof n=="bigint")return;if(typeof n!="object")throw new TypeError(`safety-intelligence: JSON-like input required at ${o}`);if(ArrayBuffer.isView(n)||n instanceof ArrayBuffer)throw new TypeError(`safety-intelligence: binary key material refused at ${o}`);if(t.has(n))throw new TypeError(`safety-intelligence: cyclic input refused at ${o}`);if(t.add(n),Array.isArray(n)){if(n.length>S)throw new RangeError(`safety-intelligence: array too large at ${o}`);if(n.length===64&&n.every(c=>Number.isInteger(c)&&c>=0&&c<=255))throw new TypeError(`safety-intelligence: key material refused at ${o}`);n.forEach((c,f)=>s(c,`${o}[${f}]`,a+1,d)),t.delete(n);return}if(Object.getPrototypeOf(n)!==Object.prototype)throw new TypeError(`safety-intelligence: plain object required at ${o}`);let y=Reflect.ownKeys(n).filter(c=>typeof c=="string");if(y.length>64)throw new RangeError(`safety-intelligence: too many fields at ${o}`);for(let c of y){if(Re(c))throw new TypeError(`safety-intelligence: secret-bearing field refused at ${o}.${c}`);let f=Object.getOwnPropertyDescriptor(n,c),m=f&&"get"in f&&typeof f.get=="function"?f.get.call(n):n[c];m!==void 0&&s(m,`${o}.${c}`,a+1,c)}t.delete(n)}return s(e,"$",0),e}function w(e,t,r){for(let s of Object.keys(e||{}))if(!t.has(s))throw new TypeError(`safety-intelligence: unknown ${r} field ${s}`)}function k(e,t,r,{required:s=!1}={}){if(e==null||e===""){if(s)throw new TypeError(`safety-intelligence: ${t} required`);return null}let n=String(e).trim();if(!n&&s)throw new TypeError(`safety-intelligence: ${t} required`);if(n.length>r)throw new RangeError(`safety-intelligence: ${t} exceeds ${r} characters`);if(/[\u0000-\u001f\u007f\u200b-\u200f\u202a-\u202e\u2060-\u2064\ufeff]/i.test(n))throw new TypeError(`safety-intelligence: control or invisible characters refused in ${t}`);return n||null}function O(e,t){if(e==null||e==="")throw new TypeError(`safety-intelligence: ${t} required`);let r;if(typeof e=="number"){if(!Number.isSafeInteger(e)||e<0)throw new TypeError(`safety-intelligence: ${t} must be a safe integer millisecond timestamp`);r=e}else if(typeof e=="string"){let s=e.trim();if(Ne.test(s)&&s.length<=Se){if(r=Number(s),!Number.isSafeInteger(r))throw new TypeError(`safety-intelligence: ${t} must be a safe integer millisecond timestamp`)}else if(Ae.test(s)){if(r=Date.parse(s),!Number.isFinite(r)||new Date(r).toISOString().replace(/\.000Z$/,"Z")!==s&&new Date(r).toISOString()!==s)throw new TypeError(`safety-intelligence: ${t} must be a canonical ISO timestamp`)}else throw new TypeError(`safety-intelligence: ${t} must be a canonical ISO timestamp or integer milliseconds`)}else throw new TypeError(`safety-intelligence: ${t} must be a timestamp`);if(!Number.isFinite(r))throw new TypeError(`safety-intelligence: ${t} must be a valid timestamp`);return{ms:r,iso:new Date(r).toISOString()}}function H(e,t){return e==null||e===""?null:O(e,t)}function F(e){let t=String(e||"").trim().toLowerCase();if(t==="evm"||t==="eip155")return"evm";if(t==="solana")return"solana";if(t==="bitcoin"||t==="bip122"||t==="btc")return"bitcoin";throw new TypeError("safety-intelligence: chain family must be evm, solana, or bitcoin")}function J(e){p(e);let t,r;if(Number.isInteger(e))t="evm",r=e;else if(typeof e=="string"){let o=e.trim();if(/^\d+$/.test(o))t="evm",r=Number(o);else{let a=/^(eip155|evm|solana|bitcoin|bip122|btc):([^:]+)$/i.exec(o);if(!a)throw new TypeError("safety-intelligence: chain must include a supported family");t=F(a[1]),r=a[2]}}else if(e&&typeof e=="object"&&!Array.isArray(e))w(e,new Set(["family","namespace","chainId","reference","network","key"]),"chain"),t=F(e.family??e.namespace??(e.chainId!=null?"evm":"")),r=t==="evm"?e.chainId??e.reference:e.network??e.reference;else throw new TypeError("safety-intelligence: chain required");if(t==="evm"){let o=typeof r=="string"&&/^\d+$/.test(r)?Number(r):r;if(!Number.isSafeInteger(o)||o<=0)throw new TypeError("safety-intelligence: EVM chainId must be a positive safe integer");return g({family:t,namespace:"eip155",reference:String(o),chainId:o,key:`eip155:${o}`})}let s=k(r,`${t} network`,80,{required:!0}).toLowerCase();if(!/^[a-z0-9][a-z0-9._-]*$/.test(s))throw new TypeError(`safety-intelligence: invalid ${t} network`);let n=t==="bitcoin"?"bip122":"solana";return g({family:t,namespace:n,reference:s,network:s,key:`${n}:${s}`})}function Le(e){let t=String(e).toLowerCase();return["mainnet","main","bitcoin"].includes(t)?"mainnet":["testnet","testnet3","test","signet"].includes(t)?"testnet":t==="regtest"?"regtest":"unknown"}function Be(e,t){let r=k(e,"bitcoin address",100,{required:!0}),s=Le(t.reference);if(/^(bc1|tb1|bcrt1)/i.test(r)){if(r!==r.toLowerCase()&&r!==r.toUpperCase())throw new TypeError("safety-intelligence: mixed-case Bitcoin bech32 address refused");let a=r.toLowerCase(),d,y;try{d=W.decode(a,100),y="bech32"}catch{try{d=de.decode(a,100),y="bech32m"}catch{throw new TypeError("safety-intelligence: invalid Bitcoin bech32 checksum")}}let c=d.words[0],f;try{f=W.fromWords(d.words.slice(1))}catch{throw new TypeError("safety-intelligence: invalid Bitcoin witness program")}if(!Number.isInteger(c)||c<0||c>16||f.length<2||f.length>40)throw new TypeError("safety-intelligence: invalid Bitcoin witness program");if(c===0&&(y!=="bech32"||![20,32].includes(f.length)))throw new TypeError("safety-intelligence: invalid v0 Bitcoin witness address");if(c>0&&y!=="bech32m")throw new TypeError("safety-intelligence: v1+ Bitcoin witness address must use bech32m");let m=s==="mainnet"?"bc":s==="testnet"?"tb":s==="regtest"?"bcrt":null;if(m&&d.prefix!==m)throw new TypeError(`safety-intelligence: Bitcoin address does not match ${t.reference}`);return{canonical:a,display:a}}let n;try{n=be.decode(r)}catch{throw new TypeError("safety-intelligence: invalid Bitcoin base58check address")}if(n.length!==21)throw new TypeError("safety-intelligence: invalid Bitcoin address payload");let o=n[0];if(s==="mainnet"&&![0,5].includes(o))throw new TypeError("safety-intelligence: Bitcoin address does not match mainnet");if((s==="testnet"||s==="regtest")&&![111,196].includes(o))throw new TypeError(`safety-intelligence: Bitcoin address does not match ${t.reference}`);return{canonical:r,display:r}}function Ue(e,t){let r=J(t);p(e);let s=k(e,`${r.family} address`,128,{required:!0});if(r.family==="evm"){let n=s.startsWith("0X")?`0x${s.slice(2)}`:s,o;try{o=oe(n)}catch{throw new TypeError("safety-intelligence: invalid EVM address or mixed-case checksum")}return g({canonical:o.toLowerCase(),display:o})}if(r.family==="solana"){let n;try{n=String(ae(s))}catch{throw new TypeError("safety-intelligence: invalid Solana address")}return g({canonical:n,display:n})}return g(Be(s,r))}function I(e={}){if(p(e),!e||typeof e!="object"||Array.isArray(e))throw new TypeError("safety-intelligence: target object required");w(e,new Set(["chain","chainId","family","network","address","displayAddress","key"]),"target");let t=e.chain??(e.chainId!=null?{family:e.family??"evm",chainId:e.chainId}:{family:e.family,network:e.network}),r=J(t),s=Ue(e.address,r);return g({chain:r,address:s.canonical,displayAddress:s.display,key:`${r.key}:${s.canonical}`})}function T(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(T).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${T(e[t])}`).join(",")}}`}function L(e){return se("sha256").update(e).digest("hex")}function g(e){if(!e||typeof e!="object"||Object.isFrozen(e))return e;for(let t of Object.values(e))g(t);return Object.freeze(e)}function $(e){let t=String(e||"").trim().toLowerCase().replace(/_/g,"-"),s={sanction:"sanctions",sanctions:"sanctions",phishing:"phishing",scam:"scam",fraud:"scam",poisoning:"address-poisoning","address-poisoning":"address-poisoning"}[t];if(!s||!he.has(s))throw new TypeError(`safety-intelligence: unsupported evidence kind ${String(e||"<missing>")}`);return s}function Ke(e){let t=e.verdict??e.disposition??e.result??e.status;if(t==null){for(let n of["match","listed","malicious"])if(typeof e[n]=="boolean"){t=e[n]?"MATCH":"NO_MATCH";break}}let r=String(t||"").trim().toUpperCase().replace(/[ -]+/g,"_"),s=xe[r];if(!s)throw new TypeError(`safety-intelligence: unsupported evidence verdict ${String(t||"<missing>")}`);return s}function je(e,t){let r=e.target??(e.address!=null?{address:e.address,chain:e.chain,chainId:e.chainId,family:e.family,network:e.network}:null);if(!r){if(!t)throw new TypeError("safety-intelligence: evidence target required");return t}return I(r)}function De(e={},t={}){if(p({input:e,options:t}),!e||typeof e!="object"||Array.isArray(e))throw new TypeError("safety-intelligence: evidence object required");w(e,new Set(["kind","type","category","source","sourceRecordId","recordId","reference","verdict","disposition","result","status","match","listed","malicious","confidence","fetchedAt","expiresAt","expiry","ttlMs","summary","target","address","chain","chainId","family","network"]),"evidence"),w(t,new Set(["target","asOf"]),"evidence option");let r=je(e,t.target?I(t.target):null),s=$(e.kind??e.type??e.category),n=Ke(e),o=e.source&&typeof e.source=="object"?e.source.name??e.source.id:e.source,a=k(o,"evidence source",120,{required:!0}),d=Number(e.confidence);if(!Number.isFinite(d)||d<0||d>1)throw new TypeError("safety-intelligence: evidence confidence must be between 0 and 1");let y=O(e.fetchedAt,"evidence fetchedAt"),c=H(e.expiresAt??e.expiry,"evidence expiresAt");if(!c&&e.ttlMs!=null){let i=Number(e.ttlMs);if(!Number.isSafeInteger(i)||i<=0||i>q)throw new RangeError(`safety-intelligence: evidence ttlMs must be 1..${q}`);c={ms:y.ms+i,iso:new Date(y.ms+i).toISOString()}}if(!c)throw new TypeError("safety-intelligence: evidence expiresAt or ttlMs required");if(c.ms<=y.ms)throw new TypeError("safety-intelligence: evidence expiry must be after fetchedAt");if(t.asOf==null)throw new TypeError("safety-intelligence: explicit asOf required for deterministic freshness");let f=O(t.asOf,"asOf").ms,m=y.ms>f+Ce?"FUTURE":c.ms<=f?"STALE":"CURRENT",u=k(e.sourceRecordId??e.recordId??e.reference,"source record id",160),l=k(e.summary,"evidence summary",500),h={kind:s,verdict:n,source:a,...u?{sourceRecordId:u}:{},fetchedAt:y.iso,expiresAt:c.iso,confidence:d,freshness:m,target:r.key,...l?{summary:l}:{}},v=`safety-evidence:${L(T(h))}`;return g({id:v,...h})}function We(e=[],t={}){if(p({records:e,options:t}),!Array.isArray(e))throw new TypeError("safety-intelligence: evidence must be an array");let r=t.maxEvidence??ge;if(!Number.isSafeInteger(r)||r<=0||r>S)throw new RangeError("safety-intelligence: invalid maxEvidence");if(e.length>r)throw new RangeError(`safety-intelligence: evidence exceeds ${r} records`);w(t,new Set(["target","asOf","maxEvidence"]),"evidence-set option");let s={target:t.target,asOf:t.asOf},n=new Map(e.map(o=>{let a=De(o,s);return[a.id,a]}));return g([...n.values()].sort((o,a)=>o.id.localeCompare(a.id)))}function Ve(e,t,r){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError(`safety-intelligence: knownContacts[${r}] must be an object`);w(e,new Set(["id","label","address","chain","chainId","family","network"]),"contact");let s=I({address:e.address,chain:e.chain??(e.chainId!=null?{family:e.family??"evm",chainId:e.chainId}:e.family||e.network?{family:e.family,network:e.network}:t)}),n=k(e.id,"contact id",120),o=k(e.label,"contact label",120);return g({...n?{id:n}:{},...o?{label:o}:{},target:s})}function x(e,t){if(typeof e=="number"&&(!Number.isSafeInteger(e)||e<0))throw new TypeError(`safety-intelligence: ${t} must be an exact non-negative integer`);let r=typeof e=="bigint"?e.toString():String(e??"").trim();if(!/^\d+$/.test(r)||r.length>100)throw new TypeError(`safety-intelligence: ${t} must be a bounded base-unit integer`);return BigInt(r).toString()}function qe(e,t,r){if(!e||typeof e!="object"||Array.isArray(e))throw new TypeError(`safety-intelligence: observations[${r}] must be an object`);w(e,new Set(["address","counterparty","from","direction","amountBaseUnits","chain","chainId","family","network","observedAt"]),"observation");let s=e.counterparty??e.address??e.from,n=I({address:s,chain:e.chain??(e.chainId!=null?{family:e.family??"evm",chainId:e.chainId}:e.family||e.network?{family:e.family,network:e.network}:t)}),o=String(e.direction??(e.from!=null?"inbound":"unknown")).toLowerCase(),a=["inbound","received","receive"].includes(o)?"inbound":["outbound","sent","send"].includes(o)?"outbound":"unknown",d=x(e.amountBaseUnits,`observations[${r}].amountBaseUnits`),y=H(e.observedAt,`observations[${r}].observedAt`)?.iso??null;return g({target:n,direction:a,amountBaseUnits:d,...y?{observedAt:y}:{}})}function Me(e,t){let r=0;for(;r<e.length&&r<t.length&&e[r]===t[r];)r+=1;return r}function Fe(e,t){let r=0;for(;r<e.length&&r<t.length&&e[e.length-1-r]===t[t.length-1-r];)r+=1;return r}function z(e){return e.chain.family==="evm"?e.address.slice(2):e.address}function b(e){return g({code:e.code,severity:e.severity,category:e.category,basis:e.basis,message:e.message,...e.evidenceIds?.length?{evidenceIds:[...e.evidenceIds].sort()}:{},...e.relatedTargets?.length?{relatedTargets:[...e.relatedTargets].sort()}:{}})}function _(e){let t=new Map;for(let r of e){let s=T(r);t.set(s,r)}return[...t.values()].sort((r,s)=>(M[r.severity]??9)-(M[s.severity]??9)||r.category.localeCompare(s.category)||r.code.localeCompare(s.code)||T(r).localeCompare(T(s)))}function ze(e={},t={}){if(p({input:e,options:t}),!e||typeof e!="object"||Array.isArray(e))throw new TypeError("safety-intelligence: poisoning input object required");w(e,new Set(["target","address","chain","chainId","family","network","knownContacts","expectedContact","observations","dustThresholdBaseUnits","lookalikeEdgeChars"]),"poisoning input"),w(t,new Set(["maxContacts","maxObservations"]),"poisoning option");let r=I(e.target??{address:e.address,chain:e.chain,chainId:e.chainId,family:e.family,network:e.network}),s=e.knownContacts??[],n=e.observations??[];if(!Array.isArray(s))throw new TypeError("safety-intelligence: knownContacts must be an array");if(!Array.isArray(n))throw new TypeError("safety-intelligence: observations must be an array");let o=t.maxContacts??me,a=t.maxObservations??S;if(!Number.isSafeInteger(o)||o<=0||o>S)throw new RangeError("safety-intelligence: invalid maxContacts");if(!Number.isSafeInteger(a)||a<=0||a>S)throw new RangeError("safety-intelligence: invalid maxObservations");if(s.length>o)throw new RangeError(`safety-intelligence: knownContacts exceeds ${o}`);if(n.length>a)throw new RangeError(`safety-intelligence: observations exceeds ${a}`);let d=s.map((l,h)=>Ve(l,r.chain,h)).sort((l,h)=>l.target.key.localeCompare(h.target.key)||String(l.id||l.label||"").localeCompare(String(h.id||h.label||""))),y=n.map((l,h)=>qe(l,r.chain,h)).sort((l,h)=>T(l).localeCompare(T(h))),c=d.filter(l=>l.target.chain.key===r.chain.key),f=c.filter(l=>l.target.address===r.address),m=[],u=null;if(e.expectedContact!=null){if(typeof e.expectedContact=="string")u=I({chain:r.chain,address:e.expectedContact});else if(typeof e.expectedContact=="object"&&!Array.isArray(e.expectedContact))w(e.expectedContact,new Set(["address","chain","chainId","family","network"]),"expectedContact"),u=I({address:e.expectedContact.address,chain:e.expectedContact.chain??(e.expectedContact.chainId!=null?{family:e.expectedContact.family??"evm",chainId:e.expectedContact.chainId}:e.expectedContact.family||e.expectedContact.network?{family:e.expectedContact.family,network:e.expectedContact.network}:r.chain)});else throw new TypeError("safety-intelligence: expectedContact must be an address or target object");u.key!==r.key&&m.push(b({code:"EXPECTED_CONTACT_MISMATCH",severity:"REVIEW",category:"address-poisoning",basis:"contact-match",message:"Destination does not exactly match the caller-supplied expected contact.",relatedTargets:[u.key,r.key]}))}if(f.length===0){let l=Number(e.lookalikeEdgeChars??4);if(!Number.isSafeInteger(l)||l<3||l>12)throw new RangeError("safety-intelligence: lookalikeEdgeChars must be 3..12");let h=z(r);for(let v of c){let i=z(v.target),E=Me(h,i),N=Fe(h,i);E>=l&&N>=l&&h!==i&&m.push(b({code:"ADDRESS_LOOKALIKE",severity:"REVIEW",category:"address-poisoning",basis:"heuristic",message:`Destination shares at least ${l} leading and trailing characters with a different known contact.`,relatedTargets:[v.target.key,r.key]}))}if(e.dustThresholdBaseUnits!=null){let v=BigInt(x(e.dustThresholdBaseUnits,"dustThresholdBaseUnits"));y.filter(E=>E.target.key===r.key&&E.direction==="inbound"&&BigInt(E.amountBaseUnits)<=v).length>0&&m.push(b({code:"PRIOR_DUST_CONTACT",severity:"REVIEW",category:"address-poisoning",basis:"heuristic",message:"Destination appeared as an inbound counterparty at or below the caller-supplied base-unit dust threshold.",relatedTargets:[r.key]}))}}return g({target:r,exactKnownContact:f.length>0,exactContacts:f,findings:_(m),dustThresholdBaseUnits:e.dustThresholdBaseUnits==null?null:x(e.dustThresholdBaseUnits,"dustThresholdBaseUnits")})}function Pe(e){let t=e??ye;if(!Array.isArray(t)||t.length===0||t.length>32)throw new TypeError("safety-intelligence: requiredChecks must be a non-empty bounded array");let r=t.map((n,o)=>{if(typeof n=="string")return{kind:$(n),source:null};if(!n||typeof n!="object"||Array.isArray(n))throw new TypeError(`safety-intelligence: requiredChecks[${o}] must be a kind or object`);return w(n,new Set(["kind","source"]),"required check"),{kind:$(n.kind),source:k(n.source,"required check source",120,{required:!0})}}),s=new Map(r.map(n=>[`${n.kind}:${n.source||"*"}`,n]));return g([...s.values()].sort((n,o)=>`${n.kind}:${n.source||"*"}`.localeCompare(`${o.kind}:${o.source||"*"}`)))}function He(e,t){return e.filter(r=>r.kind===t.kind&&(!t.source||r.source===t.source))}function Je(e){return e.some(t=>t.severity==="BLOCK")?"BLOCK":e.some(t=>t.severity==="REVIEW")?"REVIEW":e.some(t=>t.severity==="UNKNOWN")?"UNKNOWN":"CLEAR"}function X(e){return p(e),`sha256:${L(T(e))}`}function B(e={},t={}){if(p({input:e,options:t}),!e||typeof e!="object"||Array.isArray(e))throw new TypeError("safety-intelligence: evaluation input object required");if(w(e,new Set(["target","address","chain","chainId","family","network","evidence","requiredChecks","knownContacts","expectedContact","observations","dustThresholdBaseUnits","lookalikeEdgeChars"]),"evaluation input"),w(t,new Set(["asOf","minClearConfidence","minBlockConfidence","maxEvidence","maxContacts","maxObservations"]),"evaluation option"),t.asOf==null)throw new TypeError("safety-intelligence: explicit asOf required for deterministic evaluation");let r=O(t.asOf,"asOf").iso,s=e.target??{address:e.address,chain:e.chain,chainId:e.chainId,family:e.family,network:e.network},n=I(s),o=Number(t.minClearConfidence??.8),a=Number(t.minBlockConfidence??.8);for(let[i,E]of[["minClearConfidence",o],["minBlockConfidence",a]])if(!Number.isFinite(E)||E<0||E>1)throw new TypeError(`safety-intelligence: ${i} must be between 0 and 1`);let d=We(e.evidence??[],{target:n,asOf:r,maxEvidence:t.maxEvidence}),y=d.filter(i=>i.target===n.key),c=Pe(e.requiredChecks),f=[];for(let i of y)i.freshness==="CURRENT"&&i.verdict==="BLOCK"?f.push(b({code:i.confidence>=a?"CURRENT_EXPLICIT_BLOCK":"LOW_CONFIDENCE_BLOCK_SIGNAL",severity:i.confidence>=a?"BLOCK":"REVIEW",category:i.kind,basis:"explicit-evidence",message:i.confidence>=a?"A current injected source returned an explicit BLOCK disposition.":"A current injected source returned BLOCK below the configured block-confidence threshold.",evidenceIds:[i.id]})):i.freshness==="CURRENT"&&i.verdict==="REVIEW"?f.push(b({code:"CURRENT_EXPLICIT_REVIEW",severity:"REVIEW",category:i.kind,basis:"explicit-evidence",message:"A current injected source returned an explicit REVIEW disposition.",evidenceIds:[i.id]})):i.freshness!=="CURRENT"&&["BLOCK","REVIEW"].includes(i.verdict)?f.push(b({code:i.freshness==="FUTURE"?"FUTURE_POSITIVE_EVIDENCE":"STALE_POSITIVE_EVIDENCE",severity:"REVIEW",category:i.kind,basis:"explicit-evidence",message:"Non-current injected adverse evidence requires human review; it is not treated as a current fact.",evidenceIds:[i.id]})):i.freshness==="CURRENT"&&i.verdict==="UNKNOWN"&&f.push(b({code:"SOURCE_UNKNOWN",severity:"UNKNOWN",category:i.kind,basis:"explicit-evidence",message:"A current injected source could not determine a disposition.",evidenceIds:[i.id]}));for(let i of c){let E=He(y,i),N=E.filter(C=>C.freshness==="CURRENT"),R=N.filter(C=>C.verdict==="CLEAR"&&C.confidence>=o),j=N.filter(C=>C.verdict==="BLOCK");if(R.length>0&&j.length>0&&f.push(b({code:"CONTRADICTORY_EVIDENCE",severity:"REVIEW",category:i.kind,basis:"explicit-evidence",message:"Current injected sources conflict for a required check.",evidenceIds:[...R,...j].map(C=>C.id)})),R.length===0){let C=N.filter(A=>A.verdict==="CLEAR"),D=E.filter(A=>A.verdict==="CLEAR"&&A.freshness!=="CURRENT"),ne=i.source?`${i.kind} from ${i.source}`:i.kind;f.push(b({code:C.length>0?"CLEAR_CONFIDENCE_TOO_LOW":D.length>0?"STALE_CLEAR_EVIDENCE":"MISSING_CURRENT_EVIDENCE",severity:"UNKNOWN",category:i.kind,basis:"coverage",message:`Required check ${ne} lacks current explicit CLEAR evidence at the configured confidence threshold.`,evidenceIds:[...C,...D].map(A=>A.id)}))}}let m=ze({target:n,knownContacts:e.knownContacts??[],expectedContact:e.expectedContact,observations:e.observations??[],dustThresholdBaseUnits:e.dustThresholdBaseUnits,lookalikeEdgeChars:e.lookalikeEdgeChars},{maxContacts:t.maxContacts,maxObservations:t.maxObservations});f.push(...m.findings);let u=_(f),l=Je(u);l==="CLEAR"&&(u=_([b({code:"REQUIRED_EVIDENCE_CURRENT_CLEAR",severity:"INFO",category:"coverage",basis:"explicit-evidence",message:"Every required injected check supplied current explicit CLEAR evidence; this is source-scoped and not a safety guarantee.",evidenceIds:y.filter(i=>i.freshness==="CURRENT"&&i.verdict==="CLEAR").map(i=>i.id)})]),l="CLEAR");let h={version:V,target:n.key,evaluatedAt:r,decision:l,gate:l==="CLEAR"?"CONTINUE":l==="BLOCK"?"BLOCK":"HOLD",requiredChecks:c,evidenceIds:y.map(i=>i.id).sort(),findings:u},v=g({...h,hash:X(h)});return g({version:V,target:n,evaluatedAt:r,status:l,evidence:d,requiredChecks:c,poisoning:m,policy:v})}function Xe(e={}){if(p(e),!e||typeof e!="object"||Array.isArray(e))throw new TypeError("safety-intelligence: transaction object required");w(e,new Set(["target","to","destination","address","chain","chainId","family","network","amountBaseUnits","valueBaseUnits"]),"transaction");let t=I(e.target??{address:e.to??e.destination??e.address,chain:e.chain,chainId:e.chainId,family:e.family,network:e.network}),r=e.amountBaseUnits??e.valueBaseUnits,s=r==null?null:x(r,"transaction amountBaseUnits"),n={target:t,amountBaseUnits:s};return g({id:`safety-transaction:${L(T(n))}`,...n})}function G(e={},t={}){if(p({input:e,options:t}),!e||typeof e!="object"||Array.isArray(e))throw new TypeError("safety-intelligence: transaction evaluation input object required");w(e,new Set(["transaction","evidence","requiredChecks","knownContacts","expectedContact","observations","dustThresholdBaseUnits","lookalikeEdgeChars"]),"transaction evaluation input");let r=Xe(e.transaction),s=B({target:r.target,evidence:e.evidence??[],requiredChecks:e.requiredChecks,knownContacts:e.knownContacts??[],expectedContact:e.expectedContact,observations:e.observations??[],dustThresholdBaseUnits:e.dustThresholdBaseUnits,lookalikeEdgeChars:e.lookalikeEdgeChars},t),{hash:n,...o}=s.policy,a={...o,transactionId:r.id},d=g({...a,hash:X(a)});return g({...s,transaction:r,policy:d})}import Y from"node:fs";var Z=1024*1024;function Q(e=[],t={}){let r=[],s={};for(let n=0;n<e.length;n+=1){let o=e[n];if(!o.startsWith("--")){r.push(o);continue}let a=o.indexOf("="),d=o.slice(2,a===-1?void 0:a),y=t[d];if(!y)throw new TypeError(`unknown option --${d}`);if(Object.hasOwn(s,d))throw new TypeError(`duplicate option --${d}`);if(y==="boolean"){if(a!==-1)throw new TypeError(`option --${d} does not take a value`);s[d]=!0;continue}let c=a===-1?e[++n]:o.slice(a+1);if(c==null||c===""||c.startsWith("--"))throw new TypeError(`option --${d} requires a value`);s[d]=c}return{positionals:r,options:s}}function ee(e,t="input"){if(!e)throw new TypeError(`${t} JSON path or - is required`);let r=e==="-"?Y.readFileSync(0):Y.readFileSync(e);if(r.length>Z)throw new RangeError(`${t} exceeds ${Z} bytes`);let s;try{s=JSON.parse(r.toString("utf8"))}catch(n){throw new TypeError(`${t} must be valid JSON: ${n.message}`)}if(!s||typeof s!="object"||Array.isArray(s)||Object.getPrototypeOf(s)!==Object.prototype)throw new TypeError(`${t} must be a JSON object`);return s}function U(e,t){if(e==null)return;let r=Number(e);if(!Number.isFinite(r)||r<0||r>1)throw new TypeError(`${t} must be between 0 and 1`);return r}function te(e,t=process.stdout){t.write(`${JSON.stringify(e,null,2)}
|
|
2
|
+
`)}function re(e,t=process.stderr){return t.write(`oracle: ${e instanceof Error?e.message:String(e)}
|
|
3
|
+
`),2}var K="oracle safety-intelligence <address|transaction> <input.json|-> --as-of <timestamp> [--min-clear-confidence <0..1>] [--min-block-confidence <0..1>]",at={name:"safety-intelligence",summary:"evaluate supplied address or transaction safety evidence",group:"read",usage:K,async run(e){let t=e.argv??[];if(t.length===0||t.includes("--help")||t.includes("-h"))return process.stdout.write(`${K}
|
|
4
|
+
`),0;try{let{positionals:r,options:s}=Q(t,{"as-of":"value","min-clear-confidence":"value","min-block-confidence":"value"});if(r.length!==2||!["address","transaction"].includes(r[0])||!s["as-of"])throw new TypeError(K);let n=ee(r[1]),o={asOf:s["as-of"],minClearConfidence:U(s["min-clear-confidence"],"min clear confidence"),minBlockConfidence:U(s["min-block-confidence"],"min block confidence")},a=r[0]==="transaction"?G(n,o):B(n,o);return te(a),0}catch(r){return re(r)}}};export{at as default};
|