qiforge-cli 1.2.1 → 1.2.13

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/cli.js CHANGED
@@ -1,5 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import{cancel as Ve,intro as Hr,isCancel as _t,log as Q,outro as Gr,select as Lt,spinner as Yr}from"@clack/prompts";import K from"process";var Z=class{commands;constructor(){this.commands=new Map}register(e){this.commands.set(e.name,e)}get(e){return this.commands.get(e)}getAll(){return Array.from(this.commands.values())}getCommandOptions(){return this.getAll().map(e=>({value:e.name,label:e.name,hint:e.description}))}};import*as w from"@clack/prompts";import{select as Xt}from"@clack/prompts";import{z as W}from"zod";var S=async r=>{let e=await Xt({message:"Select network: (default: devnet)",options:[{value:"mainnet",label:"Mainnet"},{value:"testnet",label:"Testnet"},{value:"devnet",label:"Devnet"}],initialValue:"devnet",maxItems:1});return r.addValue("network",e),e},He={mainnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d",testnet:"did:ixo:entity:3d079ebc0b332aad3305bb4a51c72edb",devnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d"},X={devnet:"https://devmx.ixo.earth",testnet:"https://testmx.ixo.earth",mainnet:"https://mx.ixo.earth"};var Ge={devnet:"https://ixo-portal.vercel.app",testnet:"https://ixo-portal.vercel.app",mainnet:"https://ixo-portal.vercel.app"},M={mainnet:"https://impacthub.ixo.world/rpc/",testnet:"https://testnet.ixo.earth/rpc/",devnet:"https://devnet.ixo.earth/rpc/"},H={devnet:"https://domain-indexer.devnet.ixo.earth/index",testnet:"https://domain-indexer.testnet.ixo.earth/index",mainnet:"https://domain-indexer.ixo.earth/index"},G={devnet:"https://devnet-blocksync-graphql.ixo.earth/graphql",testnet:"https://testnet-blocksync-graphql.ixo.earth/graphql",mainnet:"https://blocksync-graphql.ixo.earth/graphql"},be={devnet:"https://mcp-memory-engine.devnet.ixo.earth/",testnet:"https://memory-engine.testnet.ixo.earth/",mainnet:"https://memory-engine.ixo.earth/"},Te={devnet:"https://mcp-memory-engine.devnet.ixo.earth/",testnet:"https://mcp-memory-engine.testnet.ixo.earth/",mainnet:"https://mcp-memory-engine.ixo.earth/"},Pe={devnet:"https://ai-sandbox-devnet.ixo.earth/mcp",testnet:"https://ai-sandbox-testnet.ixo.earth/mcp",mainnet:"https://ai-sandbox.ixo.earth/mcp"},ke={devnet:"https://subscriptions-api.ixo-api.workers.dev",testnet:"https://subscriptions-api-testnet.ixo-api.workers.dev/",mainnet:"https://subscriptions-api-mainnet.ixo-api.workers.dev/"},b=(r,e="This field is required")=>{let i=W.string().min(1,e).safeParse(r);if(!i.success)return i.error.message},L=r=>{let t=W.string().regex(/^did:ixo:entity:[a-f0-9]{32}$/,"Invalid entity DID").safeParse(r);if(!t.success)return t.error.message},B=(r,e="This url is required or a valid URL")=>{let i=W.url(e).safeParse(r);if(!i.success)return i.error.message},Ye=(r,e="This number is required")=>{let i=W.number().min(1,e).safeParse(r);if(!i.success)return i.error.message},j=r=>{let t=W.string().min(1,"PIN is required").refine(i=>/^\d{6}$/.test(i),"PIN must be exactly 6 digits").safeParse(r);if(!t.success)return t.error.issues[0]?.message??"Invalid PIN"},ee=r=>{let t=W.string().min(1,"Matrix homeserver URL is required").refine(i=>/^https?:\/\//.test(i),"Must start with http:// or https://").refine(i=>!i.endsWith("/"),"Must not end with a trailing slash").safeParse(r);if(!t.success)return t.error.issues[0]?.message??"Invalid Matrix URL"};function Je(r){let e=new URL(r),t=e.hostname,i=e.protocol;return{homeServerUrl:r,roomBotUrl:`${i}//rooms.bot.${t}`,stateBotUrl:`${i}//state.bot.${t}`,bidsBotUrl:`${i}//bids.bot.${t}`,claimsBotUrl:`${i}//claims.bot.${t}`}}import{isCancel as Pr,log as f,spinner as kr,text as Nr}from"@clack/prompts";import{customMessages as kt,ixo as v,utils as We}from"@ixo/impactxclient-sdk";import{sha256 as ir}from"@cosmjs/crypto";import{encrypt as nr}from"eciesjs";import{ClientEvent as or,createClient as Me}from"matrix-js-sdk";import sr from"md5";var te=new Map;function Bt(r){return te.get(r)instanceof Uint8Array}function jt(r){return te.get(r)}function Ne(){te.clear()}async function ze({keys:r}){let e=Object.keys(r),t=e.find(Bt);if(console.info("[] getSecretStorageKey",r,e,t),!t)return null;let i=jt(t);return[t,i]}function Qe(r,e,t){te.set(r,t)}import{Bip39 as rt,EnglishMnemonic as it,Secp256k1 as Oe,sha256 as qt,Slip10 as nt,Slip10Curve as ot,stringToPath as st}from"@cosmjs/crypto";import{DirectSecp256k1HdWallet as Ht}from"@cosmjs/proto-signing";import{createQueryClient as at,createSigningClient as Gt,customMessages as Yt,ixo as Jt,utils as zt}from"@ixo/impactxclient-sdk";import{createCipheriv as Qt,randomBytes as Zt}from"crypto";import{createRegistry as Vt,utils as Ft}from"@ixo/impactxclient-sdk";function Y(r){try{return Ft.proto.fromTimestamp(r).getTime()}catch{return}}var re={BasicAllowance:"/cosmos.feegrant.v1beta1.BasicAllowance",PeriodicAllowance:"/cosmos.feegrant.v1beta1.PeriodicAllowance"},Ze=r=>{let e=Vt();return(r??[]).map(t=>{let i=t.allowance,n=e.decode(i);switch(i.typeUrl){case re.BasicAllowance:return{granter:t.granter,grantee:t.grantee,type:re.BasicAllowance,expiration:n.expiration?Y(n.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};case re.PeriodicAllowance:return{granter:t.granter,grantee:t.grantee,type:re.PeriodicAllowance,expiration:n.basic?.expiration?Y(n.basic.expiration):null,limit:n?.periodCanSpend?n?.periodCanSpend?.find(o=>o.denom==="uixo")?.amount:n?.basic?.spendLimit?.length?n?.basic?.spendLimit?.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};default:return{type:i.typeUrl,granter:t.granter,grantee:t.grantee,expiration:n.expiration?Y(n.expiration):n.basic?.expiration?Y(n.basic.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:n?.periodCanSpend?n?.periodCanSpend?.find(o=>o.denom==="uixo")?.amount:n?.basic?.spendLimit?.length?n?.basic?.spendLimit?.find(o=>o.denom==="uixo")?.amount:null,msgs:n.allowedMessages}}})},et=r=>{if(r==null)return!1;let e=typeof r=="object"?Y(r):r;return e==null?!0:e<Date.now()},tt=r=>r==null?!1:(typeof r=="object"?Number(r?.amount??0):typeof r=="string"?Number(r??0):r)<=5e-4;async function Ue(r,e){if(!e)throw new Error("Network parameter is required but was undefined");console.log(`\u{1F50D} Checking IID document for DID: ${r} on network: ${e}`);let t=M[e];if(!t)throw new Error(`Invalid network: ${e}. Valid networks are: ${Object.keys(M).join(", ")}`);console.log(`\u{1F517} Using RPC URL: ${t}`);try{return!!(await(await at(t)).ixo.iid.v1beta1.iidDocument({id:r}))?.iidDocument?.id}catch(i){if(i.message?.includes("did document not found")||i.message?.includes("(22)"))return!1;throw console.error("Error checking IID document:",i),i}}async function ct(r,e,t,i){try{let n=await t.getAccounts(),{address:o,pubkey:s}=n[0]??{},a=await er(o,e),c=a?.length?Ze(a)?.find(m=>!!m&&!et(m.expiration)&&!tt(m.limit))?.granter:void 0,l={typeUrl:"/ixo.iid.v1beta1.MsgCreateIidDocument",value:Jt.iid.v1beta1.MsgCreateIidDocument.fromPartial({id:r,verifications:Yt.iid.createIidVerificationMethods({did:r,pubkey:s,address:o,controller:r,type:"secp"}),signer:o,controllers:[r],...i?.length?{services:i}:{}})};await tr({offlineSigner:t,messages:[l],feegrantGranter:c,network:e})}catch(n){throw console.error(n),n}}async function er(r,e){try{let t=M[e];if(!t)throw new Error(`Invalid network: ${e}`);return(await(await at(t)).cosmos.feegrant.v1beta1.allowances({grantee:r}))?.allowances??[]}catch(t){console.error("queryAddressAllowances::",t.message);return}}var tr=async({offlineSigner:r,messages:e,memo:t="Signing with Mnemonic Demo",feegrantGranter:i,network:n})=>{let o=M[n];if(!o)throw new Error(`Invalid network: ${n}`);let s=await Gt(o,r),a=await r.getAccounts(),{address:c}=a[0]??{},l=await s.simulate(c,e,t),d=(l>5e4?l:(e??[]).length*5e5)*1.7,p=rr(d),x={amount:[{denom:"uixo",amount:String(Math.round(p.average))}],gas:String(Math.round(d)),granter:i},g=await s.signAndBroadcast(c,e,x,t,void 0);if(!!g.code)throw new Error(`Error when broadcasting tx ${g.transactionHash} at height ${g.height}. Code: ${g.code}; Raw log: ${g.rawLog}`)},rr=r=>{let e={low:.02,average:.035,high:.045},t=r<.01?.01:r;return{low:t*e.low,average:t*e.average,high:t*e.high}},ie=r=>new Promise(e=>setTimeout(e,r));function ne(r,e){let t=Zt(16),i=Qt("aes-256-cbc",Buffer.from(e.padEnd(32)),t),n=i.update(r);return n=Buffer.concat([n,i.final()]),t.toString("hex")+":"+n.toString("hex")}var lt=async r=>{let e=await Ht.fromMnemonic(r,{prefix:"ixo"}),t=(await e.getAccounts())[0],i=await rt.mnemonicToSeed(new it(r)),n=st("m/44'/118'/0'/0/0"),s=nt.derivePath(ot.Secp256k1,i,n).privkey,a=await Oe.makeKeypair(s),c=Oe.compressPubkey(a.pubkey);return{mnemonic:r,did:zt.did.generateSecpDid(t.address),baseAccount:t,async getAccounts(){return await e.getAccounts()},async signDirect(m,d){return await e.signDirect(m,d)},async sign(m){try{let d=await rt.mnemonicToSeed(new it(r)),p=st("m/44'/118'/0'/0/0"),{privkey:x}=nt.derivePath(ot.Secp256k1,d,p),g=new Uint8Array(Buffer.from(m,"base64")),I=qt(g);return(await Oe.createSignature(I,x)).toFixedLength().slice(0,64)}catch(d){throw console.error("Error during signature creation:",d),d}}}};var ar="/.well-known/matrix/client",De=async({homeServerUrl:r,username:e,password:t,deviceName:i},n=!1)=>{let o=r,s=e,a=s.match(/^@(.+):(.+\..+)$/);a&&(s=a[1],o=a[2],o=n?o:await ur(o));try{let c=pt(o),l=await c.login("m.login.password",{identifier:{type:"m.id.user",user:fr(s)},password:t,initial_device_display_name:i});return{accessToken:l.access_token,deviceId:l.device_id,userId:l.user_id,baseUrl:n?o:l?.well_known?.["m.homeserver"]?.base_url||c.baseUrl}}catch(c){let l=c.message;throw l==="Unknown message"&&(l="Please check your credentials"),console.error("mxLogin::",l),new Error(l)}};async function cr(r){let e=await fetch(`${r}/public-key`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!e.ok)throw new Error("Failed to fetch public key for encryption");return await e.json()}function lr(r){let e={timestamp:new Date().toISOString(),address:r,service:"matrix",type:"create-account"},t=Buffer.from(JSON.stringify(e)).toString("base64");return{challenge:e,challengeBase64:t}}function dr(r,e){let t=new Uint8Array(Buffer.from(e,"hex")),i=new Uint8Array(Buffer.from(r,"utf8")),n=nr(t,i);return Array.from(n,o=>o.toString(16).padStart(2,"0")).join("")}async function mr(r,e,t,i,n,o){let s=await cr(o),a=dr(e,s.publicKey),c={address:r,encryptedPassword:a,publicKeyFingerprint:s.fingerprint,secpResult:{signature:t,challenge:i}},l=await fetch(`${o}/user/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});if(!l.ok){let m=await l.text(),d=`Failed to create user account (HTTP ${l.status})`;try{let p=JSON.parse(m);d=p.error||p.message||p.detail||m}catch{d=m||d}throw console.error(`Room bot error [${l.status}]: ${m}`),new Error(d)}return await l.json()}async function dt(r,e,t,i,n,o){try{let{challengeBase64:s}=lr(r),a=await i.sign(s),c=Buffer.from(a).toString("base64");if(!(await mr(r,e,c,s,n,o)).success)throw new Error("Failed to create matrix account via API");let m=_e(r);return await De({homeServerUrl:n,username:m,password:e,deviceName:t})}catch(s){throw console.error("mxRegisterWithSecp error:",s),s}}async function mt({homeServerUrl:r,username:e}){let t=pt(r);try{return!!await t.isUsernameAvailable(e)}catch{return!1}}function pt(r){if(!r)throw new Error("Home server URL is required to instantiate matrix client");return Me({baseUrl:r})}async function gt({homeServerUrl:r,accessToken:e,userId:t,deviceId:i}){if(console.log("createMatrixClient::",{homeServerUrl:r,accessToken:e,userId:t,deviceId:i}),!r||!e||!t||!i)throw new Error("Login to Matrix account before trying to instantiate Matrix client.");let n=Me({baseUrl:r,accessToken:e,userId:t,deviceId:i,timelineSupport:!0,cryptoCallbacks:{getSecretStorageKey:ze,cacheSecretStorageKey:Qe},verificationMethods:["m.sas.v1"]});return await n.initRustCrypto({useIndexedDB:!1}),n.setMaxListeners(20),await n.startClient({lazyLoadMembers:!0,includeArchivedRooms:!1}),await new Promise((o,s)=>{let a={NULL:()=>{console.info("[NULL] state")},SYNCING:()=>{},PREPARED:()=>{console.info(`[PREPARED] state: user ${t}`),o()},RECONNECTING:()=>{console.info("[RECONNECTING] state")},CATCHUP:()=>{console.info("[CATCHUP] state")},ERROR:()=>{s(new Error("[ERROR] state: starting matrix client"))},STOPPED:()=>{console.info("[STOPPED] state")}};n.on(or.Sync,c=>{a[c]()})}),n}async function oe({mxClient:r,baseUrl:e,accessToken:t,userId:i,deviceId:n}){let o=r;o||(o=Me({baseUrl:e,accessToken:t,userId:i,deviceId:n})),o&&(o.stopClient(),await o.logout().catch(console.error),o.clearStores())}function ut(r){let e=r.getAccountData("m.cross_signing.master");return console.log("hasCrossSigningAccountData::masterKeyData",e),!!e}async function ft(r,{securityPhrase:e,password:t,forceReset:i=!1,skipBootstrapSecureStorage:n=!1}){i&&Ne();let o=r.getCrypto();if(!o)throw new Error("Failed to setup matrix cross signing - failed to get matrix crypto api");if(!n){let a=await o.createRecoveryKeyFromPassphrase(e);Ne(),await o.bootstrapSecretStorage({createSecretStorageKey:async()=>a,setupNewSecretStorage:i})}let s=r.getUserId();return await o.bootstrapCrossSigning({authUploadDeviceSigningKeys:async function(a){await a(hr({userId:s,password:t}))},setupNewCrossSigning:i}),await o.resetKeyBackup(),await ie(300),!!r.getAccountData("m.cross_signing.master")}function _e(r){if(!r)throw new Error("Address is required to generate matrix username");return"did-ixo-"+r}function ht(r){return Buffer.from(sr(r.replace(/ /g,""))).toString("base64").slice(0,24)}function yt(r){let e=ir(new TextEncoder().encode(r.replace(/ /g,"")));return Buffer.from(e).toString("base64").slice(0,32)}function pr(r){return r.replace(/^(https?:\/\/)/,"").replace(/\/$/,"")}function gr(r,e=""){return"did-ixo-"+r+e}function wt(r,e){return"#"+gr(r)+":"+pr(e)}async function ur(r){let e="https://";/^https?:\/\//.test(r)&&(e="");let t=`${e}${r}${ar}`;try{let o=(await(await fetch(t,{method:"GET"})).json())["m.homeserver"]?.base_url;if(o===void 0)throw new Error;return o}catch{return`${e}${r}`}}function fr(r){return(r.indexOf("@")===0?r.substring(1):r).trim()}function hr({userId:r,password:e}){return{type:"m.login.password",password:e,identifier:{type:"m.id.user",user:r}}}import{ixo as yr,utils as Le}from"@ixo/impactxclient-sdk";import{createMatrixApiClient as wr}from"@ixo/matrixclient-sdk";var xt="Oracles CLI";async function se({pin:r,oracleName:e,network:t,oracleAvatarUrl:i,matrixHomeServerUrl:n},o){try{let{homeServerUrl:s,roomBotUrl:a}=Je(n),c=Le.mnemonic.generateMnemonic(),l=await lt(c),m=l.baseAccount.address;console.log("\u2705 Wallet created:",m),await o(m);let d=Le.did.generateSecpDid(m),p=await Ue(d,t);if(console.log("\u2705 DID exists:",p),!p){console.log("\u2705 DID does not exist, creating...");let _=yr.iid.v1beta1.Service.fromPartial({id:`${d}#matrix`,type:"MatrixHomeServer",serviceEndpoint:s});if(await ct(d,t,l,[_]),console.log("\u2705 DID created, waiting 500ms..."),await ie(500),console.log("\u2705 Checking if DID exists..."),!await Ue(d,t))throw new Error("Failed to create DID document")}console.log("\u2705 DID created:",d);let x=Le.mnemonic.generateMnemonic(12),g=_e(m),I=ht(x),O=yt(x);if(!await mt({homeServerUrl:s,username:g}))throw new Error("Matrix account already exists");let R=await dt(m,I,xt,l,s,a);if(!R?.accessToken)throw new Error("Failed to register matrix account");console.log("\u2705 Matrix account created:",R.userId);let U=await gt({homeServerUrl:s,accessToken:R.accessToken,userId:R.userId,deviceId:R.deviceId});try{await Promise.all([U.setDisplayName(e),U.setAvatarUrl(i)])}catch(_){console.error("Failed to set display name or avatar url:",_)}let T=wr({homeServerUrl:s,accessToken:R.accessToken}),Ie=ut(U);if(!Ie&&(Ie=await ft(U,{securityPhrase:O,password:I,forceReset:!0}),!Ie))throw new Error("Failed to setup cross signing");console.log("\u2705 Matrix cross-signing setup completed");let $t=wt(m,R.baseUrl),P=(await T.room.v1beta1.queryId($t).catch(()=>{}))?.room_id??"";if(!P){let _=await fetch(`${a}/room/source`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({did:d,userMatrixId:R.userId})});if(!_.ok)throw new Error("Failed to create matrix room");if(P=(await _.json()).roomId,!P)throw new Error("Failed to create user matrix room")}let Se=await T.room.v1beta1.listJoinedMembers(P).catch(()=>{}),Ae=!!Se?.joined?.[R.userId];if(!Ae){if(!(await T.room.v1beta1.join(P)).room_id)throw new Error("Failed to join matrix room");if(Se=await T.room.v1beta1.listJoinedMembers(P),Ae=!!Se?.joined?.[R.userId],!Ae)throw new Error("Failed to join matrix room")}console.log("\u2705 Matrix room created/joined:",P);let Kt=ne(x,r),qe=await fetch(`${s}/_matrix/client/v3/rooms/${P}/state/ixo.room.state.secure/encrypted_mnemonic`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${R.accessToken}`},body:JSON.stringify({encrypted_mnemonic:Kt})});if(!qe.ok)throw new Error("Failed to store encrypted mnemonic in matrix room");return await qe.json(),console.log("\u2705 Encrypted Matrix mnemonic stored in room"),U.stopClient(),{address:m,did:d,mnemonic:c,matrixUserId:R.userId,matrixRoomId:P,matrixMnemonic:x,matrixPassword:I,matrixAccessToken:R.accessToken,matrixRecoveryPhrase:O,matrixHomeServerUrl:s,pin:r,matrixDeviceName:xt}}catch(s){throw console.error("Simplified registration failed:",s),s}}import{ixo as $e}from"@ixo/impactxclient-sdk";import xr from"bs58";import{randomUUID as Ct}from"crypto";import{exportJWK as vt,generateKeyPair as vr}from"jose";var Rt="ixo.room.encryption_key.index",Et="p256_encryption",Cr="ixo.room.encryption_key";function Rr(r){let e=Buffer.from(r.x,"base64url"),t=Buffer.from(r.y,"base64url"),i=new Uint8Array(33);return i[0]=(t[t.length-1]&1)===0?2:3,i.set(e,1),i}function Er(r){let e=new Uint8Array(2+r.length);return e[0]=128,e[1]=36,e.set(r,2),"z"+xr.encode(e)}async function Ke(r,e,t){let i=await fetch(`${t}/_matrix/client/v3/rooms/${encodeURIComponent(r)}/state/${Rt}/${Et}`,{headers:{Authorization:`Bearer ${e}`}});if(i.status===404)return null;if(!i.ok)throw new Error(`Failed to read encryption key index (status ${i.status}): ${await i.text()}`);return await i.json()}async function Ir(r,e,t,i){let n=`enc_key_${Ct()}`,o=await fetch(`${t}/_matrix/client/v3/rooms/${encodeURIComponent(r)}/send/${Cr}/${n}`,{method:"PUT",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({encrypted_private_key:i})});if(!o.ok)throw new Error(`Failed to store encryption key timeline event: ${o.statusText}`);let s=await o.json();if(!s?.event_id)throw new Error("No event_id returned from timeline event send");return s.event_id}async function It(r,e,t,i){let n=await fetch(`${t}/_matrix/client/v3/rooms/${encodeURIComponent(r)}/state/${Rt}/${Et}`,{method:"PUT",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(i)});if(!n.ok)throw new Error(`Failed to write encryption key state index: ${n.statusText}`)}function St(r){let e=r.indexOf(":");if(e===-1||!r.startsWith("!"))throw new Error(`Invalid Matrix room ID format: ${r}. Expected !roomId:server (e.g. !abc123:devmx.ixo.earth)`);return`https://${r.slice(e+1)}`}async function At(r,e,t){let i=await Ke(r,e,t);return i?.keys?Object.values(i.keys).some(n=>n.active):!1}async function ae(r){let{roomId:e,accessToken:t,homeServerUrl:i,pin:n,oracleEntityDid:o}=r,s=await Ke(e,t,i);if(s?.keys){let U=Object.entries(s.keys).find(([,T])=>!T.active&&T.publicKeyMultibase);if(U){let[,T]=U;return{publicKeyMultibase:T.publicKeyMultibase,verificationMethodId:T.didVerificationMethodId}}}let a=Ct(),{privateKey:c,publicKey:l}=await vr("ECDH-ES",{crv:"P-256",extractable:!0}),m=await vt(c);m.alg="ECDH-ES+A256KW";let d=await vt(l);d.alg="ECDH-ES+A256KW";let p=ne(JSON.stringify(m),n),x=await Ir(e,t,i,p),g=Rr(d),I=Er(g),O=`${o}#p256-enc-1`,Ee={eventId:x,didVerificationMethodId:O,algorithm:"ECDH-ES+A256KW",curve:"P-256",createdAt:new Date().toISOString(),active:!1,publicKeyMultibase:I},R={keys:{...s?.keys??{},[a]:Ee}};return await It(e,t,i,R),{publicKeyMultibase:I,verificationMethodId:O}}async function ce(r){let{roomId:e,accessToken:t,homeServerUrl:i,verificationMethodId:n}=r,o=await Ke(e,t,i);if(!o?.keys)throw new Error("No encryption key index found \u2014 cannot activate");let s=!1;for(let a of Object.values(o.keys))a.didVerificationMethodId===n&&(a.active=!0,s=!0);if(!s)throw new Error(`No key entry found for verification method ${n}`);await It(e,t,i,o)}function le(r){return{typeUrl:"/ixo.iid.v1beta1.MsgAddVerification",value:$e.iid.v1beta1.MsgAddVerification.fromPartial({id:r.oracleEntityDid,verification:$e.iid.v1beta1.Verification.fromPartial({relationships:["keyAgreement"],method:$e.iid.v1beta1.VerificationMethod.fromPartial({id:r.verificationMethodId,type:"Multikey",controller:r.oracleEntityDid,publicKeyMultibase:r.publicKeyMultibase})}),signer:r.signerAddress})}}import{createMatrixApiClient as br,utils as Tr}from"@ixo/matrixclient-sdk";import{CID as Sr}from"multiformats";import{base64 as Ar}from"multiformats/bases/base64";import*as bt from"multiformats/hashes/sha2";async function Tt(r){let e=r.startsWith("m")?r:"m"+r,t=Ar.decode(e),i=await bt.sha256.digest(t);return Sr.create(1,85,i).toString()}function Pt(r){let e=new TextEncoder().encode(r);return btoa(String.fromCharCode(...Array.from(e)))}var J=async({data:r,fileName:e,homeServerUrl:t,accessToken:i})=>{let n=br({homeServerUrl:t,accessToken:i}),o=JSON.stringify(r),s=Buffer.from(o,"utf8"),a=e+".json",l=await n.media.v1beta1.upload(a,"application/ld+json",s),m=Tr.mxc.mxcUrlToHttp(t,l.content_uri);if(!m)throw new Error("Failed to upload file to Matrix");let d=JSON.stringify(r),p=Pt(d),x=await Tt(p);return{encrypted:"false",cid:x,proof:x,serviceEndpoint:m,mxc:l.content_uri}};var D=class{constructor(e,t){this.config=t;if(!e.did||!e.pubKey||!e.address||!e.algo)throw new Error("Wallet not found");this.wallet=e}wallet;buildMsgCreateEntity(e){return{typeUrl:"/ixo.entity.v1beta1.MsgCreateEntity",value:v.entity.v1beta1.MsgCreateEntity.fromPartial({entityType:"oracle",context:[],entityStatus:0,verification:[...kt.iid.createIidVerificationMethods({did:this.wallet.did,pubkey:new Uint8Array(Buffer.from(this.wallet.pubKey)),address:this.wallet.address,controller:this.wallet.did,type:this.wallet.algo==="ed25519"?"ed":"secp"})],controller:[this.wallet.did],ownerAddress:this.wallet.address,ownerDid:this.wallet.did,relayerNode:He[this.config.getValue("network")??"devnet"],service:[v.iid.v1beta1.Service.fromPartial({id:"{id}#matrix",type:"MatrixHomeServer",serviceEndpoint:e})],linkedResource:[],accordedRight:[],linkedEntity:[],linkedClaim:[],startDate:We.proto.toTimestamp(new Date),endDate:We.proto.toTimestamp(new Date(Date.now()+31536e8))})}}addLinkedAccounts(e,{oracleAccountAddress:t}){if(!this.wallet.signXClient||!this.wallet.wallet)throw new Error("SignX client or wallet not found");let o=[{devnet:"did:ixo:ixo17w9u5uk4qjyjgeyqfpnp92jwy58faey9vvp3ar",testnet:"did:ixo:ixo14vjrckltpngugp03tcasfgh5qakey9n3sgm6y2",mainnet:"did:ixo:ixo1d39eutxdc0e8mnp0fmzqjdy6aaf26s9hzrk33r"}[this.config.getValue("network")],`did:ixo:${t}`].map(s=>v.iid.v1beta1.LinkedEntity.fromPartial({id:s,type:"agent",relationship:"admin",service:"matrix"}));e.value.linkedEntity=o}async createAuthZConfig({oracleAccountAddress:e,oracleName:t,entityDid:i,homeServerUrl:n,accessToken:o}){let a=await J({data:{"@context":["https://schema.org",{ixo:"https://w3id.org/ixo/context/v1",oracle:{"@id":i,"@type":"@id"}}],"@type":"Service","@id":"oracle:OracleAuthorization",name:"OracleAuthorization",description:"OracleAuthorization",serviceType:"OracleClaimAuthorizationService",requiredPermissions:["/ixo.claims.v1beta1.MsgCreateClaimAuthorization"],granteeAddress:e,granterAddress:"",oracleName:t},fileName:"authz",homeServerUrl:n,accessToken:o});return v.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#orz",type:"oracleAuthZConfig",proof:a.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Orale AuthZ Config",serviceEndpoint:a.serviceEndpoint})}async createFeesConfig({entityDid:e,price:t,denom:i,homeServerUrl:n,accessToken:o}){let s={"@context":["https://schema.org",{ixo:"https://w3id.org/ixo/context/v1",oracle:{"@id":e,"@type":"@id"}}],"@type":"Service","@id":"oracle:ServiceFeeModel",name:"Pricing",description:"Pricing",serviceType:"",offers:{"@type":"Offer",priceCurrency:i,priceSpecification:{"@type":"PaymentChargeSpecification",priceCurrency:i,price:t*1e3,unitCode:"MON",billingIncrement:1,billingPeriod:"P1M",priceType:"Subscription",maxPrice:t},eligibleQuantity:{"@type":"QuantitativeValue",value:1,unitCode:"MON"}}},a=await J({data:s,fileName:"fees",homeServerUrl:n,accessToken:o});return v.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#fee",type:"pricingList",proof:a.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Pricing List",serviceEndpoint:a.serviceEndpoint})}async updateOracleDomain(e,t){let i=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!i)throw new Error("SignX client or wallet not found");let n={typeUrl:"/ixo.iid.v1beta1.MsgDeleteService",value:v.iid.v1beta1.MsgDeleteService.fromPartial({id:e,serviceId:`${e}#api`,signer:i})},o={typeUrl:"/ixo.iid.v1beta1.MsgDeleteService",value:v.iid.v1beta1.MsgDeleteService.fromPartial({id:e,serviceId:`${e}#ws`,signer:i})},s={typeUrl:"/ixo.iid.v1beta1.MsgAddService",value:v.iid.v1beta1.MsgAddService.fromPartial({id:e,serviceData:v.iid.v1beta1.Service.fromPartial({id:`${e}#api`,type:"oracleService",serviceEndpoint:t}),signer:i})},a={typeUrl:"/ixo.iid.v1beta1.MsgAddService",value:v.iid.v1beta1.MsgAddService.fromPartial({id:e,serviceData:v.iid.v1beta1.Service.fromPartial({id:`${e}#ws`,type:"wsService",serviceEndpoint:t}),signer:i})};f.info(`Sign to update oracle domain for entity ${e}`);let c=await this.wallet.signXClient.transact([n,o,s,a],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(c)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),f.success(`Oracle domain updated to ${t}`)}async addControllerToEntity(e,t){let i=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!i)throw new Error("SignX client or wallet not found");let n={typeUrl:"/ixo.iid.v1beta1.MsgAddController",value:v.iid.v1beta1.MsgAddController.fromPartial({id:e,controllerDid:t,signer:i})};f.info(`Sign to add controller ${t} to entity ${e}`);let o=await this.wallet.signXClient.transact([n],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(o)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),f.success(`Controller ${t} added to entity ${e}`)}async createOracleConfigFiles({oracleName:e,entityDid:t,price:i,oracleAccountAddress:n,homeServerUrl:o,accessToken:s}){let a=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!a)throw new Error("SignX client or wallet not found");let l=(await Promise.all([this.createAuthZConfig({oracleName:e,entityDid:t,oracleAccountAddress:n,homeServerUrl:o,accessToken:s}),this.createFeesConfig({entityDid:t,price:i,denom:this.config.getValue("network")==="devnet"?"uixo":"ibc/6BBE9BD4246F8E04948D5A4EEE7164B2630263B9EBB5E7DC5F0A46C62A2FF97B",homeServerUrl:o,accessToken:s})])).map(p=>({typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:v.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:t,linkedResource:v.iid.v1beta1.LinkedResource.fromPartial({id:p.id,description:p.description,type:p.type,proof:p.proof,mediaType:p.mediaType,encrypted:p.encrypted,serviceEndpoint:p.serviceEndpoint}),signer:a})}));f.info("Sign to edit the entity and add the config files");let m=await this.wallet.signXClient.transact(l,this.wallet.wallet);return this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(m)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction()}async createDomainCard({profile:e,entityDid:t,homeServerUrl:i,accessToken:n}){let o=new Date().toISOString(),s={"@context":["https://www.w3.org/ns/credentials/v2","https://w3id.org/ixo/context/v1",{schema:"https://schema.org/",ixo:"https://w3id.org/ixo/vocab/v1",prov:"http://www.w3.org/ns/prov#",proj:"https://linked.data.gov.au/def/project#",xsd:"http://www.w3.org/2001/XMLSchema#",id:"@id",type:"@type","ixo:vector":{"@container":"@list","@type":"xsd:double"},"@protected":!0}],id:`${t}#dmn`,type:["VerifiableCredential","ixo:DomainCard"],issuer:{id:this.wallet.did},validFrom:o,credentialSchema:{id:"https://github.com/ixoworld/domainCards/schemas/ixo-domain-card-1.json",type:"JsonSchema"},credentialSubject:{id:t,type:["ixo:oracle"],additionalType:["schema:Organization"],name:e.name,alternateName:e.orgName!==e.name?[e.orgName]:void 0,description:e.description,logo:{type:"schema:ImageObject",id:e.logo,contentUrl:e.logo},image:[{type:"schema:ImageObject",id:e.coverImage,contentUrl:e.coverImage}],address:{type:"schema:PostalAddress",addressLocality:e.location},...e.url?{url:e.url}:{}}},a=await J({data:s,fileName:"domainCard",homeServerUrl:i,accessToken:n});return v.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#dmn",type:"domainCard",proof:a.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Domain Card",serviceEndpoint:a.serviceEndpoint})}async addProfile({orgName:e,name:t,logo:i,coverImage:n,location:o,description:s,homeServerUrl:a,accessToken:c}){let m=await J({data:{"@context":{ixo:"https://w3id.org/ixo/ns/protocol/","@id":"@type",type:"@type","@protected":!1},id:"ixo:entity#profile",type:"profile",orgName:e,name:t,image:n,logo:i,brand:e,location:o,description:s},fileName:"profile",homeServerUrl:a,accessToken:c});return v.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#pro",type:"Settings",description:"Profile",mediaType:"application/json",serviceEndpoint:m.serviceEndpoint,proof:m.proof,encrypted:"false",right:""})}addServices(e,t){e.value.service.push(...t.map(i=>v.iid.v1beta1.Service.fromPartial(i)))}setParentProtocol(e,t){e.value.context.push(...kt.iid.createAgentIidContext([{key:"class",val:t}]))}async submitToDomainIndexer(e){let t=this.config.getValue("network")??"devnet",i=H[t];try{let n=await fetch(i,{method:"POST",headers:{accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({did:e})});if(!n.ok){let o=await n.text();f.warn(`Failed to submit to domain indexer: ${n.status} ${o}`);return}f.success("Domain card submitted to domain indexer")}catch(n){f.warn(`Error submitting to domain indexer: ${n instanceof Error?n.message:String(n)}`)}}async execute(e){if(!this.wallet.signXClient||!this.wallet.wallet)throw new Error("SignX client not found");let{matrixHomeServerUrl:t}=e;f.info("Creating Oracle Wallet and Matrix Account");let i=await Nr({message:"Enter a 6-digit PIN to secure your Matrix Vault:",placeholder:"123456",validate(g){return j(g)}});Pr(i)&&(f.error("User cancelled"),process.exit(1));let n=await se({pin:i,oracleName:e.oracleConfig.oracleName,network:this.config.getValue("network"),oracleAvatarUrl:e.profile.logo,matrixHomeServerUrl:t},async g=>{await this.wallet.sendTokens(g,25e4)}),o=n.matrixHomeServerUrl,s=n.matrixAccessToken;f.info("Adding profile");let a=await this.addProfile({...e.profile,homeServerUrl:o,accessToken:s}),c=this.buildMsgCreateEntity(t);c.value.linkedResource.push(a),f.info("Adding services"),this.addServices(c,e.services),f.info("Adding parent protocol"),this.setParentProtocol(c,e.parentProtocol),this.addLinkedAccounts(c,{oracleAccountAddress:n.address}),f.info("Sign this transaction to create the entity");let l=await this.wallet.signXClient.transact([c],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(l)),await this.wallet.signXClient.pollNextTransaction();let m=await this.wallet.signXClient.awaitTransaction();f.success("Entity created -- wait to attach the required config files");let d=We.common.getValueFromEvents(m,"wasm","token_id");f.info("Creating domain card");let p=await this.createDomainCard({profile:e.profile,entityDid:d,homeServerUrl:o,accessToken:s});if(this.wallet.wallet?.address){let g={typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:v.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:d,linkedResource:v.iid.v1beta1.LinkedResource.fromPartial({id:p.id,description:p.description,type:p.type,proof:p.proof,mediaType:p.mediaType,encrypted:p.encrypted,serviceEndpoint:p.serviceEndpoint}),signer:this.wallet.wallet.address})};f.info("Sign to add domain card to the entity");let I=await this.wallet.signXClient.transact([g],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(I)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),f.success("Domain card added to entity")}await this.createOracleConfigFiles({oracleName:e.oracleConfig.oracleName,price:e.oracleConfig.price,oracleAccountAddress:n.address,entityDid:d,homeServerUrl:o,accessToken:s}),f.success("Entity created -- config files attached"),f.info("Setting up P-256 encryption key for secrets management");try{let g=await ae({roomId:n.matrixRoomId,accessToken:s,homeServerUrl:o,pin:i,oracleEntityDid:d}),I=le({oracleEntityDid:d,verificationMethodId:g.verificationMethodId,publicKeyMultibase:g.publicKeyMultibase,signerAddress:this.wallet.wallet.address});f.info("Sign to add P-256 encryption key (keyAgreement) to the entity");let O=await this.wallet.signXClient.transact([I],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(O)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),await ce({roomId:n.matrixRoomId,accessToken:s,homeServerUrl:o,verificationMethodId:g.verificationMethodId}),f.success("P-256 encryption key published to entity DID")}catch(g){f.warn(`Failed to setup encryption key: ${g instanceof Error?g.message:String(g)}`),f.warn("You can set it up later using: oracles-cli setup-encryption-key")}await oe({baseUrl:o,accessToken:s,userId:n.matrixUserId,deviceId:""});let x=kr();x.start("Creating Entity Matrix Room..."),x.stop("Room created -- room joined"),f.warn("Please save the following information in a secure location as it is not stored:"),f.info("ORACLE ACCOUNT DETAILS");for(let g in n)f.info(`${g}: ${n[g]}`);return this.config.addValue("registerUserResult",n),this.config.addValue("entityDid",d),this.config.addValue("oracleMatrixHomeServerUrl",t),f.info("Submitting domain card to domain indexer"),await this.submitToDomainIndexer(d),d}};var V=class{constructor(e,t){this.wallet=e;this.config=t}name="create-entity";description="Create an entity";async execute(){this.config.getValue("network")||await S(this.config);let t=this.wallet.matrixHomeServer??X[this.config.getValue("network")??"devnet"],i=await w.group({matrixHomeServerUrl:()=>w.text({message:"Matrix homeserver URL for the oracle:",initialValue:t,defaultValue:t,validate(c){return ee(c)}}),oracleName:()=>w.text({message:"What is the name of the oracle?",initialValue:"My oracle",validate(c){return b(c,"Oracle name is required")}}),oraclePrice:()=>w.text({message:"What is the price of the oracle in IXO CREDITS?",initialValue:"100",validate(c){return Ye(parseInt(c??""),"Oracle price is required and must be a number")}}),profile:()=>w.group({orgName:()=>w.text({message:"What is the name of the organization?",initialValue:"IXO",validate(c){return b(c,"Organization name is required")}}),name:()=>w.text({message:"What is the name of the profile?",initialValue:"My oracle",validate(c){return b(c,"Profile name is required")}}),logo:({results:c})=>w.text({message:"What is the logo of the profile?",initialValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${c?.name??"IXO"}`,defaultValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${c?.name??"IXO"}`,validate(l){return l?B(l,"Logo is required or a valid URL"):`https://api.dicebear.com/8.x/bottts/svg?seed=${c?.name??"IXO"}`}}),coverImage:({results:c})=>w.text({message:"What is the cover image of the profile?",initialValue:c.logo,defaultValue:c.logo,validate(l){return l?B(l,"Cover image is required or a valid URL"):c.logo}}),location:()=>w.text({message:"What is the location of your domain?",initialValue:"New York, NY",validate(c){return b(c,"Location is required")}}),description:()=>w.text({message:"What is the description of the entity (profile)?",initialValue:"We are a company that helps you with daily tasks",validate(c){return b(c,"Description is required")}}),url:()=>w.text({message:"What is the website URL of the oracle? (optional, press Enter to skip)",placeholder:"https://your-oracle-website.com"})}),parentProtocol:()=>w.select({message:"What is the parent protocol of the entity?",options:[{value:"did:ixo:entity:1a76366f16570483cea72b111b27fd78",label:"IXO Oracle Protocol",hint:"default protocol"}],initialValue:"did:ixo:entity:1a76366f16570483cea72b111b27fd78"}),apiUrl:()=>w.text({message:"What is the API URL of the oracle?",initialValue:"http://localhost:4000",validate(c){return B(c,"API URL is required or a valid URL")}})},{onCancel:()=>{w.cancel("Operation cancelled."),process.exit(0)}}),o=await new D(this.wallet,this.config).execute({oracleConfig:{oracleName:i.oracleName,price:parseInt(i.oraclePrice)},profile:{orgName:i.profile.orgName,name:i.profile.name,logo:i.profile.logo,coverImage:i.profile.coverImage,location:i.profile.location,description:i.profile.description,...i.profile.url?{url:i.profile.url}:{}},services:[{id:"{id}#api",serviceEndpoint:i.apiUrl,type:"oracleService"},{id:"{id}#ws",serviceEndpoint:i.apiUrl,type:"wsService"}],parentProtocol:i.parentProtocol,matrixHomeServerUrl:i.matrixHomeServerUrl});w.log.info(`API for the oracle is: ${i.apiUrl} | You can change this after you deploy the oracle`);let a=`${Ge[this.config.getValue("network")??"devnet"]}/oracle/${o}/overview`;return w.log.info(`Oracle created successfully: ${o}`),w.log.info(`Oracle URL: ${a}`),{success:!0,data:`Entity created successfully: ${o}`}}};import*as A from"@clack/prompts";var de=class{constructor(e,t){this.wallet=e;this.config=t}name="create-user";description="Create a new user";async execute(){let e=this.config.getValue("network");e||await S(this.config);let t=this.wallet.matrixHomeServer??X[this.config.getValue("network")??"devnet"],i=await A.text({message:"Matrix homeserver URL:",initialValue:t,defaultValue:t,validate(a){return ee(a)}});A.isCancel(i)&&(A.log.error("User cancelled"),process.exit(1));let n=await A.text({message:"Enter a 6-digit PIN to secure your Matrix Vault:",placeholder:"123456",validate(a){return j(a)}});A.isCancel(n)&&(A.log.error("User cancelled"),process.exit(1));let o=await A.text({message:"Enter your oracle name",initialValue:"My oracle",validate(a){return b(a,"Oracle name is required")}});A.isCancel(o)&&(A.log.error("User cancelled"),process.exit(1));let s=await se({pin:n,oracleName:o,network:this.config.getValue("network")??e,oracleAvatarUrl:`https://api.dicebear.com/8.x/bottts/svg?seed=${o}`,matrixHomeServerUrl:i},async a=>{await this.wallet.sendTokens(a,15e4)});return await oe({baseUrl:s.matrixHomeServerUrl,accessToken:s.matrixAccessToken,userId:s.matrixUserId,deviceId:""}),{success:!0,data:s}}};var z=class{constructor(e){this.registry=e}name="help";description="Show help information and available commands";async execute(){return{success:!0,data:`
2
+ import{cancel as Qe,intro as Ci,isCancel as ar,log as Z,outro as Ri,select as cr,spinner as Ei}from"@clack/prompts";import q from"process";var se=class{commands;constructor(){this.commands=new Map}register(e){this.commands.set(e.name,e)}get(e){return this.commands.get(e)}getAll(){return Array.from(this.commands.values())}getCommandOptions(){return this.getAll().map(e=>({value:e.name,label:e.name,hint:e.description}))}};import*as A from"@clack/prompts";import*as tt from"@clack/prompts";function Me(r){process.stdout.write(r)}function rt(r,e){process.stdout.write(`\x1B[2m[Tool] ${r}(${e})\x1B[0m
3
+ `)}function _(r){tt.log.error(r)}function it(){process.stdout.write(`
4
+ `)}function nt(r,e,t,i){console.log(),console.log(`\x1B[1m${r}\x1B[0m by ${e}`),console.log(`\x1B[2m${t}\x1B[0m`),console.log(),console.log(`\x1B[2mSession: ${i}\x1B[0m`),console.log("\x1B[2mType 'exit' to quit\x1B[0m"),console.log()}import{select as pr}from"@clack/prompts";import{z as H}from"zod";var T=async r=>{let e=await pr({message:"Select network: (default: devnet)",options:[{value:"mainnet",label:"Mainnet"},{value:"testnet",label:"Testnet"},{value:"devnet",label:"Devnet"}],initialValue:"devnet",maxItems:1});return r.addValue("network",e),e},ot={mainnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d",testnet:"did:ixo:entity:3d079ebc0b332aad3305bb4a51c72edb",devnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d"},K={devnet:"https://devmx.ixo.earth",testnet:"https://testmx.ixo.earth",mainnet:"https://mx.ixo.earth"},st={devnet:"https://rooms.bot.devmx.ixo.earth",testnet:"https://rooms.bot.testmx.ixo.earth",mainnet:"https://rooms.bot.mx.ixo.earth"};var at={devnet:"https://ixo-portal.vercel.app",testnet:"https://ixo-portal.vercel.app",mainnet:"https://ixo-portal.vercel.app"},W={mainnet:"https://impacthub.ixo.world/rpc/",testnet:"https://testnet.ixo.earth/rpc/",devnet:"https://devnet.ixo.earth/rpc/"},ee={devnet:"https://domain-indexer.devnet.ixo.earth/index",testnet:"https://domain-indexer.testnet.ixo.earth/index",mainnet:"https://domain-indexer.ixo.earth/index"},te={devnet:"https://devnet-blocksync-graphql.ixo.earth/graphql",testnet:"https://testnet-blocksync-graphql.ixo.earth/graphql",mainnet:"https://blocksync-graphql.ixo.earth/graphql"},_e={devnet:"https://mcp-memory-engine.devnet.ixo.earth/",testnet:"https://memory-engine.testnet.ixo.earth/",mainnet:"https://memory-engine.ixo.earth/"},De={devnet:"https://mcp-memory-engine.devnet.ixo.earth/",testnet:"https://mcp-memory-engine.testnet.ixo.earth/",mainnet:"https://mcp-memory-engine.ixo.earth/"},$e={devnet:"https://ai-sandbox-devnet.ixo.earth/mcp",testnet:"https://ai-sandbox-testnet.ixo.earth/mcp",mainnet:"https://ai-sandbox.ixo.earth/mcp"},Le={devnet:"https://subscriptions-api.ixo-api.workers.dev",testnet:"https://subscriptions-api-testnet.ixo-api.workers.dev/",mainnet:"https://subscriptions-api-mainnet.ixo-api.workers.dev/"},P=(r,e="This field is required")=>{let i=H.string().min(1,e).safeParse(r);if(!i.success)return i.error.message},D=r=>{let t=H.string().regex(/^did:ixo:entity:[a-f0-9]{32}$/,"Invalid entity DID").safeParse(r);if(!t.success)return t.error.message},j=(r,e="This url is required or a valid URL")=>{let i=H.url(e).safeParse(r);if(!i.success)return i.error.message},ct=(r,e="This number is required")=>{let i=H.number().min(1,e).safeParse(r);if(!i.success)return i.error.message},G=r=>{let t=H.string().min(1,"PIN is required").refine(i=>/^\d{6}$/.test(i),"PIN must be exactly 6 digits").safeParse(r);if(!t.success)return t.error.issues[0]?.message??"Invalid PIN"},ae=r=>{let t=H.string().min(1,"Matrix homeserver URL is required").refine(i=>/^https?:\/\//.test(i),"Must start with http:// or https://").refine(i=>!i.endsWith("/"),"Must not end with a trailing slash").safeParse(r);if(!t.success)return t.error.issues[0]?.message??"Invalid Matrix URL"};function lt(r){let e=new URL(r),t=e.hostname,i=e.protocol;return{homeServerUrl:r,roomBotUrl:`${i}//rooms.bot.${t}`,stateBotUrl:`${i}//state.bot.${t}`,bidsBotUrl:`${i}//bids.bot.${t}`,claimsBotUrl:`${i}//claims.bot.${t}`}}import{log as X}from"@clack/prompts";async function re(r,e,t){let i=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json",...t},body:JSON.stringify(e)});if(!i.ok){let n=await i.text();if(i.status===403||n.includes("already in the room")||n.includes("already joined"))return{};throw new Error(`Request failed (${i.status}): ${n.slice(0,200)}`)}return await i.json()}async function dt({userDid:r,oracleEntityDid:e,matrixAccessToken:t,network:i}){let n=st[i],o=K[i];if(!n||!o)throw new Error(`Unknown network: ${i}`);let s={Authorization:`Bearer ${t}`};X.info(`User DID: ${r}`),X.info(`Oracle Entity DID: ${e}`),X.step("Sourcing Matrix space...");let c=await re(`${n}/spaces/source`,{did:r}),m=Object.values(c.subspaces??{}).map(a=>a.space_id).filter(Boolean);X.step("Joining main space..."),await re(`${o}/_matrix/client/v3/join/${c.space_id}`,{},s),m.length>0&&(X.step(`Joining ${m.length} sub-space(s)...`),await Promise.all(m.map(a=>re(`${o}/_matrix/client/v3/join/${a}`,{},s)))),X.step("Creating oracle room...");let d=await re(`${n}/spaces/oracle/create`,{did:r,oracleDid:e},s);X.step(`Joining oracle room: ${d.roomId}`),await re(`${o}/_matrix/client/v3/join/${d.roomId}`,{},s),X.success("Matrix room ready")}async function mt(r,e,t){let i=encodeURIComponent(e),n=`${r}/_matrix/client/v3/user/${i}/openid/request_token`,o=await fetch(n,{method:"POST",headers:{Authorization:`Bearer ${t}`,"Content-Type":"application/json"},body:"{}",signal:AbortSignal.timeout(3e4)});if(!o.ok){let s=await o.text();throw new Error(`Failed to get OpenID token (${o.status}): ${s}`)}return await o.json()}async function pt(r,e){let t=await fetch(`${r}/sessions`,{method:"POST",headers:{"Content-Type":"application/json","x-matrix-access-token":e},signal:AbortSignal.timeout(3e4)});if(!t.ok){let i=await t.text();throw new Error(`Failed to create session (${t.status}): ${i}`)}return await t.json()}async function gt(r,e,t){await fetch(`${r}/sessions/${encodeURIComponent(e)}`,{method:"DELETE",headers:{"x-matrix-access-token":t},signal:AbortSignal.timeout(3e4)})}async function ut(r,e,t,i,n){let o={method:"POST",headers:{"Content-Type":"application/json","x-matrix-access-token":i},body:JSON.stringify({message:t,stream:!0})};n&&(o.signal=n);let s=await fetch(`${r}/messages/${encodeURIComponent(e)}`,o);if(!s.ok){let c=await s.text();throw new Error(`Failed to send message (${s.status}): ${c}`)}if(!s.body)throw new Error("Response body is empty");return s.body}async function ft(r){try{return(await fetch(r,{signal:AbortSignal.timeout(5e3)})).ok}catch{return!1}}import{existsSync as Ke,readFileSync as gr,writeFileSync as ur}from"fs";import J from"path";import{z as O}from"zod";var fr=O.object({oracleName:O.string(),orgName:O.string(),description:O.string(),location:O.string(),website:O.string(),price:O.number(),apiUrl:O.url(),network:O.string(),entityDid:O.string().regex(/^did:ixo:entity:[a-f0-9]{32}$/),logo:O.string()});function ht(r,e){let t=J.join(r,"oracle.config.json");ur(t,JSON.stringify(e,null,2),"utf8")}function yt(r){let e=r??hr();if(!e)return;let t=J.join(e,"oracle.config.json");if(Ke(t))try{let i=gr(t,"utf8"),n=fr.safeParse(JSON.parse(i));return n.success?n.data:void 0}catch{return}}function hr(){let r=process.cwd(),e=J.parse(r).root;for(;r!==e;){if(Ke(J.join(r,"oracle.config.json"))||Ke(J.join(r,"pnpm-workspace.yaml")))return r;r=J.dirname(r)}}async function*wt(r){let e=new TextDecoder,t=r.getReader(),i="";try{for(;;){let{done:n,value:o}=await t.read();if(n)break;i+=e.decode(o,{stream:!0});let s=i.split(`
5
+
6
+ `);i=s.pop()??"";for(let c of s){let m=c.trim();if(!m||m.startsWith(": heartbeat")||m===":")continue;let d="message",a=[];for(let g of m.split(`
7
+ `))g.startsWith("event:")?d=g.slice(6).trim():g.startsWith("data:")&&a.push(g.slice(5).trim());if(a.length===0)continue;let l=a.join(`
8
+ `),u;try{u=JSON.parse(l)}catch{u=l}yield{event:d,data:u}}}}finally{t.releaseLock()}}var ce=class{constructor(e,t){this.wallet=e;this.config=t}name="chat";description="Chat with your oracle";interactive=!0;openIdToken;openIdTokenExpiresAt=0;abortController;async ensureOpenIdToken(){let e=Date.now();if(!this.openIdToken||e>=this.openIdTokenExpiresAt-3e4){let t=this.wallet.matrix;if(!t?.userId||!t.accessToken)throw new Error("Matrix credentials not found. Please log in first.");let i=this.wallet.matrixHomeServer;if(!i)throw new Error("Cannot determine Matrix homeserver URL from wallet.");this.openIdToken=await mt(i,t.userId,t.accessToken),this.openIdTokenExpiresAt=e+this.openIdToken.expires_in*1e3}return this.openIdToken.access_token}async execute(){let e=yt(),t,i="Oracle",n="",o="",s=e?.entityDid;if(e)t=e.apiUrl,i=e.oracleName||"Oracle",n=e.orgName||"",o=e.description||"";else{let g=await A.text({message:"Oracle API URL:",initialValue:"http://localhost:3000",validate:x=>j(x)});if(A.isCancel(g))return A.cancel("Operation cancelled."),{success:!1,error:"Cancelled"};t=g;let p=await A.text({message:"Oracle Entity Did:",initialValue:"did:ixo:entity:bc0f10e6f77ec9281ea64020ee085864",validate:x=>D(x)});if(A.isCancel(p))return A.cancel("Operation cancelled."),{success:!1,error:"Cancelled"};s=p}if(!await ft(t))return _(`Cannot reach oracle at ${t}. Is it running?`),{success:!1,error:`Oracle not reachable at ${t}`};let m=this.wallet.did,d=this.wallet.matrix?.accessToken,a=this.config.getValue("network");if(!m||!d||!a||!s){let g=Object.entries({userDid:m,matrixAccessToken:d,network:a,oracleEntityDid:s}).filter(([,p])=>!p).map(([p])=>p);return _(`Missing required values: ${g.join(", ")}`),{success:!1,error:`Missing required values: ${g.join(", ")}`}}try{await dt({userDid:m,oracleEntityDid:s,matrixAccessToken:d,network:a})}catch(g){let p=g instanceof Error?g.message:String(g);return _(`Matrix room setup failed: ${p}`),{success:!1,error:p}}let l;try{l=await this.ensureOpenIdToken()}catch(g){let p=g instanceof Error?g.message:String(g);return _(`Authentication failed: ${p}`),{success:!1,error:p}}let u;try{u=(await pt(t,l)).sessionId}catch(g){let p=g instanceof Error?g.message:String(g);return _(`Failed to create session: ${p}`),{success:!1,error:p}}nt(i,n,o,u);try{for(;;){let g=await A.text({message:`${i} >`});if(A.isCancel(g))break;let p=g.trim();if(p){if(p.toLowerCase()==="exit")break;try{l=await this.ensureOpenIdToken()}catch(x){let C=x instanceof Error?x.message:String(x);_(`Token refresh failed: ${C}`);continue}try{this.abortController=new AbortController;let x=await ut(t,u,p,l,this.abortController.signal);for await(let C of wt(x))switch(C.event){case"message":case"on_chat_model_stream":{let I=C.data,R=typeof I=="string"?I:I?.content??I?.text;R&&Me(String(R));break}case"on_tool_start":{let I=C.data,R=I?.name??I?.tool??"unknown",N=typeof I?.args=="string"?I.args:JSON.stringify(I?.args??I?.input??{});rt(R,N);break}case"error":{let I=typeof C.data=="string"?C.data:C.data?.message??JSON.stringify(C.data);_(I);break}case"end":case"done":break;default:{typeof C.data=="string"&&Me(C.data);break}}it()}catch(x){process.stdout.write(`
9
+ `);let C=x instanceof Error?x.message:String(x);_(C)}finally{this.abortController=void 0}}}}finally{this.abortController?.abort();try{try{l=await this.ensureOpenIdToken()}catch{}await gt(t,u,l)}catch{}}return A.log.info("Goodbye!"),{success:!0}}};import*as v from"@clack/prompts";import{isCancel as ii,log as w,spinner as ni,text as oi}from"@clack/prompts";import{customMessages as tr,ixo as E,utils as Ge}from"@ixo/impactxclient-sdk";import{sha256 as Nr}from"@cosmjs/crypto";import{encrypt as Ur}from"eciesjs";import{ClientEvent as Mr,createClient as Be}from"matrix-js-sdk";import _r from"md5";var le=new Map;function yr(r){return le.get(r)instanceof Uint8Array}function wr(r){return le.get(r)}function We(){le.clear()}async function xt({keys:r}){let e=Object.keys(r),t=e.find(yr);if(console.info("[] getSecretStorageKey",r,e,t),!t)return null;let i=wr(t);return[t,i]}function vt(r,e,t){le.set(r,t)}import{Bip39 as St,EnglishMnemonic as It,Secp256k1 as je,sha256 as Cr,Slip10 as bt,Slip10Curve as At,stringToPath as Tt}from"@cosmjs/crypto";import{DirectSecp256k1HdWallet as Rr}from"@cosmjs/proto-signing";import{createQueryClient as kt,createSigningClient as Er,customMessages as Sr,ixo as Ir,utils as br}from"@ixo/impactxclient-sdk";import{createCipheriv as Ar,randomBytes as Tr}from"crypto";import{createRegistry as xr,utils as vr}from"@ixo/impactxclient-sdk";function ie(r){try{return vr.proto.fromTimestamp(r).getTime()}catch{return}}var de={BasicAllowance:"/cosmos.feegrant.v1beta1.BasicAllowance",PeriodicAllowance:"/cosmos.feegrant.v1beta1.PeriodicAllowance"},Ct=r=>{let e=xr();return(r??[]).map(t=>{let i=t.allowance,n=e.decode(i);switch(i.typeUrl){case de.BasicAllowance:return{granter:t.granter,grantee:t.grantee,type:de.BasicAllowance,expiration:n.expiration?ie(n.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};case de.PeriodicAllowance:return{granter:t.granter,grantee:t.grantee,type:de.PeriodicAllowance,expiration:n.basic?.expiration?ie(n.basic.expiration):null,limit:n?.periodCanSpend?n?.periodCanSpend?.find(o=>o.denom==="uixo")?.amount:n?.basic?.spendLimit?.length?n?.basic?.spendLimit?.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};default:return{type:i.typeUrl,granter:t.granter,grantee:t.grantee,expiration:n.expiration?ie(n.expiration):n.basic?.expiration?ie(n.basic.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:n?.periodCanSpend?n?.periodCanSpend?.find(o=>o.denom==="uixo")?.amount:n?.basic?.spendLimit?.length?n?.basic?.spendLimit?.find(o=>o.denom==="uixo")?.amount:null,msgs:n.allowedMessages}}})},Rt=r=>{if(r==null)return!1;let e=typeof r=="object"?ie(r):r;return e==null?!0:e<Date.now()},Et=r=>r==null?!1:(typeof r=="object"?Number(r?.amount??0):typeof r=="string"?Number(r??0):r)<=5e-4;async function Xe(r,e){if(!e)throw new Error("Network parameter is required but was undefined");console.log(`\u{1F50D} Checking IID document for DID: ${r} on network: ${e}`);let t=W[e];if(!t)throw new Error(`Invalid network: ${e}. Valid networks are: ${Object.keys(W).join(", ")}`);console.log(`\u{1F517} Using RPC URL: ${t}`);try{return!!(await(await kt(t)).ixo.iid.v1beta1.iidDocument({id:r}))?.iidDocument?.id}catch(i){if(i.message?.includes("did document not found")||i.message?.includes("(22)"))return!1;throw console.error("Error checking IID document:",i),i}}async function Pt(r,e,t,i){try{let n=await t.getAccounts(),{address:o,pubkey:s}=n[0]??{},c=await kr(o,e),m=c?.length?Ct(c)?.find(a=>!!a&&!Rt(a.expiration)&&!Et(a.limit))?.granter:void 0,d={typeUrl:"/ixo.iid.v1beta1.MsgCreateIidDocument",value:Ir.iid.v1beta1.MsgCreateIidDocument.fromPartial({id:r,verifications:Sr.iid.createIidVerificationMethods({did:r,pubkey:s,address:o,controller:r,type:"secp"}),signer:o,controllers:[r],...i?.length?{services:i}:{}})};await Pr({offlineSigner:t,messages:[d],feegrantGranter:m,network:e})}catch(n){throw console.error(n),n}}async function kr(r,e){try{let t=W[e];if(!t)throw new Error(`Invalid network: ${e}`);return(await(await kt(t)).cosmos.feegrant.v1beta1.allowances({grantee:r}))?.allowances??[]}catch(t){console.error("queryAddressAllowances::",t.message);return}}var Pr=async({offlineSigner:r,messages:e,memo:t="Signing with Mnemonic Demo",feegrantGranter:i,network:n})=>{let o=W[n];if(!o)throw new Error(`Invalid network: ${n}`);let s=await Er(o,r),c=await r.getAccounts(),{address:m}=c[0]??{},d=await s.simulate(m,e,t),l=(d>5e4?d:(e??[]).length*5e5)*1.7,u=Or(l),g={amount:[{denom:"uixo",amount:String(Math.round(u.average))}],gas:String(Math.round(l)),granter:i},p=await s.signAndBroadcast(m,e,g,t,void 0);if(!!p.code)throw new Error(`Error when broadcasting tx ${p.transactionHash} at height ${p.height}. Code: ${p.code}; Raw log: ${p.rawLog}`)},Or=r=>{let e={low:.02,average:.035,high:.045},t=r<.01?.01:r;return{low:t*e.low,average:t*e.average,high:t*e.high}},me=r=>new Promise(e=>setTimeout(e,r));function pe(r,e){let t=Tr(16),i=Ar("aes-256-cbc",Buffer.from(e.padEnd(32)),t),n=i.update(r);return n=Buffer.concat([n,i.final()]),t.toString("hex")+":"+n.toString("hex")}var Ot=async r=>{let e=await Rr.fromMnemonic(r,{prefix:"ixo"}),t=(await e.getAccounts())[0],i=await St.mnemonicToSeed(new It(r)),n=Tt("m/44'/118'/0'/0/0"),s=bt.derivePath(At.Secp256k1,i,n).privkey,c=await je.makeKeypair(s),m=je.compressPubkey(c.pubkey);return{mnemonic:r,did:br.did.generateSecpDid(t.address),baseAccount:t,async getAccounts(){return await e.getAccounts()},async signDirect(a,l){return await e.signDirect(a,l)},async sign(a){try{let l=await St.mnemonicToSeed(new It(r)),u=Tt("m/44'/118'/0'/0/0"),{privkey:g}=bt.derivePath(At.Secp256k1,l,u),p=new Uint8Array(Buffer.from(a,"base64")),x=Cr(p);return(await je.createSignature(x,g)).toFixedLength().slice(0,64)}catch(l){throw console.error("Error during signature creation:",l),l}}}};var Dr="/.well-known/matrix/client",$r=async({homeServerUrl:r,username:e,password:t,deviceName:i},n=!1)=>{let o=r,s=e,c=s.match(/^@(.+):(.+\..+)$/);c&&(s=c[1],o=c[2],o=n?o:await Xt(o));try{let m=_t(o),d=await m.login("m.login.password",{identifier:{type:"m.id.user",user:Bt(s)},password:t,initial_device_display_name:i});return{accessToken:d.access_token,deviceId:d.device_id,userId:d.user_id,baseUrl:n?o:d?.well_known?.["m.homeserver"]?.base_url||m.baseUrl}}catch(m){let d=m.message;throw d==="Unknown message"&&(d="Please check your credentials"),console.error("mxLogin::",d),new Error(d)}},Nt=async({homeServerUrl:r,username:e,password:t})=>{let i=r,n=e,o=n.match(/^@(.+):(.+\..+)$/);o&&(n=o[1],i=o[2],i=await Xt(i));let s=await fetch(`${i}/_matrix/client/v3/login`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:"m.login.password",identifier:{type:"m.id.user",user:Bt(n)},password:t,initial_device_display_name:"Oracle Service"})});if(!s.ok){let m=await s.json().catch(()=>({}));throw new Error(`Matrix login failed: ${m.error||s.statusText}`)}let c=await s.json();return{accessToken:c.access_token,userId:c.user_id,deviceId:c.device_id}};async function Lr(r){let e=await fetch(`${r}/public-key`,{method:"GET",headers:{"Content-Type":"application/json"}});if(!e.ok)throw new Error("Failed to fetch public key for encryption");return await e.json()}function Kr(r){let e={timestamp:new Date().toISOString(),address:r,service:"matrix",type:"create-account"},t=Buffer.from(JSON.stringify(e)).toString("base64");return{challenge:e,challengeBase64:t}}function Wr(r,e){let t=new Uint8Array(Buffer.from(e,"hex")),i=new Uint8Array(Buffer.from(r,"utf8")),n=Ur(t,i);return Array.from(n,o=>o.toString(16).padStart(2,"0")).join("")}async function jr(r,e,t,i,n,o){let s=await Lr(o),c=Wr(e,s.publicKey),m={address:r,encryptedPassword:c,publicKeyFingerprint:s.fingerprint,secpResult:{signature:t,challenge:i}},d=await fetch(`${o}/user/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(m)});if(!d.ok){let a=await d.text(),l=`Failed to create user account (HTTP ${d.status})`;try{let u=JSON.parse(a);l=u.error||u.message||u.detail||a}catch{l=a||l}throw console.error(`Room bot error [${d.status}]: ${a}`),new Error(l)}return await d.json()}async function Ut(r,e,t,i,n,o){try{let{challengeBase64:s}=Kr(r),c=await i.sign(s),m=Buffer.from(c).toString("base64");if(!(await jr(r,e,m,s,n,o)).success)throw new Error("Failed to create matrix account via API");let a=Ve(r);return await $r({homeServerUrl:n,username:a,password:e,deviceName:t})}catch(s){throw console.error("mxRegisterWithSecp error:",s),s}}async function Mt({homeServerUrl:r,username:e}){let t=_t(r);try{return!!await t.isUsernameAvailable(e)}catch{return!1}}function _t(r){if(!r)throw new Error("Home server URL is required to instantiate matrix client");return Be({baseUrl:r})}async function Dt({homeServerUrl:r,accessToken:e,userId:t,deviceId:i}){if(console.log("createMatrixClient::",{homeServerUrl:r,accessToken:e,userId:t,deviceId:i}),!r||!e||!t||!i)throw new Error("Login to Matrix account before trying to instantiate Matrix client.");let n=Be({baseUrl:r,accessToken:e,userId:t,deviceId:i,timelineSupport:!0,cryptoCallbacks:{getSecretStorageKey:xt,cacheSecretStorageKey:vt},verificationMethods:["m.sas.v1"]});return await n.initRustCrypto({useIndexedDB:!1}),n.setMaxListeners(20),await n.startClient({lazyLoadMembers:!0,includeArchivedRooms:!1}),await new Promise((o,s)=>{let c={NULL:()=>{console.info("[NULL] state")},SYNCING:()=>{},PREPARED:()=>{console.info(`[PREPARED] state: user ${t}`),o()},RECONNECTING:()=>{console.info("[RECONNECTING] state")},CATCHUP:()=>{console.info("[CATCHUP] state")},ERROR:()=>{s(new Error("[ERROR] state: starting matrix client"))},STOPPED:()=>{console.info("[STOPPED] state")}};n.on(Mr.Sync,m=>{c[m]()})}),n}async function ge({mxClient:r,baseUrl:e,accessToken:t,userId:i,deviceId:n}){let o=r;o||(o=Be({baseUrl:e,accessToken:t,userId:i,deviceId:n})),o&&(o.stopClient(),await o.logout().catch(console.error),o.clearStores())}function $t(r){let e=r.getAccountData("m.cross_signing.master");return console.log("hasCrossSigningAccountData::masterKeyData",e),!!e}async function Lt(r,{securityPhrase:e,password:t,forceReset:i=!1,skipBootstrapSecureStorage:n=!1}){i&&We();let o=r.getCrypto();if(!o)throw new Error("Failed to setup matrix cross signing - failed to get matrix crypto api");if(!n){let c=await o.createRecoveryKeyFromPassphrase(e);We(),await o.bootstrapSecretStorage({createSecretStorageKey:async()=>c,setupNewSecretStorage:i})}let s=r.getUserId();return await o.bootstrapCrossSigning({authUploadDeviceSigningKeys:async function(c){await c(Vr({userId:s,password:t}))},setupNewCrossSigning:i}),await o.resetKeyBackup(),await me(300),!!r.getAccountData("m.cross_signing.master")}function Ve(r){if(!r)throw new Error("Address is required to generate matrix username");return"did-ixo-"+r}function Kt(r){return Buffer.from(_r(r.replace(/ /g,""))).toString("base64").slice(0,24)}function Wt(r){let e=Nr(new TextEncoder().encode(r.replace(/ /g,"")));return Buffer.from(e).toString("base64").slice(0,32)}function Xr(r){return r.replace(/^(https?:\/\/)/,"").replace(/\/$/,"")}function Br(r,e=""){return"did-ixo-"+r+e}function jt(r,e){return"#"+Br(r)+":"+Xr(e)}async function Xt(r){let e="https://";/^https?:\/\//.test(r)&&(e="");let t=`${e}${r}${Dr}`;try{let o=(await(await fetch(t,{method:"GET"})).json())["m.homeserver"]?.base_url;if(o===void 0)throw new Error;return o}catch{return`${e}${r}`}}function Bt(r){return(r.indexOf("@")===0?r.substring(1):r).trim()}function Vr({userId:r,password:e}){return{type:"m.login.password",password:e,identifier:{type:"m.id.user",user:r}}}import{ixo as Fr,utils as Fe}from"@ixo/impactxclient-sdk";import{createMatrixApiClient as qr}from"@ixo/matrixclient-sdk";var Vt="Oracles CLI";async function ue({pin:r,oracleName:e,network:t,oracleAvatarUrl:i,matrixHomeServerUrl:n},o){try{let{homeServerUrl:s,roomBotUrl:c}=lt(n),m=Fe.mnemonic.generateMnemonic(),d=await Ot(m),a=d.baseAccount.address;console.log("\u2705 Wallet created:",a),await o(a);let l=Fe.did.generateSecpDid(a),u=await Xe(l,t);if(console.log("\u2705 DID exists:",u),!u){console.log("\u2705 DID does not exist, creating...");let V=Fr.iid.v1beta1.Service.fromPartial({id:`${l}#matrix`,type:"MatrixHomeServer",serviceEndpoint:s});if(await Pt(l,t,d,[V]),console.log("\u2705 DID created, waiting 500ms..."),await me(500),console.log("\u2705 Checking if DID exists..."),!await Xe(l,t))throw new Error("Failed to create DID document")}console.log("\u2705 DID created:",l);let g=Fe.mnemonic.generateMnemonic(12),p=Ve(a),x=Kt(g),C=Wt(g);if(!await Mt({homeServerUrl:s,username:p}))throw new Error("Matrix account already exists");let R=await Ut(a,x,Vt,d,s,c);if(!R?.accessToken)throw new Error("Failed to register matrix account");console.log("\u2705 Matrix account created:",R.userId);let N=await Dt({homeServerUrl:s,accessToken:R.accessToken,userId:R.userId,deviceId:R.deviceId});try{await Promise.all([N.setDisplayName(e),N.setAvatarUrl(i)])}catch(V){console.error("Failed to set display name or avatar url:",V)}let U=qr({homeServerUrl:s,accessToken:R.accessToken}),Oe=$t(N);if(!Oe&&(Oe=await Lt(N,{securityPhrase:C,password:x,forceReset:!0}),!Oe))throw new Error("Failed to setup cross signing");console.log("\u2705 Matrix cross-signing setup completed");let lr=jt(a,R.baseUrl),M=(await U.room.v1beta1.queryId(lr).catch(()=>{}))?.room_id??"";if(!M){let V=await fetch(`${c}/room/source`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({did:l,userMatrixId:R.userId})});if(!V.ok)throw new Error("Failed to create matrix room");if(M=(await V.json()).roomId,!M)throw new Error("Failed to create user matrix room")}let Ne=await U.room.v1beta1.listJoinedMembers(M).catch(()=>{}),Ue=!!Ne?.joined?.[R.userId];if(!Ue){if(!(await U.room.v1beta1.join(M)).room_id)throw new Error("Failed to join matrix room");if(Ne=await U.room.v1beta1.listJoinedMembers(M),Ue=!!Ne?.joined?.[R.userId],!Ue)throw new Error("Failed to join matrix room")}console.log("\u2705 Matrix room created/joined:",M);let dr=pe(g,r),et=await fetch(`${s}/_matrix/client/v3/rooms/${M}/state/ixo.room.state.secure/encrypted_mnemonic`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${R.accessToken}`},body:JSON.stringify({encrypted_mnemonic:dr})});if(!et.ok)throw new Error("Failed to store encrypted mnemonic in matrix room");return await et.json(),console.log("\u2705 Encrypted Matrix mnemonic stored in room"),N.stopClient(),{address:a,did:l,mnemonic:m,matrixUserId:R.userId,matrixRoomId:M,matrixMnemonic:g,matrixPassword:x,matrixAccessToken:R.accessToken,matrixRecoveryPhrase:C,matrixHomeServerUrl:s,pin:r,matrixDeviceName:Vt}}catch(s){throw console.error("Simplified registration failed:",s),s}}import{ixo as qe}from"@ixo/impactxclient-sdk";import Hr from"bs58";import{randomUUID as qt}from"crypto";import{exportJWK as Ft,generateKeyPair as Gr}from"jose";var Ht="ixo.room.encryption_key.index",Gt="p256_encryption",Jr="ixo.room.encryption_key";function Yr(r){let e=Buffer.from(r.x,"base64url"),t=Buffer.from(r.y,"base64url"),i=new Uint8Array(33);return i[0]=(t[t.length-1]&1)===0?2:3,i.set(e,1),i}function zr(r){let e=new Uint8Array(2+r.length);return e[0]=128,e[1]=36,e.set(r,2),"z"+Hr.encode(e)}async function He(r,e,t){let i=await fetch(`${t}/_matrix/client/v3/rooms/${encodeURIComponent(r)}/state/${Ht}/${Gt}`,{headers:{Authorization:`Bearer ${e}`}});if(i.status===404)return null;if(!i.ok)throw new Error(`Failed to read encryption key index (status ${i.status}): ${await i.text()}`);return await i.json()}async function Qr(r,e,t,i){let n=`enc_key_${qt()}`,o=await fetch(`${t}/_matrix/client/v3/rooms/${encodeURIComponent(r)}/send/${Jr}/${n}`,{method:"PUT",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify({encrypted_private_key:i})});if(!o.ok)throw new Error(`Failed to store encryption key timeline event: ${o.statusText}`);let s=await o.json();if(!s?.event_id)throw new Error("No event_id returned from timeline event send");return s.event_id}async function Jt(r,e,t,i){let n=await fetch(`${t}/_matrix/client/v3/rooms/${encodeURIComponent(r)}/state/${Ht}/${Gt}`,{method:"PUT",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json"},body:JSON.stringify(i)});if(!n.ok)throw new Error(`Failed to write encryption key state index: ${n.statusText}`)}function Yt(r){let e=r.indexOf(":");if(e===-1||!r.startsWith("!"))throw new Error(`Invalid Matrix room ID format: ${r}. Expected !roomId:server (e.g. !abc123:devmx.ixo.earth)`);return`https://${r.slice(e+1)}`}async function zt(r,e,t){let i=await He(r,e,t);return i?.keys?Object.values(i.keys).some(n=>n.active):!1}async function fe(r){let{roomId:e,accessToken:t,homeServerUrl:i,pin:n,oracleEntityDid:o}=r,s=await He(e,t,i);if(s?.keys){let N=Object.entries(s.keys).find(([,U])=>!U.active&&U.publicKeyMultibase);if(N){let[,U]=N;return{publicKeyMultibase:U.publicKeyMultibase,verificationMethodId:U.didVerificationMethodId}}}let c=qt(),{privateKey:m,publicKey:d}=await Gr("ECDH-ES",{crv:"P-256",extractable:!0}),a=await Ft(m);a.alg="ECDH-ES+A256KW";let l=await Ft(d);l.alg="ECDH-ES+A256KW";let u=pe(JSON.stringify(a),n),g=await Qr(e,t,i,u),p=Yr(l),x=zr(p),C=`${o}#p256-enc-1`,I={eventId:g,didVerificationMethodId:C,algorithm:"ECDH-ES+A256KW",curve:"P-256",createdAt:new Date().toISOString(),active:!1,publicKeyMultibase:x},R={keys:{...s?.keys??{},[c]:I}};return await Jt(e,t,i,R),{publicKeyMultibase:x,verificationMethodId:C}}async function he(r){let{roomId:e,accessToken:t,homeServerUrl:i,verificationMethodId:n}=r,o=await He(e,t,i);if(!o?.keys)throw new Error("No encryption key index found \u2014 cannot activate");let s=!1;for(let c of Object.values(o.keys))c.didVerificationMethodId===n&&(c.active=!0,s=!0);if(!s)throw new Error(`No key entry found for verification method ${n}`);await Jt(e,t,i,o)}function ye(r){return{typeUrl:"/ixo.iid.v1beta1.MsgAddVerification",value:qe.iid.v1beta1.MsgAddVerification.fromPartial({id:r.oracleEntityDid,verification:qe.iid.v1beta1.Verification.fromPartial({relationships:["keyAgreement"],method:qe.iid.v1beta1.VerificationMethod.fromPartial({id:r.verificationMethodId,type:"Multikey",controller:r.oracleEntityDid,publicKeyMultibase:r.publicKeyMultibase})}),signer:r.signerAddress})}}import{createMatrixApiClient as ti,utils as ri}from"@ixo/matrixclient-sdk";import{CID as Zr}from"multiformats";import{base64 as ei}from"multiformats/bases/base64";import*as Qt from"multiformats/hashes/sha2";async function Zt(r){let e=r.startsWith("m")?r:"m"+r,t=ei.decode(e),i=await Qt.sha256.digest(t);return Zr.create(1,85,i).toString()}function er(r){let e=new TextEncoder().encode(r);return btoa(String.fromCharCode(...Array.from(e)))}var ne=async({data:r,fileName:e,homeServerUrl:t,accessToken:i})=>{let n=ti({homeServerUrl:t,accessToken:i}),o=JSON.stringify(r),s=Buffer.from(o,"utf8"),c=e+".json",d=await n.media.v1beta1.upload(c,"application/ld+json",s),a=ri.mxc.mxcUrlToHttp(t,d.content_uri);if(!a)throw new Error("Failed to upload file to Matrix");let l=JSON.stringify(r),u=er(l),g=await Zt(u);return{encrypted:"false",cid:g,proof:g,serviceEndpoint:a,mxc:d.content_uri}};var B=class{constructor(e,t){this.config=t;if(!e.did||!e.pubKey||!e.address||!e.algo)throw new Error("Wallet not found");this.wallet=e}wallet;buildMsgCreateEntity(e){return{typeUrl:"/ixo.entity.v1beta1.MsgCreateEntity",value:E.entity.v1beta1.MsgCreateEntity.fromPartial({entityType:"oracle",context:[],entityStatus:0,verification:[...tr.iid.createIidVerificationMethods({did:this.wallet.did,pubkey:new Uint8Array(Buffer.from(this.wallet.pubKey)),address:this.wallet.address,controller:this.wallet.did,type:this.wallet.algo==="ed25519"?"ed":"secp"})],controller:[this.wallet.did],ownerAddress:this.wallet.address,ownerDid:this.wallet.did,relayerNode:ot[this.config.getValue("network")??"devnet"],service:[E.iid.v1beta1.Service.fromPartial({id:"{id}#matrix",type:"MatrixHomeServer",serviceEndpoint:e})],linkedResource:[],accordedRight:[],linkedEntity:[],linkedClaim:[],startDate:Ge.proto.toTimestamp(new Date),endDate:Ge.proto.toTimestamp(new Date(Date.now()+31536e8))})}}addLinkedAccounts(e,{oracleAccountAddress:t}){if(!this.wallet.signXClient||!this.wallet.wallet)throw new Error("SignX client or wallet not found");let o=[{devnet:"did:ixo:ixo17w9u5uk4qjyjgeyqfpnp92jwy58faey9vvp3ar",testnet:"did:ixo:ixo14vjrckltpngugp03tcasfgh5qakey9n3sgm6y2",mainnet:"did:ixo:ixo1d39eutxdc0e8mnp0fmzqjdy6aaf26s9hzrk33r"}[this.config.getValue("network")],`did:ixo:${t}`].map(s=>E.iid.v1beta1.LinkedEntity.fromPartial({id:s,type:"agent",relationship:"admin",service:"matrix"}));e.value.linkedEntity=o}async createAuthZConfig({oracleAccountAddress:e,oracleName:t,entityDid:i,homeServerUrl:n,accessToken:o}){let c=await ne({data:{"@context":["https://schema.org",{ixo:"https://w3id.org/ixo/context/v1",oracle:{"@id":i,"@type":"@id"}}],"@type":"Service","@id":"oracle:OracleAuthorization",name:"OracleAuthorization",description:"OracleAuthorization",serviceType:"OracleClaimAuthorizationService",requiredPermissions:["/ixo.claims.v1beta1.MsgCreateClaimAuthorization"],granteeAddress:e,granterAddress:"",oracleName:t},fileName:"authz",homeServerUrl:n,accessToken:o});return E.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#orz",type:"oracleAuthZConfig",proof:c.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Orale AuthZ Config",serviceEndpoint:c.serviceEndpoint})}async createFeesConfig({entityDid:e,price:t,denom:i,homeServerUrl:n,accessToken:o}){let s={"@context":["https://schema.org",{ixo:"https://w3id.org/ixo/context/v1",oracle:{"@id":e,"@type":"@id"}}],"@type":"Service","@id":"oracle:ServiceFeeModel",name:"Pricing",description:"Pricing",serviceType:"",offers:{"@type":"Offer",priceCurrency:i,priceSpecification:{"@type":"PaymentChargeSpecification",priceCurrency:i,price:t*1e3,unitCode:"MON",billingIncrement:1,billingPeriod:"P1M",priceType:"Subscription",maxPrice:t},eligibleQuantity:{"@type":"QuantitativeValue",value:1,unitCode:"MON"}}},c=await ne({data:s,fileName:"fees",homeServerUrl:n,accessToken:o});return E.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#fee",type:"pricingList",proof:c.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Pricing List",serviceEndpoint:c.serviceEndpoint})}async updateOracleDomain(e,t){let i=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!i)throw new Error("SignX client or wallet not found");let n={typeUrl:"/ixo.iid.v1beta1.MsgDeleteService",value:E.iid.v1beta1.MsgDeleteService.fromPartial({id:e,serviceId:"{id}#api",signer:i})},o={typeUrl:"/ixo.iid.v1beta1.MsgDeleteService",value:E.iid.v1beta1.MsgDeleteService.fromPartial({id:e,serviceId:"{id}#ws",signer:i})},s={typeUrl:"/ixo.iid.v1beta1.MsgAddService",value:E.iid.v1beta1.MsgAddService.fromPartial({id:e,serviceData:E.iid.v1beta1.Service.fromPartial({id:"{id}#api",type:"oracleService",serviceEndpoint:t}),signer:i})},c={typeUrl:"/ixo.iid.v1beta1.MsgAddService",value:E.iid.v1beta1.MsgAddService.fromPartial({id:e,serviceData:E.iid.v1beta1.Service.fromPartial({id:"{id}#ws",type:"wsService",serviceEndpoint:t}),signer:i})};w.info(`Sign to update oracle domain for entity ${e}`);let m=await this.wallet.signXClient.transact([n,o,s,c],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(m)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),w.success(`Oracle domain updated to ${t}`)}async addControllerToEntity(e,t){let i=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!i)throw new Error("SignX client or wallet not found");let n={typeUrl:"/ixo.iid.v1beta1.MsgAddController",value:E.iid.v1beta1.MsgAddController.fromPartial({id:e,controllerDid:t,signer:i})};w.info(`Sign to add controller ${t} to entity ${e}`);let o=await this.wallet.signXClient.transact([n],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(o)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),w.success(`Controller ${t} added to entity ${e}`)}async createOracleConfigFiles({oracleName:e,entityDid:t,price:i,oracleAccountAddress:n,homeServerUrl:o,accessToken:s}){let c=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!c)throw new Error("SignX client or wallet not found");let d=(await Promise.all([this.createAuthZConfig({oracleName:e,entityDid:t,oracleAccountAddress:n,homeServerUrl:o,accessToken:s}),this.createFeesConfig({entityDid:t,price:i,denom:this.config.getValue("network")==="devnet"?"uixo":"ibc/6BBE9BD4246F8E04948D5A4EEE7164B2630263B9EBB5E7DC5F0A46C62A2FF97B",homeServerUrl:o,accessToken:s})])).map(u=>({typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:E.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:t,linkedResource:E.iid.v1beta1.LinkedResource.fromPartial({id:u.id,description:u.description,type:u.type,proof:u.proof,mediaType:u.mediaType,encrypted:u.encrypted,serviceEndpoint:u.serviceEndpoint}),signer:c})}));w.info("Sign to edit the entity and add the config files");let a=await this.wallet.signXClient.transact(d,this.wallet.wallet);return this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(a)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction()}async createDomainCard({profile:e,entityDid:t,homeServerUrl:i,accessToken:n}){let o=new Date().toISOString(),s={"@context":["https://www.w3.org/ns/credentials/v2","https://w3id.org/ixo/context/v1",{schema:"https://schema.org/",ixo:"https://w3id.org/ixo/vocab/v1",prov:"http://www.w3.org/ns/prov#",proj:"https://linked.data.gov.au/def/project#",xsd:"http://www.w3.org/2001/XMLSchema#",id:"@id",type:"@type","ixo:vector":{"@container":"@list","@type":"xsd:double"},"@protected":!0}],id:`${t}#dmn`,type:["VerifiableCredential","ixo:DomainCard"],issuer:{id:this.wallet.did},validFrom:o,credentialSchema:{id:"https://github.com/ixoworld/domainCards/schemas/ixo-domain-card-1.json",type:"JsonSchema"},credentialSubject:{id:t,type:["ixo:oracle"],additionalType:["schema:Organization"],name:e.name,alternateName:e.orgName!==e.name?[e.orgName]:void 0,description:e.description,logo:{type:"schema:ImageObject",id:e.logo,contentUrl:e.logo},image:[{type:"schema:ImageObject",id:e.coverImage,contentUrl:e.coverImage}],address:{type:"schema:PostalAddress",addressLocality:e.location},...e.url?{url:e.url}:{}}},c=await ne({data:s,fileName:"domainCard",homeServerUrl:i,accessToken:n});return E.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#dmn",type:"domainCard",proof:c.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Domain Card",serviceEndpoint:c.serviceEndpoint})}async addProfile({orgName:e,name:t,logo:i,coverImage:n,location:o,description:s,homeServerUrl:c,accessToken:m}){let a=await ne({data:{"@context":{ixo:"https://w3id.org/ixo/ns/protocol/","@id":"@type",type:"@type","@protected":!1},id:"ixo:entity#profile",type:"profile",orgName:e,name:t,image:n,logo:i,brand:e,location:o,description:s},fileName:"profile",homeServerUrl:c,accessToken:m});return E.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#pro",type:"Settings",description:"Profile",mediaType:"application/json",serviceEndpoint:a.serviceEndpoint,proof:a.proof,encrypted:"false",right:""})}addServices(e,t){e.value.service.push(...t.map(i=>E.iid.v1beta1.Service.fromPartial(i)))}setParentProtocol(e,t){e.value.context.push(...tr.iid.createAgentIidContext([{key:"class",val:t}]))}async submitToDomainIndexer(e){let t=this.config.getValue("network")??"devnet",i=ee[t];try{let n=await fetch(i,{method:"POST",headers:{accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({did:e})});if(!n.ok){let o=await n.text();w.warn(`Failed to submit to domain indexer: ${n.status} ${o}`);return}w.success("Domain card submitted to domain indexer")}catch(n){w.warn(`Error submitting to domain indexer: ${n instanceof Error?n.message:String(n)}`)}}async execute(e){if(!this.wallet.signXClient||!this.wallet.wallet)throw new Error("SignX client not found");let{matrixHomeServerUrl:t}=e;w.info("Creating Oracle Wallet and Matrix Account");let i=await oi({message:"Enter a 6-digit PIN to secure your Matrix Vault:",placeholder:"123456",validate(p){return G(p)}});ii(i)&&(w.error("User cancelled"),process.exit(1));let n=await ue({pin:i,oracleName:e.oracleConfig.oracleName,network:this.config.getValue("network"),oracleAvatarUrl:e.profile.logo,matrixHomeServerUrl:t},async p=>{await this.wallet.sendTokens(p,25e4)}),o=n.matrixHomeServerUrl,s=n.matrixAccessToken;w.info("Adding profile");let c=await this.addProfile({...e.profile,homeServerUrl:o,accessToken:s}),m=this.buildMsgCreateEntity(t);m.value.linkedResource.push(c),w.info("Adding services"),this.addServices(m,e.services),w.info("Adding parent protocol"),this.setParentProtocol(m,e.parentProtocol),this.addLinkedAccounts(m,{oracleAccountAddress:n.address}),w.info("Sign this transaction to create the entity");let d=await this.wallet.signXClient.transact([m],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(d)),await this.wallet.signXClient.pollNextTransaction();let a=await this.wallet.signXClient.awaitTransaction();w.success("Entity created -- wait to attach the required config files");let l=Ge.common.getValueFromEvents(a,"wasm","token_id");w.info("Creating domain card");let u=await this.createDomainCard({profile:e.profile,entityDid:l,homeServerUrl:o,accessToken:s});if(this.wallet.wallet?.address){let p={typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:E.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:l,linkedResource:E.iid.v1beta1.LinkedResource.fromPartial({id:u.id,description:u.description,type:u.type,proof:u.proof,mediaType:u.mediaType,encrypted:u.encrypted,serviceEndpoint:u.serviceEndpoint}),signer:this.wallet.wallet.address})};w.info("Sign to add domain card to the entity");let x=await this.wallet.signXClient.transact([p],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(x)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),w.success("Domain card added to entity")}await this.createOracleConfigFiles({oracleName:e.oracleConfig.oracleName,price:e.oracleConfig.price,oracleAccountAddress:n.address,entityDid:l,homeServerUrl:o,accessToken:s}),w.success("Entity created -- config files attached"),w.info("Setting up P-256 encryption key for secrets management");try{let p=await fe({roomId:n.matrixRoomId,accessToken:s,homeServerUrl:o,pin:i,oracleEntityDid:l}),x=ye({oracleEntityDid:l,verificationMethodId:p.verificationMethodId,publicKeyMultibase:p.publicKeyMultibase,signerAddress:this.wallet.wallet.address});w.info("Sign to add P-256 encryption key (keyAgreement) to the entity");let C=await this.wallet.signXClient.transact([x],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(C)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),await he({roomId:n.matrixRoomId,accessToken:s,homeServerUrl:o,verificationMethodId:p.verificationMethodId}),w.success("P-256 encryption key published to entity DID")}catch(p){w.warn(`Failed to setup encryption key: ${p instanceof Error?p.message:String(p)}`),w.warn("You can set it up later using: oracles-cli setup-encryption-key")}await ge({baseUrl:o,accessToken:s,userId:n.matrixUserId,deviceId:""});let g=ni();g.start("Creating Entity Matrix Room..."),g.stop("Room created -- room joined"),w.warn("Please save the following information in a secure location as it is not stored:"),w.info("ORACLE ACCOUNT DETAILS");for(let p in n)w.info(`${p}: ${n[p]}`);return this.config.addValue("registerUserResult",n),this.config.addValue("entityDid",l),this.config.addValue("oracleMatrixHomeServerUrl",t),w.info("Submitting domain card to domain indexer"),await this.submitToDomainIndexer(l),l}};var Y=class{constructor(e,t){this.wallet=e;this.config=t}name="create-entity";description="Create an entity";async execute(){this.config.getValue("network")||await T(this.config);let t=this.wallet.matrixHomeServer??K[this.config.getValue("network")??"devnet"],i=await v.group({matrixHomeServerUrl:()=>v.text({message:"Matrix homeserver URL for the oracle:",initialValue:t,defaultValue:t,validate(a){return ae(a)}}),oracleName:()=>v.text({message:"What is the name of the oracle?",initialValue:"My oracle",validate(a){return P(a,"Oracle name is required")}}),oraclePrice:()=>v.text({message:"What is the price of the oracle in IXO CREDITS?",initialValue:"100",validate(a){return ct(parseInt(a??""),"Oracle price is required and must be a number")}}),profile:()=>v.group({orgName:()=>v.text({message:"What is the name of the organization?",initialValue:"IXO",validate(a){return P(a,"Organization name is required")}}),name:()=>v.text({message:"What is the name of the profile?",initialValue:"My oracle",validate(a){return P(a,"Profile name is required")}}),logo:({results:a})=>v.text({message:"What is the logo of the profile?",initialValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${a?.name??"IXO"}`,defaultValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${a?.name??"IXO"}`,validate(l){return l?j(l,"Logo is required or a valid URL"):`https://api.dicebear.com/8.x/bottts/svg?seed=${a?.name??"IXO"}`}}),coverImage:({results:a})=>v.text({message:"What is the cover image of the profile?",initialValue:a.logo,defaultValue:a.logo,validate(l){return l?j(l,"Cover image is required or a valid URL"):a.logo}}),location:()=>v.text({message:"What is the location of your domain?",initialValue:"New York, NY",validate(a){return P(a,"Location is required")}}),description:()=>v.text({message:"What is the description of the entity (profile)?",initialValue:"We are a company that helps you with daily tasks",validate(a){return P(a,"Description is required")}}),url:()=>v.text({message:"What is the website URL of the oracle? (optional, press Enter to skip)",placeholder:"https://your-oracle-website.com"})}),parentProtocol:()=>v.select({message:"What is the parent protocol of the entity?",options:[{value:"did:ixo:entity:1a76366f16570483cea72b111b27fd78",label:"IXO Oracle Protocol",hint:"default protocol"}],initialValue:"did:ixo:entity:1a76366f16570483cea72b111b27fd78"}),apiUrl:()=>v.text({message:"What is the API URL of the oracle?",initialValue:"http://localhost:4000",validate(a){return j(a,"API URL is required or a valid URL")}})},{onCancel:()=>{v.cancel("Operation cancelled."),process.exit(0)}}),o=await new B(this.wallet,this.config).execute({oracleConfig:{oracleName:i.oracleName,price:parseInt(i.oraclePrice)},profile:{orgName:i.profile.orgName,name:i.profile.name,logo:i.profile.logo,coverImage:i.profile.coverImage,location:i.profile.location,description:i.profile.description,...i.profile.url?{url:i.profile.url}:{}},services:[{id:"{id}#api",serviceEndpoint:i.apiUrl,type:"oracleService"},{id:"{id}#ws",serviceEndpoint:i.apiUrl,type:"wsService"}],parentProtocol:i.parentProtocol,matrixHomeServerUrl:i.matrixHomeServerUrl});v.log.info(`API for the oracle is: ${i.apiUrl} | You can change this after you deploy the oracle`);let s=this.config.getValue("projectPath")??process.cwd(),c=this.config.getValue("network")??"devnet";try{ht(s,{oracleName:i.oracleName,orgName:i.profile.orgName,description:i.profile.description,location:i.profile.location,website:i.profile.url??"",price:parseInt(i.oraclePrice),apiUrl:i.apiUrl,network:c,entityDid:o,logo:i.profile.logo}),v.log.success(`Oracle config saved to ${s}/oracle.config.json`)}catch(a){v.log.warning(`Could not save oracle.config.json: ${a instanceof Error?a.message:String(a)}`)}let d=`${at[this.config.getValue("network")??"devnet"]}/oracle/${o}/overview`;return v.log.info(`Oracle created successfully: ${o}`),v.log.info(`Oracle URL: ${d}`),{success:!0,data:`Entity created successfully: ${o}`}}};import*as k from"@clack/prompts";var we=class{constructor(e,t){this.wallet=e;this.config=t}name="create-user";description="Create a new user";async execute(){let e=this.config.getValue("network");e||await T(this.config);let t=this.wallet.matrixHomeServer??K[this.config.getValue("network")??"devnet"],i=await k.text({message:"Matrix homeserver URL:",initialValue:t,defaultValue:t,validate(c){return ae(c)}});k.isCancel(i)&&(k.log.error("User cancelled"),process.exit(1));let n=await k.text({message:"Enter a 6-digit PIN to secure your Matrix Vault:",placeholder:"123456",validate(c){return G(c)}});k.isCancel(n)&&(k.log.error("User cancelled"),process.exit(1));let o=await k.text({message:"Enter your oracle name",initialValue:"My oracle",validate(c){return P(c,"Oracle name is required")}});k.isCancel(o)&&(k.log.error("User cancelled"),process.exit(1));let s=await ue({pin:n,oracleName:o,network:this.config.getValue("network")??e,oracleAvatarUrl:`https://api.dicebear.com/8.x/bottts/svg?seed=${o}`,matrixHomeServerUrl:i},async c=>{await this.wallet.sendTokens(c,15e4)});return await ge({baseUrl:s.matrixHomeServerUrl,accessToken:s.matrixAccessToken,userId:s.matrixUserId,deviceId:""}),{success:!0,data:s}}};var oe=class{constructor(e){this.registry=e}name="help";description="Show help information and available commands";async execute(){return{success:!0,data:`
3
10
  QiForge CLI - Help
4
11
 
5
12
  USAGE:
@@ -11,23 +18,25 @@ ${this.registry.getAll().map(i=>` ${i.name.padEnd(15)} ${i.description}`).join(
11
18
 
12
19
  EXAMPLES:
13
20
  qiforge-cli --init Initialize a new IXO Oracle project
21
+ qiforge-cli --chat Chat with your oracle
14
22
  qiforge-cli Launch interactive menu
15
23
  qiforge-cli help Show this help message
16
24
 
17
25
  OPTIONS:
18
26
  --init Initialize a new project (shortcut)
27
+ --chat Start a chat session with your oracle
19
28
  --help, -h Show help information
20
29
 
21
30
  For more information, visit: https://www.npmjs.com/package/qiforge-cli
22
- `}}};import*as u from"@clack/prompts";import{existsSync as ge}from"fs";import F from"path";import Ot from"simple-git";import pe from"fs";import me from"path";function Or(r,e){return`
31
+ `}}};import*as y from"@clack/prompts";import{existsSync as Ce}from"fs";import z from"path";import ir from"simple-git";import ve from"fs";import xe from"path";function si(r,e){return`
23
32
  PORT=4000
24
33
  ORACLE_NAME=${e.oracleName}
25
34
 
26
35
  # Network
27
36
  NETWORK=${r}
28
- RPC_URL=${M[r]}
29
- BLOCKSYNC_GRAPHQL_URL=${G[r]}
30
- BLOCKSYNC_URI=${G[r]}
37
+ RPC_URL=${W[r]}
38
+ BLOCKSYNC_GRAPHQL_URL=${te[r]}
39
+ BLOCKSYNC_URI=${te[r].replace("/graphql","")}
31
40
 
32
41
  # Matrix
33
42
  MATRIX_BASE_URL=${e.matrixBaseUrl}
@@ -52,13 +61,13 @@ OPENAI_API_KEY=
52
61
  OPEN_ROUTER_API_KEY=
53
62
 
54
63
  # External Services (configure these for your deployment)
55
- MEMORY_MCP_URL=${Te[r]}
56
- MEMORY_ENGINE_URL=${be[r]}
64
+ MEMORY_MCP_URL=${De[r]}
65
+ MEMORY_ENGINE_URL=${_e[r]}
57
66
 
58
67
  # FIRECRWAL -> check the docs https://docs.firecrawl.dev/mcp-server
59
68
  FIRECRAWL_MCP_URL=
60
- DOMAIN_INDEXER_URL=${H[r]}
61
- SANDBOX_MCP_URL=${Pe[r]}
69
+ DOMAIN_INDEXER_URL=${ee[r]}
70
+ SANDBOX_MCP_URL=${$e[r]}
62
71
 
63
72
  # Observability (optional)
64
73
  LANGSMITH_TRACING=true
@@ -69,24 +78,24 @@ LANGSMITH_PROJECT="${e.oracleName}_${r}"
69
78
 
70
79
  DISABLE_CREDITS=true
71
80
  CORS_ORIGIN=*
72
- SUBSCRIPTION_URL=${ke[r]}
81
+ SUBSCRIPTION_URL=${Le[r]}
73
82
 
74
83
  ### BACKUP \u2014 save these securely (values above are already set)
75
84
  # ORACLE_ADDRESS=${e.oracleAddress}
76
85
  # ORACLE_DID=${e.oracleDid}
77
- `}function Ur(r,e){return`# To fill in the blank values, run: qiforge-cli create-entity (select ${r})
86
+ `}function ai(r,e){return`# To fill in the blank values, run: qiforge-cli create-entity (select ${r})
78
87
 
79
88
  PORT=4000
80
89
  ORACLE_NAME=${e}
81
90
 
82
91
  # Network
83
92
  NETWORK=${r}
84
- RPC_URL=${M[r]}
85
- BLOCKSYNC_GRAPHQL_URL=${G[r]}
86
- BLOCKSYNC_URI=${G[r]}
93
+ RPC_URL=${W[r]}
94
+ BLOCKSYNC_GRAPHQL_URL=${te[r]}
95
+ BLOCKSYNC_URI=${te[r].replace("/graphql","")}
87
96
 
88
97
  # Matrix
89
- MATRIX_BASE_URL=${X[r]}
98
+ MATRIX_BASE_URL=${K[r]}
90
99
  MATRIX_ORACLE_ADMIN_ACCESS_TOKEN=
91
100
  MATRIX_ORACLE_ADMIN_PASSWORD=
92
101
  MATRIX_ORACLE_ADMIN_USER_ID=
@@ -108,13 +117,13 @@ OPENAI_API_KEY=
108
117
  OPEN_ROUTER_API_KEY=
109
118
 
110
119
  # External Services (configure these for your deployment)
111
- MEMORY_MCP_URL=${Te[r]}
112
- MEMORY_ENGINE_URL=${be[r]}
120
+ MEMORY_MCP_URL=${De[r]}
121
+ MEMORY_ENGINE_URL=${_e[r]}
113
122
 
114
123
  # FIRECRWAL -> check the docs https://docs.firecrawl.dev/mcp-server
115
124
  FIRECRAWL_MCP_URL=
116
- DOMAIN_INDEXER_URL=${H[r]}
117
- SANDBOX_MCP_URL=${Pe[r]}
125
+ DOMAIN_INDEXER_URL=${ee[r]}
126
+ SANDBOX_MCP_URL=${$e[r]}
118
127
 
119
128
  # Observability (optional)
120
129
  LANGSMITH_TRACING=true
@@ -126,22 +135,22 @@ LANGSMITH_PROJECT="${e}_${r}"
126
135
  # Features (optional)
127
136
  # DISABLE_CREDITS=false
128
137
  # CORS_ORIGIN=*
129
- # SUBSCRIPTION_URL=${ke[r]}
130
- `}function Xe(r,e){try{pe.writeFileSync(r,e),console.log("\u2705 env file created successfully at:",r)}catch(t){throw console.error("\u274C Failed to create env file:",r,t),t}}var Nt=async r=>{let e=r.getOrThrow("oracleMatrixHomeServerUrl"),t=r.getOrThrow("network"),i=r.getOrThrow("registerUserResult"),n=await De({homeServerUrl:e,username:i.matrixUserId,password:i.matrixPassword,deviceName:i.matrixDeviceName}),o=r.getOrThrow("projectPath"),s=me.join(o,"apps","app");console.log("Creating env files in:",s),pe.existsSync(s)||(console.log("Creating directory:",s),pe.mkdirSync(s,{recursive:!0}));let a=r.getValue("projectName")??"",c=Or(t,{oracleName:a,network:t,matrixBaseUrl:e,matrixAccessToken:n.accessToken,matrixPassword:i.matrixPassword,matrixUserId:i.matrixUserId,matrixRecoveryPhrase:i.matrixRecoveryPhrase,matrixPin:i.pin,matrixRoomId:i.matrixRoomId,mnemonic:i.mnemonic,entityDid:r.getOrThrow("entityDid"),oracleAddress:i.address,oracleDid:i.did}),l=`.env.${t}`;Xe(me.join(s,l),c),Xe(me.join(s,".env"),c);let m=[{net:"devnet",filename:".env.devnet"},{net:"testnet",filename:".env.testnet"},{net:"mainnet",filename:".env.mainnet"}];for(let{net:d,filename:p}of m){if(d===t)continue;let x=me.join(s,p);if(pe.existsSync(x))continue;let g=Ur(d,a);Xe(x,g)}};var ue=class{constructor(e,t){this.config=e;this.wallet=t}name="init";description="Initialize Project";async getProjectInput(){let e=await u.text({message:"What is your project named?",placeholder:"my-ixo-project",validate(o){if(!o)return"Project name is required"}});u.isCancel(e)&&(u.cancel("Operation cancelled."),process.exit(0));let t=String(e),i,n;return t.includes("/")||t.includes("\\")?(i=t,n=F.basename(t)):(n=t,i=F.join(process.cwd(),n)),this.isValidProjectName(n)||(u.note("Invalid project name. Using a valid name instead.","Warning"),n=this.sanitizeProjectName(n),i=F.join(F.dirname(i),n)),{projectPath:i,projectName:n}}isValidProjectName(e){return/^[a-zA-Z][a-zA-Z0-9-_]*$/.test(e)&&e.length>0&&e.length<=50}sanitizeProjectName(e){return e.replace(/[^a-zA-Z0-9-_]/g,"-").replace(/^-+|-+$/g,"").toLowerCase().substring(0,50)}async confirmProjectCreation(e,t){if(ge(e)){let o=await u.confirm({message:`Directory "${e}" already exists. Do you want to overwrite it?`,initialValue:!1});return u.isCancel(o)&&(u.cancel("Operation cancelled."),process.exit(0)),o}let n=await u.confirm({message:`Create IXO project "${t}" in "${e}"?`,initialValue:!0});return u.isCancel(n)&&(u.cancel("Operation cancelled."),process.exit(0)),n}async selectRepo(){let e=await u.select({message:"Select a template to clone",options:[{value:"git@github.com:ixoworld/qiforge.git",label:"IXO Oracles (Default)"},{label:"Custom template",value:"custom"}]});if(u.isCancel(e)&&(u.cancel("Operation cancelled."),process.exit(0)),e==="custom"){let t=await u.text({message:"Enter the custom template URL"});return u.isCancel(t)&&(u.cancel("Operation cancelled."),process.exit(0)),t}return e}async cloneRepo(e,t,i=!1){let n=Ot(),o=u.spinner();try{if(o.start("Cloning repository..."),i&&ge(t)){let{rmSync:l}=await import("fs");l(t,{recursive:!0,force:!0})}await n.clone(e,t);let s=F.join(t,".git");if(ge(s)){let{rmSync:l}=await import("fs");l(s,{recursive:!0,force:!0})}await Ot(t).init(),o.stop("Repository cloned successfully"),u.log.info("Creating Oracle Entity and Matrix Account"),(await new V(this.wallet,this.config).execute()).success?u.log.info("Oracle Entity and Matrix Account created successfully"):u.log.error("Failed to create Oracle Entity and Matrix Account"),await Nt(this.config),u.log.success(`
138
+ # SUBSCRIPTION_URL=${Le[r]}
139
+ `}function Je(r,e){try{ve.writeFileSync(r,e),console.log("\u2705 env file created successfully at:",r)}catch(t){throw console.error("\u274C Failed to create env file:",r,t),t}}var rr=async r=>{let e=r.getOrThrow("oracleMatrixHomeServerUrl"),t=r.getOrThrow("network"),i=r.getOrThrow("registerUserResult"),n=await Nt({homeServerUrl:e,username:i.matrixUserId,password:i.matrixPassword}),o=r.getOrThrow("projectPath"),s=xe.join(o,"apps","app");console.log("Creating env files in:",s),ve.existsSync(s)||(console.log("Creating directory:",s),ve.mkdirSync(s,{recursive:!0}));let c=r.getValue("projectName")??"",m=si(t,{oracleName:c,network:t,matrixBaseUrl:e,matrixAccessToken:n.accessToken,matrixPassword:i.matrixPassword,matrixUserId:i.matrixUserId,matrixRecoveryPhrase:i.matrixRecoveryPhrase,matrixPin:i.pin,matrixRoomId:i.matrixRoomId,mnemonic:i.mnemonic,entityDid:r.getOrThrow("entityDid"),oracleAddress:i.address,oracleDid:i.did}),d=`.env.${t}`;Je(xe.join(s,d),m),Je(xe.join(s,".env"),m);let a=[{net:"devnet",filename:".env.devnet"},{net:"testnet",filename:".env.testnet"},{net:"mainnet",filename:".env.mainnet"}];for(let{net:l,filename:u}of a){if(l===t)continue;let g=xe.join(s,u);if(ve.existsSync(g))continue;let p=ai(l,c);Je(g,p)}};var Re=class{constructor(e,t){this.config=e;this.wallet=t}name="init";description="Initialize Project";async getProjectInput(){let e=await y.text({message:"What is your project named?",placeholder:"my-ixo-project",validate(o){if(!o)return"Project name is required"}});y.isCancel(e)&&(y.cancel("Operation cancelled."),process.exit(0));let t=String(e),i,n;return t.includes("/")||t.includes("\\")?(i=t,n=z.basename(t)):(n=t,i=z.join(process.cwd(),n)),this.isValidProjectName(n)||(y.note("Invalid project name. Using a valid name instead.","Warning"),n=this.sanitizeProjectName(n),i=z.join(z.dirname(i),n)),{projectPath:i,projectName:n}}isValidProjectName(e){return/^[a-zA-Z][a-zA-Z0-9-_]*$/.test(e)&&e.length>0&&e.length<=50}sanitizeProjectName(e){return e.replace(/[^a-zA-Z0-9-_]/g,"-").replace(/^-+|-+$/g,"").toLowerCase().substring(0,50)}async confirmProjectCreation(e,t){if(Ce(e)){let o=await y.confirm({message:`Directory "${e}" already exists. Do you want to overwrite it?`,initialValue:!1});return y.isCancel(o)&&(y.cancel("Operation cancelled."),process.exit(0)),o}let n=await y.confirm({message:`Create IXO project "${t}" in "${e}"?`,initialValue:!0});return y.isCancel(n)&&(y.cancel("Operation cancelled."),process.exit(0)),n}async selectRepo(){let e=await y.select({message:"Select a template to clone",options:[{value:"git@github.com:ixoworld/qiforge.git",label:"IXO Oracles (Default)"},{label:"Custom template",value:"custom"}]});if(y.isCancel(e)&&(y.cancel("Operation cancelled."),process.exit(0)),e==="custom"){let t=await y.text({message:"Enter the custom template URL"});return y.isCancel(t)&&(y.cancel("Operation cancelled."),process.exit(0)),t}return e}async cloneRepo(e,t,i=!1){let n=ir(),o=y.spinner();try{if(o.start("Cloning repository..."),i&&Ce(t)){let{rmSync:d}=await import("fs");d(t,{recursive:!0,force:!0})}await n.clone(e,t);let s=z.join(t,".git");if(Ce(s)){let{rmSync:d}=await import("fs");d(s,{recursive:!0,force:!0})}await ir(t).init(),o.stop("Repository cloned successfully"),y.log.info("Creating Oracle Entity and Matrix Account"),(await new Y(this.wallet,this.config).execute()).success?y.log.info("Oracle Entity and Matrix Account created successfully"):y.log.error("Failed to create Oracle Entity and Matrix Account"),await rr(this.config),y.log.success(`
131
140
  \u2705 IXO project created successfully!
132
141
 
133
142
  \u{1F4C1} Location: ${t}
134
143
  \u{1F680} Next steps:
135
- cd ${F.basename(t)}
144
+ cd ${z.basename(t)}
136
145
  pnpm install
137
146
  pnpm build
138
147
  cd apps/app
139
- pnpm start:dev`)}catch(s){throw o.stop("Failed to clone repository"),s}}async execute(){try{let{projectPath:e,projectName:t}=await this.getProjectInput();if(!await this.confirmProjectCreation(e,t))return{success:!1,data:"Project creation cancelled"};this.config.addValue("projectPath",e),this.config.addValue("projectName",t);let n=await this.selectRepo();this.config.addValue("repo",n);let o=ge(e);return await this.cloneRepo(n,e,o),{success:!0,data:`Project "${t}" created successfully in "${e}"`}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Unknown error occurred"}}}};import{confirm as Mr}from"@clack/prompts";var fe=class{constructor(e){this.wallet=e}name="logout";description="Logout command";async execute(){return await Mr({message:"Are you sure you want to logout?",initialValue:!1})?(await this.wallet.clearWallet(),{success:!0,data:"Logged out successfully"}):{success:!1,error:"Logout cancelled"}}};import*as C from"@clack/prompts";var he=class{constructor(e,t){this.wallet=e;this.config=t}name="setup-encryption-key";description="Setup P-256 encryption key for an existing oracle (keyAgreement)";async execute(){this.config.getValue("network")||await S(this.config);let t=await C.group({entityDid:()=>C.text({message:"Oracle entity DID (ORACLE_ENTITY_DID from .env):",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(n){return L(n)}}),matrixRoomId:()=>C.text({message:"Oracle Matrix room ID (MATRIX_ACCOUNT_ROOM_ID from .env):",placeholder:"!abc123:devmx.ixo.earth",validate(n){return!n||!n.startsWith("!")||!n.includes(":")?"Matrix room ID must be in format !roomId:server (e.g. !abc123:devmx.ixo.earth)":b(n,"Matrix room ID is required")}}),matrixAccessToken:()=>C.password({message:"Oracle Matrix access token (MATRIX_ORACLE_ADMIN_ACCESS_TOKEN from .env):",validate(n){return b(n,"Matrix access token is required")}}),pin:()=>C.password({message:"Oracle PIN (MATRIX_VALUE_PIN from .env):",validate(n){return j(n)}})},{onCancel:()=>{C.cancel("Operation cancelled."),process.exit(0)}}),i=St(t.matrixRoomId);try{if(!this.wallet.signXClient||!this.wallet.wallet?.address)throw new Error("Wallet/SignX client not available. Please login first.");if(C.log.info("Checking for existing encryption key..."),await At(t.matrixRoomId,t.matrixAccessToken,i))return C.log.info("Encryption key already exists for this oracle. No action needed."),{success:!0,data:"Encryption key already exists"};C.log.info("Preparing P-256 encryption keypair...");let o=await ae({roomId:t.matrixRoomId,accessToken:t.matrixAccessToken,homeServerUrl:i,pin:t.pin,oracleEntityDid:t.entityDid});C.log.success("Encryption key prepared in Matrix room");let s=le({oracleEntityDid:t.entityDid,verificationMethodId:o.verificationMethodId,publicKeyMultibase:o.publicKeyMultibase,signerAddress:this.wallet.wallet.address});C.log.info("Sign to add P-256 encryption key (keyAgreement) to the entity");let a=await this.wallet.signXClient.transact([s],this.wallet.wallet);return this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(a)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),await ce({roomId:t.matrixRoomId,accessToken:t.matrixAccessToken,homeServerUrl:i,verificationMethodId:o.verificationMethodId}),C.log.success(`P-256 encryption key published to entity DID: ${t.entityDid}`),C.log.info(`Verification method ID: ${o.verificationMethodId}`),{success:!0,data:`Encryption key setup complete for ${t.entityDid}`}}catch(n){return{success:!1,error:n instanceof Error?n.message:String(n)}}}};import{toHex as Dr}from"@cosmjs/encoding";import{createRegistry as _r}from"@ixo/impactxclient-sdk";import{SignX as Ut,SIGN_X_LOGIN_ERROR as Lr,SIGN_X_LOGIN_SUCCESS as $r,SIGN_X_TRANSACT_ERROR as Kr,SIGN_X_TRANSACT_SUCCESS as Wr}from"@ixo/signx-sdk";import Xr from"qrcode-terminal";var Mt={devnet:"https://signx.devnet.ixo.earth",testnet:"https://signx.testnet.ixo.earth",mainnet:"https://signx.ixo.earth"},q=class{signXClient;_loginData;get loginData(){return this._loginData}static loadFromWallet(e){return new Ut({endpoint:Mt[e.network],sitename:"QiForge CLI",network:e.network})}constructor(e){this.signXClient=new Ut({endpoint:Mt[e],sitename:"QiForge CLI",network:e})}async login(){let e=await this.signXClient.login({pollingInterval:2e3,matrix:!0});return this._loginData=e,e}displayStyledQRCode(e,t){let i=typeof e=="string"?e:JSON.stringify(e);console.log(`
140
- `+" ".repeat(5)+"\u{1F510} "+t),console.log(" ".repeat(5)+"\u{1F4F1} Scan with IXO app"),console.log(" ".repeat(5)+"\u2501".repeat(30)),Xr.generate(i,{small:!0}),console.log(" ".repeat(5)+`\u23F3 Waiting...
141
- `)}displayQRCode(e){this.displayStyledQRCode(e,"Login with SignX")}async awaitLogin(){return new Promise((e,t)=>{try{this.signXClient.on($r,i=>{if(!i.data){t(new Error("Login failed"));return}if(!i.data.matrix){t(new Error("Matrix login failed"));return}e(i.data)}),this.signXClient.on(Lr,i=>{console.log("Login error:",i),t(i)})}catch(i){console.error("Error in connecting:",i),t(i)}})}async transact(e,t,i){let n=_r();return this.signXClient.transact({address:t.address,did:t.did,pubkey:t.pubKey,timestamp:new Date().toISOString(),transactions:[{sequence:1,txBodyHex:Dr(n.encodeTxBody({messages:e,memo:i||""}))}]})}async awaitTransaction(){return new Promise((e,t)=>{try{this.signXClient.on(Wr,i=>{e(i.data)}),this.signXClient.on(Kr,i=>{t(i)})}catch(i){console.error("Error in connecting:",i),t(i)}})}async pollNextTransaction(){return this.signXClient.pollNextTransaction()}displayTransactionQRCode(e){this.displayStyledQRCode(e,"SIGNX TRANSACTION")}};var ye=class{constructor(e,t){this.wallet=e;this.config=t}name="signx-login";description="Login with SignX wallet";async execute(){try{let e=await S(this.config),t=new q(e),i=await t.login();t.displayQRCode(i);let n=await t.awaitLogin();return this.wallet.setWallet(n),this.wallet.setSignXClient(t),{success:!0,data:{message:"Successfully logged in with SignX!",wallet:{address:n.address,did:n.did,name:n.name}}}}catch(e){return{success:!1,error:e instanceof Error?`SignX login failed: ${e.message}`:"Unknown error"}}}};import*as k from"@clack/prompts";var we=class{constructor(e,t){this.wallet=e;this.config=t}name="update-oracle-api-url";description="Update the oracle API domain (default is localhost)";async execute(){this.config.getValue("network")||await S(this.config);let t=await k.group({entityDid:()=>k.text({message:"What is the DID of the entity you want to update?",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(i){return L(i)}}),apiUrl:()=>k.text({message:"What is the new API URL (domain) for the oracle?",initialValue:"http://localhost:4000",validate(i){return B(i,"API URL is required and must be a valid URL")}})},{onCancel:()=>{k.cancel("Operation cancelled."),process.exit(0)}});try{let i=new D(this.wallet,this.config);return k.log.info(`Updating oracle domain for entity ${t.entityDid} to ${t.apiUrl}`),await i.updateOracleDomain(t.entityDid,t.apiUrl),{success:!0,data:`Oracle domain updated to ${t.apiUrl} for entity ${t.entityDid}`}}catch(i){return{success:!1,error:i instanceof Error?i.message:String(i)}}}};import*as E from"@clack/prompts";var xe=class{constructor(e,t){this.wallet=e;this.config=t;this.createEntity=new D(this.wallet,this.config)}name="update-entity";description="Update an entity (add controllers, etc.)";createEntity;async execute(){this.config.getValue("network")||await S(this.config);let t=await E.group({entityDid:()=>E.text({message:"What is the DID of the entity you want to update?",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(i){return L(i)}}),action:()=>E.select({message:"What would you like to do?",options:[{value:"add-controller",label:"Add Controller",hint:"Add a new controller DID to the entity"}],initialValue:"add-controller"}),controllerDid:async({results:i})=>{if(i.action!=="add-controller")throw new Error("Unknown action");let n=await E.text({message:"What is the DID of the controller you want to add?",validate(o){return L(o)}});return E.isCancel(n)&&(E.cancel("Operation cancelled."),process.exit(0)),n}},{onCancel:()=>{E.cancel("Operation cancelled."),process.exit(0)}});try{if(t.action==="add-controller"&&typeof t.controllerDid=="string"){let i=t.controllerDid,n=t.entityDid;return E.log.info(`Adding controller ${i} to entity ${n}`),await this.createEntity.addControllerToEntity(n,i),E.log.success(`Controller ${i} successfully added to entity ${n}`),{success:!0,data:`Controller ${i} added to entity ${n}`}}return{success:!1,error:"Unknown action"}}catch(i){return{success:!1,error:i instanceof Error?i.message:String(i)}}}};var Be=class extends Error{constructor(t,i="CLI_ERROR",n){super(t);this.code=i;this.suggestions=n;this.name="CLIError"}};function ve(r){r instanceof Be&&(console.error(`
148
+ pnpm start:dev`)}catch(s){throw o.stop("Failed to clone repository"),s}}async execute(){try{let{projectPath:e,projectName:t}=await this.getProjectInput();if(!await this.confirmProjectCreation(e,t))return{success:!1,data:"Project creation cancelled"};this.config.addValue("projectPath",e),this.config.addValue("projectName",t);let n=await this.selectRepo();this.config.addValue("repo",n);let o=Ce(e);return await this.cloneRepo(n,e,o),{success:!0,data:`Project "${t}" created successfully in "${e}"`}}catch(e){return{success:!1,error:e instanceof Error?e.message:"Unknown error occurred"}}}};import{confirm as ci}from"@clack/prompts";var Ee=class{constructor(e){this.wallet=e}name="logout";description="Logout command";async execute(){return await ci({message:"Are you sure you want to logout?",initialValue:!1})?(await this.wallet.clearWallet(),{success:!0,data:"Logged out successfully"}):{success:!1,error:"Logout cancelled"}}};import*as S from"@clack/prompts";var Se=class{constructor(e,t){this.wallet=e;this.config=t}name="setup-encryption-key";description="Setup P-256 encryption key for an existing oracle (keyAgreement)";async execute(){this.config.getValue("network")||await T(this.config);let t=await S.group({entityDid:()=>S.text({message:"Oracle entity DID (ORACLE_ENTITY_DID from .env):",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(n){return D(n)}}),matrixRoomId:()=>S.text({message:"Oracle Matrix room ID (MATRIX_ACCOUNT_ROOM_ID from .env):",placeholder:"!abc123:devmx.ixo.earth",validate(n){return!n||!n.startsWith("!")||!n.includes(":")?"Matrix room ID must be in format !roomId:server (e.g. !abc123:devmx.ixo.earth)":P(n,"Matrix room ID is required")}}),matrixAccessToken:()=>S.password({message:"Oracle Matrix access token (MATRIX_ORACLE_ADMIN_ACCESS_TOKEN from .env):",validate(n){return P(n,"Matrix access token is required")}}),pin:()=>S.password({message:"Oracle PIN (MATRIX_VALUE_PIN from .env):",validate(n){return G(n)}})},{onCancel:()=>{S.cancel("Operation cancelled."),process.exit(0)}}),i=Yt(t.matrixRoomId);try{if(!this.wallet.signXClient||!this.wallet.wallet?.address)throw new Error("Wallet/SignX client not available. Please login first.");if(S.log.info("Checking for existing encryption key..."),await zt(t.matrixRoomId,t.matrixAccessToken,i))return S.log.info("Encryption key already exists for this oracle. No action needed."),{success:!0,data:"Encryption key already exists"};S.log.info("Preparing P-256 encryption keypair...");let o=await fe({roomId:t.matrixRoomId,accessToken:t.matrixAccessToken,homeServerUrl:i,pin:t.pin,oracleEntityDid:t.entityDid});S.log.success("Encryption key prepared in Matrix room");let s=ye({oracleEntityDid:t.entityDid,verificationMethodId:o.verificationMethodId,publicKeyMultibase:o.publicKeyMultibase,signerAddress:this.wallet.wallet.address});S.log.info("Sign to add P-256 encryption key (keyAgreement) to the entity");let c=await this.wallet.signXClient.transact([s],this.wallet.wallet);return this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(c)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),await he({roomId:t.matrixRoomId,accessToken:t.matrixAccessToken,homeServerUrl:i,verificationMethodId:o.verificationMethodId}),S.log.success(`P-256 encryption key published to entity DID: ${t.entityDid}`),S.log.info(`Verification method ID: ${o.verificationMethodId}`),{success:!0,data:`Encryption key setup complete for ${t.entityDid}`}}catch(n){return{success:!1,error:n instanceof Error?n.message:String(n)}}}};import{toHex as li}from"@cosmjs/encoding";import{createRegistry as di}from"@ixo/impactxclient-sdk";import{SignX as nr,SIGN_X_LOGIN_ERROR as mi,SIGN_X_LOGIN_SUCCESS as pi,SIGN_X_TRANSACT_ERROR as gi,SIGN_X_TRANSACT_SUCCESS as ui}from"@ixo/signx-sdk";import fi from"qrcode-terminal";var or={devnet:"https://signx.devnet.ixo.earth",testnet:"https://signx.testnet.ixo.earth",mainnet:"https://signx.ixo.earth"},Q=class{signXClient;_loginData;get loginData(){return this._loginData}static loadFromWallet(e){return new nr({endpoint:or[e.network],sitename:"QiForge CLI",network:e.network})}constructor(e){this.signXClient=new nr({endpoint:or[e],sitename:"QiForge CLI",network:e})}async login(){let e=await this.signXClient.login({pollingInterval:2e3,matrix:!0});return this._loginData=e,e}displayStyledQRCode(e,t){let i=typeof e=="string"?e:JSON.stringify(e);console.log(`
149
+ `+" ".repeat(5)+"\u{1F510} "+t),console.log(" ".repeat(5)+"\u{1F4F1} Scan with IXO app"),console.log(" ".repeat(5)+"\u2501".repeat(30)),fi.generate(i,{small:!0}),console.log(" ".repeat(5)+`\u23F3 Waiting...
150
+ `)}displayQRCode(e){this.displayStyledQRCode(e,"Login with SignX")}async awaitLogin(){return new Promise((e,t)=>{try{this.signXClient.on(pi,i=>{if(!i.data){t(new Error("Login failed"));return}if(!i.data.matrix){t(new Error("Matrix login failed"));return}e(i.data)}),this.signXClient.on(mi,i=>{console.log("Login error:",i),t(i)})}catch(i){console.error("Error in connecting:",i),t(i)}})}async transact(e,t,i){let n=di();return this.signXClient.transact({address:t.address,did:t.did,pubkey:t.pubKey,timestamp:new Date().toISOString(),transactions:[{sequence:1,txBodyHex:li(n.encodeTxBody({messages:e,memo:i||""}))}]})}async awaitTransaction(){return new Promise((e,t)=>{try{this.signXClient.on(ui,i=>{e(i.data)}),this.signXClient.on(gi,i=>{t(i)})}catch(i){console.error("Error in connecting:",i),t(i)}})}async pollNextTransaction(){return this.signXClient.pollNextTransaction()}displayTransactionQRCode(e){this.displayStyledQRCode(e,"SIGNX TRANSACTION")}};var Ie=class{constructor(e,t){this.wallet=e;this.config=t}name="signx-login";description="Login with SignX wallet";async execute(){try{let e=await T(this.config),t=new Q(e),i=await t.login();t.displayQRCode(i);let n=await t.awaitLogin();return this.wallet.setWallet(n),this.wallet.setSignXClient(t),{success:!0,data:{message:"Successfully logged in with SignX!",wallet:{address:n.address,did:n.did,name:n.name}}}}catch(e){return{success:!1,error:e instanceof Error?`SignX login failed: ${e.message}`:"Unknown error"}}}};import*as $ from"@clack/prompts";var be=class{constructor(e,t){this.wallet=e;this.config=t}name="update-oracle-api-url";description="Update the oracle API domain (default is localhost)";async execute(){this.config.getValue("network")||await T(this.config);let t=await $.group({entityDid:()=>$.text({message:"What is the DID of the entity you want to update?",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(i){return D(i)}}),apiUrl:()=>$.text({message:"What is the new API URL (domain) for the oracle?",initialValue:"http://localhost:4000",validate(i){return j(i,"API URL is required and must be a valid URL")}})},{onCancel:()=>{$.cancel("Operation cancelled."),process.exit(0)}});try{let i=new B(this.wallet,this.config);return $.log.info(`Updating oracle domain for entity ${t.entityDid} to ${t.apiUrl}`),await i.updateOracleDomain(t.entityDid,t.apiUrl),{success:!0,data:`Oracle domain updated to ${t.apiUrl} for entity ${t.entityDid}`}}catch(i){return{success:!1,error:i instanceof Error?i.message:String(i)}}}};import*as b from"@clack/prompts";var Ae=class{constructor(e,t){this.wallet=e;this.config=t;this.createEntity=new B(this.wallet,this.config)}name="update-entity";description="Update an entity (add controllers, etc.)";createEntity;async execute(){this.config.getValue("network")||await T(this.config);let t=await b.group({entityDid:()=>b.text({message:"What is the DID of the entity you want to update?",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(i){return D(i)}}),action:()=>b.select({message:"What would you like to do?",options:[{value:"add-controller",label:"Add Controller",hint:"Add a new controller DID to the entity"}],initialValue:"add-controller"}),controllerDid:async({results:i})=>{if(i.action!=="add-controller")throw new Error("Unknown action");let n=await b.text({message:"What is the DID of the controller you want to add?",validate(o){return D(o)}});return b.isCancel(n)&&(b.cancel("Operation cancelled."),process.exit(0)),n}},{onCancel:()=>{b.cancel("Operation cancelled."),process.exit(0)}});try{if(t.action==="add-controller"&&typeof t.controllerDid=="string"){let i=t.controllerDid,n=t.entityDid;return b.log.info(`Adding controller ${i} to entity ${n}`),await this.createEntity.addControllerToEntity(n,i),b.log.success(`Controller ${i} successfully added to entity ${n}`),{success:!0,data:`Controller ${i} added to entity ${n}`}}return{success:!1,error:"Unknown action"}}catch(i){return{success:!1,error:i instanceof Error?i.message:String(i)}}}};var Ye=class extends Error{constructor(t,i="CLI_ERROR",n){super(t);this.code=i;this.suggestions=n;this.name="CLIError"}};function Te(r){r instanceof Ye&&(console.error(`
142
151
  \u274C ${r.name}: ${r.message}`),r.suggestions?.length&&(console.error(`
143
152
  Suggestions:`),r.suggestions.forEach(e=>console.error(` \u2022 ${e}`))),process.exit(1)),r instanceof Error&&(console.error(`
144
153
  \u274C Unexpected Error: ${r.message}`),r.stack&&(console.error(`
145
154
  Stack trace:`),console.error(r.stack)),process.exit(1)),console.error(`
146
- \u274C Unknown error occurred`,r),process.exit(1)}var Ce=class r{config={};static instance;constructor(){}static getInstance(){return r.instance||(r.instance=new r),r.instance}addValue(e,t){this.config[e]=t}getValue(e){return this.config[e]}getOrThrow(e){let t=this.getValue(e);if(!t)throw new Error(`Value ${e} is not set`);return t}getConfig(){return this.config}deleteValue(e){delete this.config[e]}};import{log as N}from"@clack/prompts";import{cosmos as Dt}from"@ixo/impactxclient-sdk";import{existsSync as je,readFileSync as Br,writeFileSync as jr}from"fs";import{unlink as Vr}from"fs/promises";import Fr from"os";import qr from"path";var $=qr.join(Fr.homedir(),".wallet.json"),Re=class{wallet;signXClient;config;constructor(e){this.config=e,this.loadWallet()}setSignXClient(e){this.signXClient=e}loadWallet(){if(je($))try{let e=Br($,"utf8");if(this.wallet=JSON.parse(e),!this.wallet.matrix?.userId||!this.wallet.matrix.userId.includes(":")){N.warning("Wallet is missing valid Matrix credentials. Please re-authenticate via SignX."),this.wallet=void 0;return}let t=this.wallet.network;if(!t){let i=this.wallet.matrix.userId.split(":")[1];if(t={"devmx.ixo.earth":"devnet","testmx.ixo.earth":"testnet","mx.ixo.earth":"mainnet"}[i],!t)throw new Error(`Cannot determine network from matrix domain: ${i}`);this.wallet.network=t}this.config.addValue("network",t),this.setSignXClient(new q(t)),N.success(`Welcome back, ${this.wallet.name}!`),N.info(`Network: ${t}`)}catch(e){N.warning(`Failed to load wallet file: ${e instanceof Error?e.message:String(e)}`),this.wallet=void 0}else N.warning("No wallet file found")}setWallet(e){try{this.wallet=e;let t=JSON.stringify(e,null,2);jr($,t,"utf8"),N.success(`Wallet saved successfully to: ${$}`)}catch(t){throw N.error(`Failed to save wallet: ${t instanceof Error?t.message:String(t)}`),new Error("Failed to save wallet file")}}checkWalletExists(){return je($)&&this.wallet!==void 0}async clearWallet(){this.wallet=void 0;try{je($)&&(await Vr($),N.success("Wallet file deleted successfully"))}catch(e){N.error(`Failed to delete wallet file: ${e instanceof Error?e.message:String(e)}`)}}get did(){return this.wallet?.did}get address(){return this.wallet?.address}get name(){return this.wallet?.name}get pubKey(){return this.wallet?.pubKey}get algo(){return this.wallet?.algo}get matrix(){return this.wallet?.matrix}get matrixHomeServer(){let e=this.wallet?.matrix?.userId;return!e||!e.includes(":")?void 0:`https://${e.split(":")[1]}`}reloadWallet(){this.loadWallet()}async sendTokens(e,t){if(!this.address||!this.signXClient||!this.wallet)throw new Error("Wallet not loaded");let i={typeUrl:"/cosmos.bank.v1beta1.MsgSend",value:Dt.bank.v1beta1.MsgSend.fromPartial({fromAddress:this.address,toAddress:e,amount:[Dt.base.v1beta1.Coin.fromPartial({amount:t.toString(),denom:"uixo"})]})},n=await this.signXClient?.transact([i],this.wallet);return this.signXClient?.displayTransactionQRCode(JSON.stringify(n)),await this.signXClient?.pollNextTransaction(),await this.signXClient?.awaitTransaction()}};var Fe=class{registry;config;wallet;constructor(){this.registry=new Z,this.config=Ce.getInstance(),this.wallet=new Re(this.config)}registerCommands(){this.registry.register(new ue(this.config,this.wallet)),this.registry.register(new V(this.wallet,this.config)),this.registry.register(new xe(this.wallet,this.config)),this.registry.register(new we(this.wallet,this.config)),this.registry.register(new he(this.wallet,this.config)),this.registry.register(new de(this.wallet,this.config)),this.registry.register(new fe(this.wallet)),this.registry.register(new z(this.registry))}async showHelp(){this.wallet.setWallet({address:"0x0000000000000000000000000000000000000000",algo:"secp",did:"did:ixo:entity:1a76366f16570483cea72b111b27fd78",network:"devnet",name:"My oracle",pubKey:"0x0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",ledgered:!1,matrix:{accessToken:"",userId:"0x0000000000000000000000000000000000000000",address:"",roomId:""}}),this.registerCommands();let t=await new z(this.registry).execute();t.success&&t.data&&console.log(t.data)}async handleAuthentication(){if(!this.wallet.checkWalletExists()){let e=await Lt({message:"Login with SignX",options:[{value:"login",label:"Login"},{value:"exit",label:"Exit"}]});switch(_t(e)&&(Ve("Operation cancelled."),K.exit(0)),String(e)){case"login":{(await new ye(this.wallet,this.config).execute()).success&&Q.success("Login successful");return}case"exit":{Ve("Operation cancelled."),K.exit(0);return}default:throw new Error(`Unknown command: ${e}`)}}}async executeCommand(e){let t=this.registry.get(e);if(!t)throw new Error(`Unknown command: ${e}`);let i=Yr();i.start(`Executing ${t.name}...`);let n=await t.execute();i.stop(`${t.name} completed`),n.success?(Q.success(`${t.name} completed successfully!`),n.data&&Q.info(JSON.stringify(n.data,null,2))):Q.error(`${t.name} failed: ${n.error}`)}async interactiveMode(){Hr("IXO CLI"),Q.warn("Keep your IXO Mobile App open while running the CLI; So u do not interrupt the signX session"),await this.handleAuthentication(),this.registerCommands();let e=await Lt({message:`Welcome ${this.wallet.name}, what would you like to do?`,options:[...this.registry.getCommandOptions()],initialValue:"init"});_t(e)&&(Ve("Operation cancelled."),K.exit(0)),await this.executeCommand(String(e))}async argumentMode(e){let t=e[0];if(!t){await this.interactiveMode();return}if(t==="--init"){await this.handleAuthentication(),this.registerCommands(),await this.executeCommand("init");return}if(t==="--help"||t==="-h"){await this.showHelp();return}await this.handleAuthentication(),this.registerCommands(),await this.executeCommand(t)}async run(e){try{let t=e.slice(2);t.length===0?await this.interactiveMode():await this.argumentMode(t)}catch(t){ve(t)}Gr("Thanks for using IXO CLI!"),K.exit(0)}};K.on("uncaughtException",ve);K.on("unhandledRejection",ve);var Jr=new Fe;Jr.run(K.argv);
155
+ \u274C Unknown error occurred`,r),process.exit(1)}var ke=class r{config={};static instance;constructor(){}static getInstance(){return r.instance||(r.instance=new r),r.instance}addValue(e,t){this.config[e]=t}getValue(e){return this.config[e]}getOrThrow(e){let t=this.getValue(e);if(!t)throw new Error(`Value ${e} is not set`);return t}getConfig(){return this.config}deleteValue(e){delete this.config[e]}};import{log as L}from"@clack/prompts";import{cosmos as sr}from"@ixo/impactxclient-sdk";import{existsSync as ze,readFileSync as hi,writeFileSync as yi}from"fs";import{unlink as wi}from"fs/promises";import xi from"os";import vi from"path";var F=vi.join(xi.homedir(),".wallet.json"),Pe=class{wallet;signXClient;config;constructor(e){this.config=e,this.loadWallet()}setSignXClient(e){this.signXClient=e}loadWallet(){if(ze(F))try{let e=hi(F,"utf8");if(this.wallet=JSON.parse(e),!this.wallet.matrix?.userId||!this.wallet.matrix.userId.includes(":")){L.warning("Wallet is missing valid Matrix credentials. Please re-authenticate via SignX."),this.wallet=void 0;return}let t=this.wallet.network;if(!t){let i=this.wallet.matrix.userId.split(":")[1];if(t={"devmx.ixo.earth":"devnet","testmx.ixo.earth":"testnet","mx.ixo.earth":"mainnet"}[i],!t)throw new Error(`Cannot determine network from matrix domain: ${i}`);this.wallet.network=t}this.config.addValue("network",t),this.setSignXClient(new Q(t)),L.success(`Welcome back, ${this.wallet.name}!`),L.info(`Network: ${t}`)}catch(e){L.warning(`Failed to load wallet file: ${e instanceof Error?e.message:String(e)}`),this.wallet=void 0}else L.warning("No wallet file found")}setWallet(e){try{this.wallet=e;let t=JSON.stringify(e,null,2);yi(F,t,"utf8"),L.success(`Wallet saved successfully to: ${F}`)}catch(t){throw L.error(`Failed to save wallet: ${t instanceof Error?t.message:String(t)}`),new Error("Failed to save wallet file")}}checkWalletExists(){return ze(F)&&this.wallet!==void 0}async clearWallet(){this.wallet=void 0;try{ze(F)&&(await wi(F),L.success("Wallet file deleted successfully"))}catch(e){L.error(`Failed to delete wallet file: ${e instanceof Error?e.message:String(e)}`)}}get did(){return this.wallet?.did}get address(){return this.wallet?.address}get name(){return this.wallet?.name}get pubKey(){return this.wallet?.pubKey}get algo(){return this.wallet?.algo}get matrix(){return this.wallet?.matrix}get matrixHomeServer(){let e=this.wallet?.matrix?.userId;return!e||!e.includes(":")?void 0:`https://${e.split(":")[1]}`}reloadWallet(){this.loadWallet()}async sendTokens(e,t){if(!this.address||!this.signXClient||!this.wallet)throw new Error("Wallet not loaded");let i={typeUrl:"/cosmos.bank.v1beta1.MsgSend",value:sr.bank.v1beta1.MsgSend.fromPartial({fromAddress:this.address,toAddress:e,amount:[sr.base.v1beta1.Coin.fromPartial({amount:t.toString(),denom:"uixo"})]})},n=await this.signXClient?.transact([i],this.wallet);return this.signXClient?.displayTransactionQRCode(JSON.stringify(n)),await this.signXClient?.pollNextTransaction(),await this.signXClient?.awaitTransaction()}};var Ze=class{registry;config;wallet;constructor(){this.registry=new se,this.config=ke.getInstance(),this.wallet=new Pe(this.config)}registerCommands(){this.registry.register(new Re(this.config,this.wallet)),this.registry.register(new Y(this.wallet,this.config)),this.registry.register(new Ae(this.wallet,this.config)),this.registry.register(new be(this.wallet,this.config)),this.registry.register(new Se(this.wallet,this.config)),this.registry.register(new we(this.wallet,this.config)),this.registry.register(new ce(this.wallet,this.config)),this.registry.register(new Ee(this.wallet)),this.registry.register(new oe(this.registry))}async showHelp(){this.wallet.setWallet({address:"0x0000000000000000000000000000000000000000",algo:"secp",did:"did:ixo:entity:1a76366f16570483cea72b111b27fd78",network:"devnet",name:"My oracle",pubKey:"0x0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",ledgered:!1,matrix:{accessToken:"",userId:"0x0000000000000000000000000000000000000000",address:"",roomId:""}}),this.registerCommands();let t=await new oe(this.registry).execute();t.success&&t.data&&console.log(t.data)}async handleAuthentication(){if(!this.wallet.checkWalletExists()){let e=await cr({message:"Login with SignX",options:[{value:"login",label:"Login"},{value:"exit",label:"Exit"}]});switch(ar(e)&&(Qe("Operation cancelled."),q.exit(0)),String(e)){case"login":{(await new Ie(this.wallet,this.config).execute()).success&&Z.success("Login successful");return}case"exit":{Qe("Operation cancelled."),q.exit(0);return}default:throw new Error(`Unknown command: ${e}`)}}}async executeCommand(e){let t=this.registry.get(e);if(!t)throw new Error(`Unknown command: ${e}`);if(t.interactive){let o=await t.execute();!o.success&&o.error&&Z.error(`${t.name} failed: ${o.error}`);return}let i=Ei();i.start(`Executing ${t.name}...`);let n=await t.execute();i.stop(`${t.name} completed`),n.success?(Z.success(`${t.name} completed successfully!`),n.data&&Z.info(JSON.stringify(n.data,null,2))):Z.error(`${t.name} failed: ${n.error}`)}async interactiveMode(){Ci("IXO CLI"),Z.warn("Keep your IXO Mobile App open while running the CLI; So u do not interrupt the signX session"),await this.handleAuthentication(),this.registerCommands();let e=await cr({message:`Welcome ${this.wallet.name}, what would you like to do?`,options:[...this.registry.getCommandOptions()],initialValue:"init"});ar(e)&&(Qe("Operation cancelled."),q.exit(0)),await this.executeCommand(String(e))}async argumentMode(e){let t=e[0];if(!t){await this.interactiveMode();return}if(t==="--init"){await this.handleAuthentication(),this.registerCommands(),await this.executeCommand("init");return}if(t==="--chat"||t==="chat"){await this.handleAuthentication(),this.registerCommands(),await this.executeCommand("chat");return}if(t==="--help"||t==="-h"){await this.showHelp();return}await this.handleAuthentication(),this.registerCommands(),await this.executeCommand(t)}async run(e){try{let t=e.slice(2);t.length===0?await this.interactiveMode():await this.argumentMode(t)}catch(t){Te(t)}Ri("Thanks for using IXO CLI!"),q.exit(0)}};q.on("uncaughtException",Te);q.on("unhandledRejection",Te);var Si=new Ze;Si.run(q.argv);
147
156
  //# sourceMappingURL=cli.js.map