qiforge-cli 1.3.0 → 1.3.1
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 +24 -22
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{cancel as
|
|
3
|
-
`)}function _(r){
|
|
4
|
-
`)}function
|
|
2
|
+
import{cancel as Ze,intro as vi,isCancel as sr,log as Z,outro as Ci,select as ar,spinner as Ri}from"@clack/prompts";import H from"process";var ae=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 rt from"@clack/prompts";function De(r){process.stdout.write(r)}function it(r,e){process.stdout.write(`\x1B[2m[Tool] ${r}(${e})\x1B[0m
|
|
3
|
+
`)}function _(r){rt.log.error(r)}function nt(){process.stdout.write(`
|
|
4
|
+
`)}function ot(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 mr}from"@clack/prompts";import{z as G}from"zod";var T=async r=>{let e=await mr({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},st={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"},at={devnet:"https://rooms.bot.devmx.ixo.earth",testnet:"https://rooms.bot.testmx.ixo.earth",mainnet:"https://rooms.bot.mx.ixo.earth"};var ct={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/"},Le={devnet:"https://mcp-memory-engine.devnet.ixo.earth/",testnet:"https://mcp-memory-engine.testnet.ixo.earth/",mainnet:"https://mcp-memory-engine.ixo.earth/"},re={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/"},P=(r,e="This field is required")=>{let i=G.string().min(1,e).safeParse(r);if(!i.success)return i.error.message},D=r=>{let t=G.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=G.url(e).safeParse(r);if(!i.success)return i.error.message},lt=(r,e="This number is required")=>{let i=G.number().min(1,e).safeParse(r);if(!i.success)return i.error.message},J=r=>{let t=G.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"},ce=r=>{let t=G.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 dt(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 ie(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 mt({userDid:r,oracleEntityDid:e,matrixAccessToken:t,network:i}){let n=at[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 ie(`${n}/spaces/source`,{did:r}),m=Object.values(c.subspaces??{}).map(a=>a.space_id).filter(Boolean);X.step("Joining main space..."),await ie(`${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=>ie(`${o}/_matrix/client/v3/join/${a}`,{},s)))),X.step("Creating oracle room...");let d=await ie(`${n}/spaces/oracle/create`,{did:r,oracleDid:e},s);X.step(`Joining oracle room: ${d.roomId}`),await ie(`${o}/_matrix/client/v3/join/${d.roomId}`,{},s),X.success("Matrix room ready")}async function pt(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 gt(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 ut(r,e,t){await fetch(`${r}/sessions/${encodeURIComponent(e)}`,{method:"DELETE",headers:{"x-matrix-access-token":t},signal:AbortSignal.timeout(3e4)})}async function ft(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 ht(r){try{return(await fetch(r,{signal:AbortSignal.timeout(5e3)})).ok}catch{return!1}}import{existsSync as le,readFileSync as pr,writeFileSync as yt}from"fs";import B from"path";import{z as O}from"zod";var gr=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 wt(r,e){let t=JSON.stringify(e,null,2),i=B.join(r,"oracle.config.json");yt(i,t,"utf8");let n=B.join(r,"apps","app","oracle.config.json");le(B.dirname(n))&&yt(n,t,"utf8")}function xt(r){let e=r??ur();if(!e)return;let t=B.join(e,"oracle.config.json");if(le(t))try{let i=pr(t,"utf8"),n=gr.safeParse(JSON.parse(i));return n.success?n.data:void 0}catch{return}}function ur(){let r=process.cwd(),e=B.parse(r).root;for(;r!==e;){if(le(B.join(r,"oracle.config.json"))||le(B.join(r,"pnpm-workspace.yaml")))return r;r=B.dirname(r)}}async function*vt(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
5
|
|
|
6
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
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
|
|
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:`
|
|
8
|
+
`),u;try{u=JSON.parse(l)}catch{u=l}yield{event:d,data:u}}}}finally{t.releaseLock()}}var de=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 pt(i,t.userId,t.accessToken),this.openIdTokenExpiresAt=e+this.openIdToken.expires_in*1e3}return this.openIdToken.access_token}async execute(){let e=xt(),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 ht(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 mt({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 gt(t,l)).sessionId}catch(g){let p=g instanceof Error?g.message:String(g);return _(`Failed to create session: ${p}`),{success:!1,error:p}}ot(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 ft(t,u,p,l,this.abortController.signal);for await(let C of vt(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&&De(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??{});it(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"&&De(C.data);break}}nt()}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 ut(t,u,l)}catch{}}return A.log.info("Goodbye!"),{success:!0}}};import*as v from"@clack/prompts";import{isCancel as ri,log as w,spinner as ii,text as ni}from"@clack/prompts";import{customMessages as er,ixo as E,utils as Je}from"@ixo/impactxclient-sdk";import{sha256 as Pr}from"@cosmjs/crypto";import{encrypt as Or}from"eciesjs";import{ClientEvent as Nr,createClient as Be}from"matrix-js-sdk";import Ur from"md5";var me=new Map;function fr(r){return me.get(r)instanceof Uint8Array}function hr(r){return me.get(r)}function We(){me.clear()}async function Ct({keys:r}){let e=Object.keys(r),t=e.find(fr);if(console.info("[] getSecretStorageKey",r,e,t),!t)return null;let i=hr(t);return[t,i]}function Rt(r,e,t){me.set(r,t)}import{Bip39 as bt,EnglishMnemonic as At,Secp256k1 as je,sha256 as xr,Slip10 as Tt,Slip10Curve as kt,stringToPath as Pt}from"@cosmjs/crypto";import{DirectSecp256k1HdWallet as vr}from"@cosmjs/proto-signing";import{createQueryClient as Ot,createSigningClient as Cr,customMessages as Rr,ixo as Er,utils as Sr}from"@ixo/impactxclient-sdk";import{createCipheriv as Ir,randomBytes as br}from"crypto";import{createRegistry as yr,utils as wr}from"@ixo/impactxclient-sdk";function ne(r){try{return wr.proto.fromTimestamp(r).getTime()}catch{return}}var pe={BasicAllowance:"/cosmos.feegrant.v1beta1.BasicAllowance",PeriodicAllowance:"/cosmos.feegrant.v1beta1.PeriodicAllowance"},Et=r=>{let e=yr();return(r??[]).map(t=>{let i=t.allowance,n=e.decode(i);switch(i.typeUrl){case pe.BasicAllowance:return{granter:t.granter,grantee:t.grantee,type:pe.BasicAllowance,expiration:n.expiration?ne(n.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};case pe.PeriodicAllowance:return{granter:t.granter,grantee:t.grantee,type:pe.PeriodicAllowance,expiration:n.basic?.expiration?ne(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?ne(n.expiration):n.basic?.expiration?ne(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}}})},St=r=>{if(r==null)return!1;let e=typeof r=="object"?ne(r):r;return e==null?!0:e<Date.now()},It=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 Ot(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 Nt(r,e,t,i){try{let n=await t.getAccounts(),{address:o,pubkey:s}=n[0]??{},c=await Ar(o,e),m=c?.length?Et(c)?.find(a=>!!a&&!St(a.expiration)&&!It(a.limit))?.granter:void 0,d={typeUrl:"/ixo.iid.v1beta1.MsgCreateIidDocument",value:Er.iid.v1beta1.MsgCreateIidDocument.fromPartial({id:r,verifications:Rr.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:[d],feegrantGranter:m,network:e})}catch(n){throw console.error(n),n}}async function Ar(r,e){try{let t=W[e];if(!t)throw new Error(`Invalid network: ${e}`);return(await(await Ot(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=W[n];if(!o)throw new Error(`Invalid network: ${n}`);let s=await Cr(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=kr(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}`)},kr=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}},ge=r=>new Promise(e=>setTimeout(e,r));function ue(r,e){let t=br(16),i=Ir("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 Ut=async r=>{let e=await vr.fromMnemonic(r,{prefix:"ixo"}),t=(await e.getAccounts())[0],i=await bt.mnemonicToSeed(new At(r)),n=Pt("m/44'/118'/0'/0/0"),s=Tt.derivePath(kt.Secp256k1,i,n).privkey,c=await je.makeKeypair(s),m=je.compressPubkey(c.pubkey);return{mnemonic:r,did:Sr.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 bt.mnemonicToSeed(new At(r)),u=Pt("m/44'/118'/0'/0/0"),{privkey:g}=Tt.derivePath(kt.Secp256k1,l,u),p=new Uint8Array(Buffer.from(a,"base64")),x=xr(p);return(await je.createSignature(x,g)).toFixedLength().slice(0,64)}catch(l){throw console.error("Error during signature creation:",l),l}}}};var Mr="/.well-known/matrix/client",Ve=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 jr(o));try{let m=Dt(o),d=await m.login("m.login.password",{identifier:{type:"m.id.user",user:Xr(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)}};async function _r(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 Dr(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 $r(r,e){let t=new Uint8Array(Buffer.from(e,"hex")),i=new Uint8Array(Buffer.from(r,"utf8")),n=Or(t,i);return Array.from(n,o=>o.toString(16).padStart(2,"0")).join("")}async function Lr(r,e,t,i,n,o){let s=await _r(o),c=$r(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 Mt(r,e,t,i,n,o){try{let{challengeBase64:s}=Dr(r),c=await i.sign(s),m=Buffer.from(c).toString("base64");if(!(await Lr(r,e,m,s,n,o)).success)throw new Error("Failed to create matrix account via API");let a=Fe(r);return await Ve({homeServerUrl:n,username:a,password:e,deviceName:t})}catch(s){throw console.error("mxRegisterWithSecp error:",s),s}}async function _t({homeServerUrl:r,username:e}){let t=Dt(r);try{return!!await t.isUsernameAvailable(e)}catch{return!1}}function Dt(r){if(!r)throw new Error("Home server URL is required to instantiate matrix client");return Be({baseUrl:r})}async function $t({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:Ct,cacheSecretStorageKey:Rt},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(Nr.Sync,m=>{c[m]()})}),n}async function fe({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 Lt(r){let e=r.getAccountData("m.cross_signing.master");return console.log("hasCrossSigningAccountData::masterKeyData",e),!!e}async function Kt(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(Br({userId:s,password:t}))},setupNewCrossSigning:i}),await o.resetKeyBackup(),await ge(300),!!r.getAccountData("m.cross_signing.master")}function Fe(r){if(!r)throw new Error("Address is required to generate matrix username");return"did-ixo-"+r}function Wt(r){return Buffer.from(Ur(r.replace(/ /g,""))).toString("base64").slice(0,24)}function jt(r){let e=Pr(new TextEncoder().encode(r.replace(/ /g,"")));return Buffer.from(e).toString("base64").slice(0,32)}function Kr(r){return r.replace(/^(https?:\/\/)/,"").replace(/\/$/,"")}function Wr(r,e=""){return"did-ixo-"+r+e}function Xt(r,e){return"#"+Wr(r)+":"+Kr(e)}async function jr(r){let e="https://";/^https?:\/\//.test(r)&&(e="");let t=`${e}${r}${Mr}`;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 Xr(r){return(r.indexOf("@")===0?r.substring(1):r).trim()}function Br({userId:r,password:e}){return{type:"m.login.password",password:e,identifier:{type:"m.id.user",user:r}}}import{ixo as Vr,utils as qe}from"@ixo/impactxclient-sdk";import{createMatrixApiClient as Fr}from"@ixo/matrixclient-sdk";var Bt="Oracles CLI";async function he({pin:r,oracleName:e,network:t,oracleAvatarUrl:i,matrixHomeServerUrl:n},o){try{let{homeServerUrl:s,roomBotUrl:c}=dt(n),m=qe.mnemonic.generateMnemonic(),d=await Ut(m),a=d.baseAccount.address;console.log("\u2705 Wallet created:",a),await o(a);let l=qe.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 F=Vr.iid.v1beta1.Service.fromPartial({id:`${l}#matrix`,type:"MatrixHomeServer",serviceEndpoint:s});if(await Nt(l,t,d,[F]),console.log("\u2705 DID created, waiting 500ms..."),await ge(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=qe.mnemonic.generateMnemonic(12),p=Fe(a),x=Wt(g),C=jt(g);if(!await _t({homeServerUrl:s,username:p}))throw new Error("Matrix account already exists");let R=await Mt(a,x,Bt,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 $t({homeServerUrl:s,accessToken:R.accessToken,userId:R.userId,deviceId:R.deviceId});try{await Promise.all([N.setDisplayName(e),N.setAvatarUrl(i)])}catch(F){console.error("Failed to set display name or avatar url:",F)}let U=Fr({homeServerUrl:s,accessToken:R.accessToken}),Ue=Lt(N);if(!Ue&&(Ue=await Kt(N,{securityPhrase:C,password:x,forceReset:!0}),!Ue))throw new Error("Failed to setup cross signing");console.log("\u2705 Matrix cross-signing setup completed");let cr=Xt(a,R.baseUrl),M=(await U.room.v1beta1.queryId(cr).catch(()=>{}))?.room_id??"";if(!M){let F=await fetch(`${c}/room/source`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({did:l,userMatrixId:R.userId})});if(!F.ok)throw new Error("Failed to create matrix room");if(M=(await F.json()).roomId,!M)throw new Error("Failed to create user matrix room")}let Me=await U.room.v1beta1.listJoinedMembers(M).catch(()=>{}),_e=!!Me?.joined?.[R.userId];if(!_e){if(!(await U.room.v1beta1.join(M)).room_id)throw new Error("Failed to join matrix room");if(Me=await U.room.v1beta1.listJoinedMembers(M),_e=!!Me?.joined?.[R.userId],!_e)throw new Error("Failed to join matrix room")}console.log("\u2705 Matrix room created/joined:",M);let lr=ue(g,r),tt=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:lr})});if(!tt.ok)throw new Error("Failed to store encrypted mnemonic in matrix room");return await tt.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:Bt}}catch(s){throw console.error("Simplified registration failed:",s),s}}import{ixo as He}from"@ixo/impactxclient-sdk";import qr from"bs58";import{randomUUID as Ft}from"crypto";import{exportJWK as Vt,generateKeyPair as Hr}from"jose";var qt="ixo.room.encryption_key.index",Ht="p256_encryption",Gr="ixo.room.encryption_key";function Jr(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 Yr(r){let e=new Uint8Array(2+r.length);return e[0]=128,e[1]=36,e.set(r,2),"z"+qr.encode(e)}async function Ge(r,e,t){let i=await fetch(`${t}/_matrix/client/v3/rooms/${encodeURIComponent(r)}/state/${qt}/${Ht}`,{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 zr(r,e,t,i){let n=`enc_key_${Ft()}`,o=await fetch(`${t}/_matrix/client/v3/rooms/${encodeURIComponent(r)}/send/${Gr}/${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 Gt(r,e,t,i){let n=await fetch(`${t}/_matrix/client/v3/rooms/${encodeURIComponent(r)}/state/${qt}/${Ht}`,{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 Jt(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 Yt(r,e,t){let i=await Ge(r,e,t);return i?.keys?Object.values(i.keys).some(n=>n.active):!1}async function ye(r){let{roomId:e,accessToken:t,homeServerUrl:i,pin:n,oracleEntityDid:o}=r,s=await Ge(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=Ft(),{privateKey:m,publicKey:d}=await Hr("ECDH-ES",{crv:"P-256",extractable:!0}),a=await Vt(m);a.alg="ECDH-ES+A256KW";let l=await Vt(d);l.alg="ECDH-ES+A256KW";let u=ue(JSON.stringify(a),n),g=await zr(e,t,i,u),p=Jr(l),x=Yr(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 Gt(e,t,i,R),{publicKeyMultibase:x,verificationMethodId:C}}async function we(r){let{roomId:e,accessToken:t,homeServerUrl:i,verificationMethodId:n}=r,o=await Ge(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 Gt(e,t,i,o)}function xe(r){return{typeUrl:"/ixo.iid.v1beta1.MsgAddVerification",value:He.iid.v1beta1.MsgAddVerification.fromPartial({id:r.oracleEntityDid,verification:He.iid.v1beta1.Verification.fromPartial({relationships:["keyAgreement"],method:He.iid.v1beta1.VerificationMethod.fromPartial({id:r.verificationMethodId,type:"Multikey",controller:r.oracleEntityDid,publicKeyMultibase:r.publicKeyMultibase})}),signer:r.signerAddress})}}import{createMatrixApiClient as ei,utils as ti}from"@ixo/matrixclient-sdk";import{CID as Qr}from"multiformats";import{base64 as Zr}from"multiformats/bases/base64";import*as zt from"multiformats/hashes/sha2";async function Qt(r){let e=r.startsWith("m")?r:"m"+r,t=Zr.decode(e),i=await zt.sha256.digest(t);return Qr.create(1,85,i).toString()}function Zt(r){let e=new TextEncoder().encode(r);return btoa(String.fromCharCode(...Array.from(e)))}var oe=async({data:r,fileName:e,homeServerUrl:t,accessToken:i})=>{let n=ei({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=ti.mxc.mxcUrlToHttp(t,d.content_uri);if(!a)throw new Error("Failed to upload file to Matrix");let l=JSON.stringify(r),u=Zt(l),g=await Qt(u);return{encrypted:"false",cid:g,proof:g,serviceEndpoint:a,mxc:d.content_uri}};var V=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:[...er.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:st[this.config.getValue("network")??"devnet"],service:[E.iid.v1beta1.Service.fromPartial({id:"{id}#matrix",type:"MatrixHomeServer",serviceEndpoint:e})],linkedResource:[],accordedRight:[],linkedEntity:[],linkedClaim:[],startDate:Je.proto.toTimestamp(new Date),endDate:Je.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 oe({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 oe({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 oe({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 oe({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(...er.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 ni({message:"Enter a 6-digit PIN to secure your Matrix Vault:",placeholder:"123456",validate(p){return J(p)}});ri(i)&&(w.error("User cancelled"),process.exit(1));let n=await he({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=Je.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 ye({roomId:n.matrixRoomId,accessToken:s,homeServerUrl:o,pin:i,oracleEntityDid:l}),x=xe({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 we({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 fe({baseUrl:o,accessToken:s,userId:n.matrixUserId,deviceId:""});let g=ii();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 ce(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 lt(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 V(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{wt(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=`${ct[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 ve=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 ce(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 J(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 he({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 fe({baseUrl:s.matrixHomeServerUrl,accessToken:s.matrixAccessToken,userId:s.matrixUserId,deviceId:""}),{success:!0,data:s}}};var se=class{constructor(e){this.registry=e}name="help";description="Show help information and available commands";async execute(){return{success:!0,data:`
|
|
10
10
|
QiForge CLI - Help
|
|
11
11
|
|
|
12
12
|
USAGE:
|
|
@@ -28,7 +28,7 @@ OPTIONS:
|
|
|
28
28
|
--help, -h Show help information
|
|
29
29
|
|
|
30
30
|
For more information, visit: https://www.npmjs.com/package/qiforge-cli
|
|
31
|
-
`}}};import*as y from"@clack/prompts";import{existsSync as
|
|
31
|
+
`}}};import*as y from"@clack/prompts";import{existsSync as Ee}from"fs";import z from"path";import rr from"simple-git";import Re from"fs";import Ce from"path";function oi(r,e){return`
|
|
32
32
|
PORT=4000
|
|
33
33
|
ORACLE_NAME=${e.oracleName}
|
|
34
34
|
|
|
@@ -61,13 +61,13 @@ OPENAI_API_KEY=
|
|
|
61
61
|
OPEN_ROUTER_API_KEY=
|
|
62
62
|
|
|
63
63
|
# External Services (configure these for your deployment)
|
|
64
|
-
MEMORY_MCP_URL=${
|
|
65
|
-
MEMORY_ENGINE_URL=${
|
|
64
|
+
MEMORY_MCP_URL=${Le[r]}
|
|
65
|
+
MEMORY_ENGINE_URL=${$e[r]}
|
|
66
66
|
|
|
67
67
|
# FIRECRWAL -> check the docs https://docs.firecrawl.dev/mcp-server
|
|
68
|
-
FIRECRAWL_MCP_URL
|
|
68
|
+
FIRECRAWL_MCP_URL=${re[r]}
|
|
69
69
|
DOMAIN_INDEXER_URL=${ee[r]}
|
|
70
|
-
SANDBOX_MCP_URL=${
|
|
70
|
+
SANDBOX_MCP_URL=${re[r]}
|
|
71
71
|
|
|
72
72
|
# Observability (optional)
|
|
73
73
|
LANGSMITH_TRACING=true
|
|
@@ -78,12 +78,14 @@ LANGSMITH_PROJECT="${e.oracleName}_${r}"
|
|
|
78
78
|
|
|
79
79
|
DISABLE_CREDITS=true
|
|
80
80
|
CORS_ORIGIN=*
|
|
81
|
-
SUBSCRIPTION_URL=${
|
|
81
|
+
SUBSCRIPTION_URL=${Ke[r]}
|
|
82
82
|
|
|
83
83
|
### BACKUP \u2014 save these securely (values above are already set)
|
|
84
84
|
# ORACLE_ADDRESS=${e.oracleAddress}
|
|
85
85
|
# ORACLE_DID=${e.oracleDid}
|
|
86
|
-
|
|
86
|
+
|
|
87
|
+
SKILLS_CAPSULES_BASE_URL="https://capsules.skills.ixo.earth"
|
|
88
|
+
`}function si(r,e){return`# To fill in the blank values, run: qiforge-cli create-entity (select ${r})
|
|
87
89
|
|
|
88
90
|
PORT=4000
|
|
89
91
|
ORACLE_NAME=${e}
|
|
@@ -117,13 +119,13 @@ OPENAI_API_KEY=
|
|
|
117
119
|
OPEN_ROUTER_API_KEY=
|
|
118
120
|
|
|
119
121
|
# External Services (configure these for your deployment)
|
|
120
|
-
MEMORY_MCP_URL=${
|
|
121
|
-
MEMORY_ENGINE_URL=${
|
|
122
|
+
MEMORY_MCP_URL=${Le[r]}
|
|
123
|
+
MEMORY_ENGINE_URL=${$e[r]}
|
|
122
124
|
|
|
123
125
|
# FIRECRWAL -> check the docs https://docs.firecrawl.dev/mcp-server
|
|
124
|
-
FIRECRAWL_MCP_URL
|
|
126
|
+
FIRECRAWL_MCP_URL=${re[r]}
|
|
125
127
|
DOMAIN_INDEXER_URL=${ee[r]}
|
|
126
|
-
SANDBOX_MCP_URL=${
|
|
128
|
+
SANDBOX_MCP_URL=${re[r]}
|
|
127
129
|
|
|
128
130
|
# Observability (optional)
|
|
129
131
|
LANGSMITH_TRACING=true
|
|
@@ -135,8 +137,8 @@ LANGSMITH_PROJECT="${e}_${r}"
|
|
|
135
137
|
# Features (optional)
|
|
136
138
|
# DISABLE_CREDITS=false
|
|
137
139
|
# CORS_ORIGIN=*
|
|
138
|
-
# SUBSCRIPTION_URL=${
|
|
139
|
-
`}function
|
|
140
|
+
# SUBSCRIPTION_URL=${Ke[r]}
|
|
141
|
+
`}function Ye(r,e){try{Re.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 tr=async r=>{let e=r.getOrThrow("oracleMatrixHomeServerUrl"),t=r.getOrThrow("network"),i=r.getOrThrow("registerUserResult"),n=await Ve({homeServerUrl:e,username:i.matrixUserId,password:i.matrixPassword,deviceName:"Oracle Service"}),o=r.getOrThrow("projectPath"),s=Ce.join(o,"apps","app");console.log("Creating env files in:",s),Re.existsSync(s)||(console.log("Creating directory:",s),Re.mkdirSync(s,{recursive:!0}));let c=r.getValue("projectName")??"",m=oi(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}`;Ye(Ce.join(s,d),m),Ye(Ce.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=Ce.join(s,u);if(Re.existsSync(g))continue;let p=si(l,c);Ye(g,p)}};var Se=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(Ee(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=rr(),o=y.spinner();try{if(o.start("Cloning repository..."),i&&Ee(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(Ee(s)){let{rmSync:d}=await import("fs");d(s,{recursive:!0,force:!0})}await rr(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 tr(this.config),y.log.success(`
|
|
140
142
|
\u2705 IXO project created successfully!
|
|
141
143
|
|
|
142
144
|
\u{1F4C1} Location: ${t}
|
|
@@ -145,12 +147,12 @@ LANGSMITH_PROJECT="${e}_${r}"
|
|
|
145
147
|
pnpm install
|
|
146
148
|
pnpm build
|
|
147
149
|
cd apps/app
|
|
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=
|
|
149
|
-
`+" ".repeat(5)+"\u{1F510} "+t),console.log(" ".repeat(5)+"\u{1F4F1} Scan with IXO app"),console.log(" ".repeat(5)+"\u2501".repeat(30)),
|
|
150
|
-
`)}displayQRCode(e){this.displayStyledQRCode(e,"Login with SignX")}async awaitLogin(){return new Promise((e,t)=>{try{this.signXClient.on(
|
|
150
|
+
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=Ee(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 ai}from"@clack/prompts";var Ie=class{constructor(e){this.wallet=e}name="logout";description="Logout command";async execute(){return await ai({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 be=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 J(n)}})},{onCancel:()=>{S.cancel("Operation cancelled."),process.exit(0)}}),i=Jt(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 Yt(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 ye({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=xe({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 we({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 ci}from"@cosmjs/encoding";import{createRegistry as li}from"@ixo/impactxclient-sdk";import{SignX as ir,SIGN_X_LOGIN_ERROR as di,SIGN_X_LOGIN_SUCCESS as mi,SIGN_X_TRANSACT_ERROR as pi,SIGN_X_TRANSACT_SUCCESS as gi}from"@ixo/signx-sdk";import ui from"qrcode-terminal";var nr={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 ir({endpoint:nr[e.network],sitename:"QiForge CLI",network:e.network})}constructor(e){this.signXClient=new ir({endpoint:nr[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(`
|
|
151
|
+
`+" ".repeat(5)+"\u{1F510} "+t),console.log(" ".repeat(5)+"\u{1F4F1} Scan with IXO app"),console.log(" ".repeat(5)+"\u2501".repeat(30)),ui.generate(i,{small:!0}),console.log(" ".repeat(5)+`\u23F3 Waiting...
|
|
152
|
+
`)}displayQRCode(e){this.displayStyledQRCode(e,"Login with SignX")}async awaitLogin(){return new Promise((e,t)=>{try{this.signXClient.on(mi,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(di,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=li();return this.signXClient.transact({address:t.address,did:t.did,pubkey:t.pubKey,timestamp:new Date().toISOString(),transactions:[{sequence:1,txBodyHex:ci(n.encodeTxBody({messages:e,memo:i||""}))}]})}async awaitTransaction(){return new Promise((e,t)=>{try{this.signXClient.on(gi,i=>{e(i.data)}),this.signXClient.on(pi,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 Ae=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 Te=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 V(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 ke=class{constructor(e,t){this.wallet=e;this.config=t;this.createEntity=new V(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 ze=class extends Error{constructor(t,i="CLI_ERROR",n){super(t);this.code=i;this.suggestions=n;this.name="CLIError"}};function Pe(r){r instanceof ze&&(console.error(`
|
|
151
153
|
\u274C ${r.name}: ${r.message}`),r.suggestions?.length&&(console.error(`
|
|
152
154
|
Suggestions:`),r.suggestions.forEach(e=>console.error(` \u2022 ${e}`))),process.exit(1)),r instanceof Error&&(console.error(`
|
|
153
155
|
\u274C Unexpected Error: ${r.message}`),r.stack&&(console.error(`
|
|
154
156
|
Stack trace:`),console.error(r.stack)),process.exit(1)),console.error(`
|
|
155
|
-
\u274C Unknown error occurred`,r),process.exit(1)}var
|
|
157
|
+
\u274C Unknown error occurred`,r),process.exit(1)}var Oe=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 or}from"@ixo/impactxclient-sdk";import{existsSync as Qe,readFileSync as fi,writeFileSync as hi}from"fs";import{unlink as yi}from"fs/promises";import wi from"os";import xi from"path";var q=xi.join(wi.homedir(),".wallet.json"),Ne=class{wallet;signXClient;config;constructor(e){this.config=e,this.loadWallet()}setSignXClient(e){this.signXClient=e}loadWallet(){if(Qe(q))try{let e=fi(q,"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);hi(q,t,"utf8"),L.success(`Wallet saved successfully to: ${q}`)}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 Qe(q)&&this.wallet!==void 0}async clearWallet(){this.wallet=void 0;try{Qe(q)&&(await yi(q),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:or.bank.v1beta1.MsgSend.fromPartial({fromAddress:this.address,toAddress:e,amount:[or.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 et=class{registry;config;wallet;constructor(){this.registry=new ae,this.config=Oe.getInstance(),this.wallet=new Ne(this.config)}registerCommands(){this.registry.register(new Se(this.config,this.wallet)),this.registry.register(new Y(this.wallet,this.config)),this.registry.register(new ke(this.wallet,this.config)),this.registry.register(new Te(this.wallet,this.config)),this.registry.register(new be(this.wallet,this.config)),this.registry.register(new ve(this.wallet,this.config)),this.registry.register(new de(this.wallet,this.config)),this.registry.register(new Ie(this.wallet)),this.registry.register(new se(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 se(this.registry).execute();t.success&&t.data&&console.log(t.data)}async handleAuthentication(){if(!this.wallet.checkWalletExists()){let e=await ar({message:"Login with SignX",options:[{value:"login",label:"Login"},{value:"exit",label:"Exit"}]});switch(sr(e)&&(Ze("Operation cancelled."),H.exit(0)),String(e)){case"login":{(await new Ae(this.wallet,this.config).execute()).success&&Z.success("Login successful");return}case"exit":{Ze("Operation cancelled."),H.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=Ri();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(){vi("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 ar({message:`Welcome ${this.wallet.name}, what would you like to do?`,options:[...this.registry.getCommandOptions()],initialValue:"init"});sr(e)&&(Ze("Operation cancelled."),H.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){Pe(t)}Ci("Thanks for using IXO CLI!"),H.exit(0)}};H.on("uncaughtException",Pe);H.on("unhandledRejection",Pe);var Ei=new et;Ei.run(H.argv);
|
|
156
158
|
//# sourceMappingURL=cli.js.map
|