qiforge-cli 1.1.0 → 1.1.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/README.md CHANGED
@@ -1,14 +1,14 @@
1
- # IXO Oracles CLI
1
+ # QiForge CLI
2
2
 
3
3
  A command-line interface for creating and managing IXO Oracle projects. This CLI helps you set up AI Agent oracles built with LangGraph, using Matrix as a datastore with linked resources stored on the IXO blockchain.
4
4
 
5
- ## What is IXO Oracles CLI?
5
+ ## What is QiForge CLI?
6
6
 
7
- The IXO Oracles CLI automates the complete setup of AI Agent oracle projects. It handles:
7
+ The QiForge CLI automates the complete setup of AI Agent oracle projects. It handles:
8
8
 
9
9
  - **Blockchain Integration**: Creates entities on the IXO blockchain with linked resources stored in Matrix
10
10
  - **Matrix Account Creation**: Sets up Matrix accounts for data storage and communication
11
- - **Project Initialization**: Clones the [IXO Oracles boilerplate](https://github.com/ixoworld/qiforge) and configures the environment
11
+ - **Project Initialization**: Clones the [QiForge boilerplate](https://github.com/ixoworld/qiforge) and configures the environment
12
12
  - **Authentication**: Integrates with SignX for secure blockchain operations
13
13
 
14
14
  ## Prerequisites
@@ -21,13 +21,13 @@ The IXO Oracles CLI automates the complete setup of AI Agent oracle projects. It
21
21
  Install the CLI globally using npm:
22
22
 
23
23
  ```bash
24
- npm install -g ixo-oracles-cli
24
+ npm install -g qiforge-cli
25
25
  ```
26
26
 
27
27
  Or with pnpm:
28
28
 
29
29
  ```bash
30
- pnpm add -g ixo-oracles-cli
30
+ pnpm add -g qiforge-cli
31
31
  ```
32
32
 
33
33
  **Important for pnpm users:** After installation, you need to approve build scripts:
@@ -47,7 +47,7 @@ Do you approve? (y/N) · true
47
47
  Or with yarn:
48
48
 
49
49
  ```bash
50
- yarn global add ixo-oracles-cli
50
+ yarn global add qiforge-cli
51
51
  ```
52
52
 
53
53
  ## Quick Start
@@ -55,33 +55,33 @@ yarn global add ixo-oracles-cli
55
55
  1. **Initialize a new oracle project:**
56
56
 
57
57
  ```bash
58
- oracles-cli --init
58
+ qiforge-cli --init
59
59
  ```
60
60
 
61
61
  2. **Or run the interactive CLI:**
62
62
 
63
63
  ```bash
64
- oracles-cli
64
+ qiforge-cli
65
65
  ```
66
66
 
67
67
  3. **Follow the prompts:**
68
68
  - First-time users will need to login with SignX (keep your IXO Mobile App open)
69
69
  - Enter your project name
70
- - Select the template (IXO Oracles boilerplate or custom)
70
+ - Select the template (QiForge boilerplate or custom)
71
71
  - Configure your oracle details
72
72
 
73
73
  ## Commands
74
74
 
75
- ### `oracles-cli --init` - Initialize Project
75
+ ### `qiforge-cli --init` - Initialize Project
76
76
 
77
77
  Creates a new IXO Oracle project with all necessary components:
78
78
 
79
- - **Project Setup**: Creates directory and clones the IXO Oracles boilerplate
79
+ - **Project Setup**: Creates directory and clones the QiForge boilerplate
80
80
  - **Entity Creation**: Creates a blockchain entity with linked resources stored in Matrix
81
81
  - **Matrix Account**: Sets up Matrix account for data storage
82
82
  - **Environment Configuration**: Creates `.env` file with all necessary variables
83
83
 
84
- ### `oracles-cli` - Interactive Menu
84
+ ### `qiforge-cli` - Interactive Menu
85
85
 
86
86
  Launches an interactive menu with the following options:
87
87
 
package/dist/cli.js CHANGED
@@ -1,24 +1,24 @@
1
1
  #!/usr/bin/env node
2
2
  import{cancel as De,intro as br,isCancel as Ct,log as G,outro as Pr,select as Rt,spinner as Nr}from"@clack/prompts";import M from"process";var z=class{commands;constructor(){this.commands=new Map}register(e){this.commands.set(e.name,e)}get(e){return this.commands.get(e)}getAll(){return Array.from(this.commands.values())}getCommandOptions(){return this.getAll().map(e=>({value:e.name,label:e.name,hint:e.description}))}};import*as w from"@clack/prompts";import{select as bt}from"@clack/prompts";import{z as D}from"zod";var S=async r=>{let e=await bt({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},$e={mainnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d",testnet:"did:ixo:entity:3d079ebc0b332aad3305bb4a51c72edb",devnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d"},L={devnet:"https://devmx.ixo.earth",testnet:"https://testmx.ixo.earth",mainnet:"https://mx.ixo.earth"};var We={devnet:"https://ixo-portal.vercel.app",testnet:"https://ixo-portal.vercel.app",mainnet:"https://ixo-portal.vercel.app"},N={mainnet:"https://impacthub.ixo.world/rpc/",testnet:"https://testnet.ixo.earth/rpc/",devnet:"https://devnet.ixo.earth/rpc/"},B={devnet:"https://domain-indexer.devnet.ixo.earth/index",testnet:"https://domain-indexer.testnet.ixo.earth/index",mainnet:"https://domain-indexer.ixo.earth/index"},j={devnet:"https://devnet-blocksync-graphql.ixo.earth/graphql",testnet:"https://testnet-blocksync-graphql.ixo.earth/graphql",mainnet:"https://blocksync-graphql.ixo.earth/graphql"},ve={devnet:"https://mcp-memory-engine.devnet.ixo.earth/",testnet:"https://memory-engine.testnet.ixo.earth/",mainnet:"https://memory-engine.ixo.earth/"},Ce={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"},Ee={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/"},T=(r,e="This field is required")=>{let i=D.string().min(1,e).safeParse(r);if(!i.success)return i.error.message},F=r=>{let t=D.string().regex(/^did:ixo:entity:[a-f0-9]{32}$/,"Invalid entity DID").safeParse(r);if(!t.success)return t.error.message},_=(r,e="This url is required or a valid URL")=>{let i=D.url(e).safeParse(r);if(!i.success)return i.error.message},Xe=(r,e="This number is required")=>{let i=D.number().min(1,e).safeParse(r);if(!i.success)return i.error.message},J=r=>{let t=D.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"},Q=r=>{let t=D.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 Ke(r){let e=new URL(r),t=e.hostname,i=e.protocol;return{homeServerUrl:r,roomBotUrl:`${i}//rooms.bot.${t}`,stateBotUrl:`${i}//state.bot.${t}`,bidsBotUrl:`${i}//bids.bot.${t}`,claimsBotUrl:`${i}//claims.bot.${t}`}}import{isCancel as lr,log as h,spinner as dr,text as mr}from"@clack/prompts";import{customMessages as ft,ixo as x,utils as Oe}from"@ixo/impactxclient-sdk";import{sha256 as jt}from"@cosmjs/crypto";import{encrypt as Ft}from"eciesjs";import{ClientEvent as Vt,createClient as be}from"matrix-js-sdk";import qt from"md5";var Z=new Map;function Pt(r){return Z.get(r)instanceof Uint8Array}function Nt(r){return Z.get(r)}function Se(){Z.clear()}async function Be({keys:r}){let e=Object.keys(r),t=e.find(Pt);if(console.info("[] getSecretStorageKey",r,e,t),!t)return null;let i=Nt(t);return[t,i]}function je(r,e,t){Z.set(r,t)}import{Bip39 as He,EnglishMnemonic as Ge,Secp256k1 as Ae,sha256 as Ut,Slip10 as Ye,Slip10Curve as ze,stringToPath as Je}from"@cosmjs/crypto";import{DirectSecp256k1HdWallet as kt}from"@cosmjs/proto-signing";import{createQueryClient as Qe,createSigningClient as Mt,customMessages as Dt,ixo as Lt,utils as _t}from"@ixo/impactxclient-sdk";import{createCipheriv as $t,randomBytes as Wt}from"crypto";import{createRegistry as Tt,utils as Ot}from"@ixo/impactxclient-sdk";function V(r){try{return Ot.proto.fromTimestamp(r).getTime()}catch{return}}var ee={BasicAllowance:"/cosmos.feegrant.v1beta1.BasicAllowance",PeriodicAllowance:"/cosmos.feegrant.v1beta1.PeriodicAllowance"},Fe=r=>{let e=Tt();return(r??[]).map(t=>{let i=t.allowance,n=e.decode(i);switch(i.typeUrl){case ee.BasicAllowance:return{granter:t.granter,grantee:t.grantee,type:ee.BasicAllowance,expiration:n.expiration?V(n.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};case ee.PeriodicAllowance:return{granter:t.granter,grantee:t.grantee,type:ee.PeriodicAllowance,expiration:n.basic?.expiration?V(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?V(n.expiration):n.basic?.expiration?V(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}}})},Ve=r=>{if(r==null)return!1;let e=typeof r=="object"?V(r):r;return e==null?!0:e<Date.now()},qe=r=>r==null?!1:(typeof r=="object"?Number(r?.amount??0):typeof r=="string"?Number(r??0):r)<=5e-4;async function Ie(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=N[e];if(!t)throw new Error(`Invalid network: ${e}. Valid networks are: ${Object.keys(N).join(", ")}`);console.log(`\u{1F517} Using RPC URL: ${t}`);try{return!!(await(await Qe(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 Ze(r,e,t,i){try{let n=await t.getAccounts(),{address:o,pubkey:s}=n[0]??{},c=await Xt(o,e),a=c?.length?Fe(c)?.find(d=>!!d&&!Ve(d.expiration)&&!qe(d.limit))?.granter:void 0,l={typeUrl:"/ixo.iid.v1beta1.MsgCreateIidDocument",value:Lt.iid.v1beta1.MsgCreateIidDocument.fromPartial({id:r,verifications:Dt.iid.createIidVerificationMethods({did:r,pubkey:s,address:o,controller:r,type:"secp"}),signer:o,controllers:[r],...i?.length?{services:i}:{}})};await Kt({offlineSigner:t,messages:[l],feegrantGranter:a,network:e})}catch(n){throw console.error(n),n}}async function Xt(r,e){try{let t=N[e];if(!t)throw new Error(`Invalid network: ${e}`);return(await(await Qe(t)).cosmos.feegrant.v1beta1.allowances({grantee:r}))?.allowances??[]}catch(t){console.error("queryAddressAllowances::",t.message);return}}var Kt=async({offlineSigner:r,messages:e,memo:t="Signing with Mnemonic Demo",feegrantGranter:i,network:n})=>{let o=N[n];if(!o)throw new Error(`Invalid network: ${n}`);let s=await Mt(o,r),c=await r.getAccounts(),{address:a}=c[0]??{},l=await s.simulate(a,e,t),m=(l>5e4?l:(e??[]).length*5e5)*1.7,p=Bt(m),v={amount:[{denom:"uixo",amount:String(Math.round(p.average))}],gas:String(Math.round(m)),granter:i},y=await s.signAndBroadcast(a,e,v,t,void 0);if(!!y.code)throw new Error(`Error when broadcasting tx ${y.transactionHash} at height ${y.height}. Code: ${y.code}; Raw log: ${y.rawLog}`)},Bt=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}},te=r=>new Promise(e=>setTimeout(e,r));function et(r,e){let t=Wt(16),i=$t("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 tt=async r=>{let e=await kt.fromMnemonic(r,{prefix:"ixo"}),t=(await e.getAccounts())[0],i=await He.mnemonicToSeed(new Ge(r)),n=Je("m/44'/118'/0'/0/0"),s=Ye.derivePath(ze.Secp256k1,i,n).privkey,c=await Ae.makeKeypair(s),a=Ae.compressPubkey(c.pubkey);return{mnemonic:r,did:_t.did.generateSecpDid(t.address),baseAccount:t,async getAccounts(){return await e.getAccounts()},async signDirect(d,m){return await e.signDirect(d,m)},async sign(d){try{let m=await He.mnemonicToSeed(new Ge(r)),p=Je("m/44'/118'/0'/0/0"),{privkey:v}=Ye.derivePath(ze.Secp256k1,m,p),y=new Uint8Array(Buffer.from(d,"base64")),P=Ut(y);return(await Ae.createSignature(P,v)).toFixedLength().slice(0,64)}catch(m){throw console.error("Error during signature creation:",m),m}}}};var Ht="/.well-known/matrix/client",Pe=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 er(o));try{let a=nt(o),l=await a.login("m.login.password",{identifier:{type:"m.id.user",user:tr(s)},password:t,initial_device_display_name:i});return{accessToken:l.access_token,deviceId:l.device_id,userId:l.user_id,baseUrl:n?o:l?.well_known?.["m.homeserver"]?.base_url||a.baseUrl}}catch(a){let l=a.message;throw l==="Unknown message"&&(l="Please check your credentials"),console.error("mxLogin::",l),new Error(l)}};async function Gt(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 Yt(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 zt(r,e){let t=new Uint8Array(Buffer.from(e,"hex")),i=new Uint8Array(Buffer.from(r,"utf8")),n=Ft(t,i);return Array.from(n,o=>o.toString(16).padStart(2,"0")).join("")}async function Jt(r,e,t,i,n,o){let s=await Gt(o),c=zt(e,s.publicKey),a={address:r,encryptedPassword:c,publicKeyFingerprint:s.fingerprint,secpResult:{signature:t,challenge:i}},l=await fetch(`${o}/user/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!l.ok){let d=await l.text(),m=`Failed to create user account (HTTP ${l.status})`;try{let p=JSON.parse(d);m=p.error||p.message||p.detail||d}catch{m=d||m}throw console.error(`Room bot error [${l.status}]: ${d}`),new Error(m)}return await l.json()}async function rt(r,e,t,i,n,o){try{let{challengeBase64:s}=Yt(r),c=await i.sign(s),a=Buffer.from(c).toString("base64");if(!(await Jt(r,e,a,s,n,o)).success)throw new Error("Failed to create matrix account via API");let d=Ne(r);return await Pe({homeServerUrl:n,username:d,password:e,deviceName:t})}catch(s){throw console.error("mxRegisterWithSecp error:",s),s}}async function it({homeServerUrl:r,username:e}){let t=nt(r);try{return!!await t.isUsernameAvailable(e)}catch{return!1}}function nt(r){if(!r)throw new Error("Home server URL is required to instantiate matrix client");return be({baseUrl:r})}async function ot({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:Be,cacheSecretStorageKey:je},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(Vt.Sync,a=>{c[a]()})}),n}async function re({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 st(r){let e=r.getAccountData("m.cross_signing.master");return console.log("hasCrossSigningAccountData::masterKeyData",e),!!e}async function at(r,{securityPhrase:e,password:t,forceReset:i=!1,skipBootstrapSecureStorage:n=!1}){i&&Se();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);Se(),await o.bootstrapSecretStorage({createSecretStorageKey:async()=>c,setupNewSecretStorage:i})}let s=r.getUserId();return await o.bootstrapCrossSigning({authUploadDeviceSigningKeys:async function(c){await c(rr({userId:s,password:t}))},setupNewCrossSigning:i}),await o.resetKeyBackup(),await te(300),!!r.getAccountData("m.cross_signing.master")}function Ne(r){if(!r)throw new Error("Address is required to generate matrix username");return"did-ixo-"+r}function ct(r){return Buffer.from(qt(r.replace(/ /g,""))).toString("base64").slice(0,24)}function lt(r){let e=jt(new TextEncoder().encode(r.replace(/ /g,"")));return Buffer.from(e).toString("base64").slice(0,32)}function Qt(r){return r.replace(/^(https?:\/\/)/,"").replace(/\/$/,"")}function Zt(r,e=""){return"did-ixo-"+r+e}function dt(r,e){return"#"+Zt(r)+":"+Qt(e)}async function er(r){let e="https://";/^https?:\/\//.test(r)&&(e="");let t=`${e}${r}${Ht}`;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 tr(r){return(r.indexOf("@")===0?r.substring(1):r).trim()}function rr({userId:r,password:e}){return{type:"m.login.password",password:e,identifier:{type:"m.id.user",user:r}}}import{ixo as ir,utils as Te}from"@ixo/impactxclient-sdk";import{createMatrixApiClient as nr}from"@ixo/matrixclient-sdk";var mt="Oracles CLI";async function ie({pin:r,oracleName:e,network:t,oracleAvatarUrl:i,matrixHomeServerUrl:n},o){try{let{homeServerUrl:s,roomBotUrl:c}=Ke(n),a=Te.mnemonic.generateMnemonic(),l=await tt(a),d=l.baseAccount.address;console.log("\u2705 Wallet created:",d),await o(d);let m=Te.did.generateSecpDid(d),p=await Ie(m,t);if(console.log("\u2705 DID exists:",p),!p){console.log("\u2705 DID does not exist, creating...");let U=ir.iid.v1beta1.Service.fromPartial({id:`${m}#matrix`,type:"MatrixHomeServer",serviceEndpoint:s});if(await Ze(m,t,l,[U]),console.log("\u2705 DID created, waiting 500ms..."),await te(500),console.log("\u2705 Checking if DID exists..."),!await Ie(m,t))throw new Error("Failed to create DID document")}console.log("\u2705 DID created:",m);let v=Te.mnemonic.generateMnemonic(12),y=Ne(d),P=ct(v),he=lt(v);if(!await it({homeServerUrl:s,username:y}))throw new Error("Matrix account already exists");let R=await rt(d,P,mt,l,s,c);if(!R?.accessToken)throw new Error("Failed to register matrix account");console.log("\u2705 Matrix account created:",R.userId);let K=await ot({homeServerUrl:s,accessToken:R.accessToken,userId:R.userId,deviceId:R.deviceId});try{await Promise.all([K.setDisplayName(e),K.setAvatarUrl(i)])}catch(U){console.error("Failed to set display name or avatar url:",U)}let Y=nr({homeServerUrl:s,accessToken:R.accessToken}),we=st(K);if(!we&&(we=await at(K,{securityPhrase:he,password:P,forceReset:!0}),!we))throw new Error("Failed to setup cross signing");console.log("\u2705 Matrix cross-signing setup completed");let St=dt(d,R.baseUrl),A=(await Y.room.v1beta1.queryId(St).catch(()=>{}))?.room_id??"";if(!A){let U=await fetch(`${c}/room/source`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({did:m,userMatrixId:R.userId})});if(!U.ok)throw new Error("Failed to create matrix room");if(A=(await U.json()).roomId,!A)throw new Error("Failed to create user matrix room")}let ye=await Y.room.v1beta1.listJoinedMembers(A).catch(()=>{}),xe=!!ye?.joined?.[R.userId];if(!xe){if(!(await Y.room.v1beta1.join(A)).room_id)throw new Error("Failed to join matrix room");if(ye=await Y.room.v1beta1.listJoinedMembers(A),xe=!!ye?.joined?.[R.userId],!xe)throw new Error("Failed to join matrix room")}console.log("\u2705 Matrix room created/joined:",A);let At=et(v,r),_e=await fetch(`${s}/_matrix/client/v3/rooms/${A}/state/ixo.room.state.secure/encrypted_mnemonic`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${R.accessToken}`},body:JSON.stringify({encrypted_mnemonic:At})});if(!_e.ok)throw new Error("Failed to store encrypted mnemonic in matrix room");return await _e.json(),console.log("\u2705 Encrypted Matrix mnemonic stored in room"),K.stopClient(),{address:d,did:m,mnemonic:a,matrixUserId:R.userId,matrixRoomId:A,matrixMnemonic:v,matrixPassword:P,matrixAccessToken:R.accessToken,matrixRecoveryPhrase:he,matrixHomeServerUrl:s,pin:r,matrixDeviceName:mt}}catch(s){throw console.error("Simplified registration failed:",s),s}}import{createMatrixApiClient as ar,utils as cr}from"@ixo/matrixclient-sdk";import{CID as or}from"multiformats";import{base64 as sr}from"multiformats/bases/base64";import*as pt from"multiformats/hashes/sha2";async function gt(r){let e=r.startsWith("m")?r:"m"+r,t=sr.decode(e),i=await pt.sha256.digest(t);return or.create(1,85,i).toString()}function ut(r){let e=new TextEncoder().encode(r);return btoa(String.fromCharCode(...Array.from(e)))}var q=async({data:r,fileName:e,homeServerUrl:t,accessToken:i})=>{let n=ar({homeServerUrl:t,accessToken:i}),o=JSON.stringify(r),s=Buffer.from(o,"utf8"),c=e+".json",l=await n.media.v1beta1.upload(c,"application/ld+json",s),d=cr.mxc.mxcUrlToHttp(t,l.content_uri);if(!d)throw new Error("Failed to upload file to Matrix");let m=JSON.stringify(r),p=ut(m),v=await gt(p);return{encrypted:"false",cid:v,proof:v,serviceEndpoint:d,mxc:l.content_uri}};var O=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:x.entity.v1beta1.MsgCreateEntity.fromPartial({entityType:"oracle",context:[],entityStatus:0,verification:[...ft.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:$e[this.config.getValue("network")??"devnet"],service:[x.iid.v1beta1.Service.fromPartial({id:"{id}#matrix",type:"MatrixHomeServer",serviceEndpoint:e})],linkedResource:[],accordedRight:[],linkedEntity:[],linkedClaim:[],startDate:Oe.proto.toTimestamp(new Date),endDate:Oe.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=>x.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 q({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 x.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 q({data:s,fileName:"fees",homeServerUrl:n,accessToken:o});return x.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:x.iid.v1beta1.MsgDeleteService.fromPartial({id:e,serviceId:`${e}#api`,signer:i})},o={typeUrl:"/ixo.iid.v1beta1.MsgDeleteService",value:x.iid.v1beta1.MsgDeleteService.fromPartial({id:e,serviceId:`${e}#ws`,signer:i})},s={typeUrl:"/ixo.iid.v1beta1.MsgAddService",value:x.iid.v1beta1.MsgAddService.fromPartial({id:e,serviceData:x.iid.v1beta1.Service.fromPartial({id:`${e}#api`,type:"oracleService",serviceEndpoint:t}),signer:i})},c={typeUrl:"/ixo.iid.v1beta1.MsgAddService",value:x.iid.v1beta1.MsgAddService.fromPartial({id:e,serviceData:x.iid.v1beta1.Service.fromPartial({id:`${e}#ws`,type:"wsService",serviceEndpoint:t}),signer:i})};h.info(`Sign to update oracle domain for entity ${e}`);let a=await this.wallet.signXClient.transact([n,o,s,c],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(a)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),h.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:x.iid.v1beta1.MsgAddController.fromPartial({id:e,controllerDid:t,signer:i})};h.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(),h.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 l=(await Promise.all([this.createAuthZConfig({oracleName:e,entityDid:t,oracleAccountAddress:n,homeServerUrl:o,accessToken:s}),this.createFeesConfig({entityDid:t,price:i,denom:this.config.getValue("network")==="devnet"?"uixo":"ibc/6BBE9BD4246F8E04948D5A4EEE7164B2630263B9EBB5E7DC5F0A46C62A2FF97B",homeServerUrl:o,accessToken:s})])).map(p=>({typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:x.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:t,linkedResource:x.iid.v1beta1.LinkedResource.fromPartial({id:p.id,description:p.description,type:p.type,proof:p.proof,mediaType:p.mediaType,encrypted:p.encrypted,serviceEndpoint:p.serviceEndpoint}),signer:c})}));h.info("Sign to edit the entity and add the config files");let d=await this.wallet.signXClient.transact(l,this.wallet.wallet);return this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(d)),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 q({data:s,fileName:"domainCard",homeServerUrl:i,accessToken:n});return x.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:a}){let d=await q({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:a});return x.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#pro",type:"Settings",description:"Profile",mediaType:"application/json",serviceEndpoint:d.serviceEndpoint,proof:d.proof,encrypted:"false",right:""})}addServices(e,t){e.value.service.push(...t.map(i=>x.iid.v1beta1.Service.fromPartial(i)))}setParentProtocol(e,t){e.value.context.push(...ft.iid.createAgentIidContext([{key:"class",val:t}]))}async submitToDomainIndexer(e){let t=this.config.getValue("network")??"devnet",i=B[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();h.warn(`Failed to submit to domain indexer: ${n.status} ${o}`);return}h.success("Domain card submitted to domain indexer")}catch(n){h.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;h.info("Creating Oracle Wallet and Matrix Account");let i=await mr({message:"Enter a 6-digit PIN to secure your Matrix Vault:",placeholder:"123456",validate(y){return J(y)}});lr(i)&&(h.error("User cancelled"),process.exit(1));let n=await ie({pin:i,oracleName:e.oracleConfig.oracleName,network:this.config.getValue("network"),oracleAvatarUrl:e.profile.logo,matrixHomeServerUrl:t},async y=>{await this.wallet.sendTokens(y,25e4)}),o=n.matrixHomeServerUrl,s=n.matrixAccessToken;h.info("Adding profile");let c=await this.addProfile({...e.profile,homeServerUrl:o,accessToken:s}),a=this.buildMsgCreateEntity(t);a.value.linkedResource.push(c),h.info("Adding services"),this.addServices(a,e.services),h.info("Adding parent protocol"),this.setParentProtocol(a,e.parentProtocol),this.addLinkedAccounts(a,{oracleAccountAddress:n.address}),h.info("Sign this transaction to create the entity");let l=await this.wallet.signXClient.transact([a],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(l)),await this.wallet.signXClient.pollNextTransaction();let d=await this.wallet.signXClient.awaitTransaction();h.success("Entity created -- wait to attach the required config files");let m=Oe.common.getValueFromEvents(d,"wasm","token_id");h.info("Creating domain card");let p=await this.createDomainCard({profile:e.profile,entityDid:m,homeServerUrl:o,accessToken:s});if(this.wallet.wallet?.address){let y={typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:x.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:m,linkedResource:x.iid.v1beta1.LinkedResource.fromPartial({id:p.id,description:p.description,type:p.type,proof:p.proof,mediaType:p.mediaType,encrypted:p.encrypted,serviceEndpoint:p.serviceEndpoint}),signer:this.wallet.wallet.address})};h.info("Sign to add domain card to the entity");let P=await this.wallet.signXClient.transact([y],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(P)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction(),h.success("Domain card added to entity")}await this.createOracleConfigFiles({oracleName:e.oracleConfig.oracleName,price:e.oracleConfig.price,oracleAccountAddress:n.address,entityDid:m,homeServerUrl:o,accessToken:s}),h.success("Entity created -- config files attached"),await re({baseUrl:o,accessToken:s,userId:n.matrixUserId,deviceId:""});let v=dr();v.start("Creating Entity Matrix Room..."),v.stop("Room created -- room joined"),h.warn("Please save the following information in a secure location as it is not stored:"),h.info("ORACLE ACCOUNT DETAILS");for(let y in n)h.info(`${y}: ${n[y]}`);return this.config.addValue("registerUserResult",n),this.config.addValue("entityDid",m),this.config.addValue("oracleMatrixHomeServerUrl",t),h.info("Submitting domain card to domain indexer"),await this.submitToDomainIndexer(m),m}};var $=class{constructor(e,t){this.wallet=e;this.config=t}name="create-entity";description="Create an entity";async execute(){this.config.getValue("network")||await S(this.config);let t=this.wallet.matrixHomeServer??L[this.config.getValue("network")??"devnet"],i=await w.group({matrixHomeServerUrl:()=>w.text({message:"Matrix homeserver URL for the oracle:",initialValue:t,defaultValue:t,validate(a){return Q(a)}}),oracleName:()=>w.text({message:"What is the name of the oracle?",initialValue:"My oracle",validate(a){return T(a,"Oracle name is required")}}),oraclePrice:()=>w.text({message:"What is the price of the oracle in IXO CREDITS?",initialValue:"100",validate(a){return Xe(parseInt(a??""),"Oracle price is required and must be a number")}}),profile:()=>w.group({orgName:()=>w.text({message:"What is the name of the organization?",initialValue:"IXO",validate(a){return T(a,"Organization name is required")}}),name:()=>w.text({message:"What is the name of the profile?",initialValue:"My oracle",validate(a){return T(a,"Profile name is required")}}),logo:({results:a})=>w.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?_(l,"Logo is required or a valid URL"):`https://api.dicebear.com/8.x/bottts/svg?seed=${a?.name??"IXO"}`}}),coverImage:({results:a})=>w.text({message:"What is the cover image of the profile?",initialValue:a.logo,defaultValue:a.logo,validate(l){return l?_(l,"Cover image is required or a valid URL"):a.logo}}),location:()=>w.text({message:"What is the location of your domain?",initialValue:"New York, NY",validate(a){return T(a,"Location is required")}}),description:()=>w.text({message:"What is the description of the entity (profile)?",initialValue:"We are a company that helps you with daily tasks",validate(a){return T(a,"Description is required")}}),url:()=>w.text({message:"What is the website URL of the oracle? (optional, press Enter to skip)",placeholder:"https://your-oracle-website.com"})}),parentProtocol:()=>w.select({message:"What is the parent protocol of the entity?",options:[{value:"did:ixo:entity:1a76366f16570483cea72b111b27fd78",label:"IXO Oracle Protocol",hint:"default protocol"}],initialValue:"did:ixo:entity:1a76366f16570483cea72b111b27fd78"}),apiUrl:()=>w.text({message:"What is the API URL of the oracle?",initialValue:"http://localhost:4000",validate(a){return _(a,"API URL is required or a valid URL")}})},{onCancel:()=>{w.cancel("Operation cancelled."),process.exit(0)}}),o=await new O(this.wallet,this.config).execute({oracleConfig:{oracleName:i.oracleName,price:parseInt(i.oraclePrice)},profile:{orgName:i.profile.orgName,name:i.profile.name,logo:i.profile.logo,coverImage:i.profile.coverImage,location:i.profile.location,description:i.profile.description,...i.profile.url?{url:i.profile.url}:{}},services:[{id:"{id}#api",serviceEndpoint:i.apiUrl,type:"oracleService"},{id:"{id}#ws",serviceEndpoint:i.apiUrl,type:"wsService"}],parentProtocol:i.parentProtocol,matrixHomeServerUrl:i.matrixHomeServerUrl});w.log.info(`API for the oracle is: ${i.apiUrl} | You can change this after you deploy the oracle`);let c=`${We[this.config.getValue("network")??"devnet"]}/oracle/${o}/overview`;return w.log.info(`Oracle created successfully: ${o}`),w.log.info(`Oracle URL: ${c}`),{success:!0,data:`Entity created successfully: ${o}`}}};import*as E from"@clack/prompts";var ne=class{constructor(e,t){this.wallet=e;this.config=t}name="create-user";description="Create a new user";async execute(){let e=this.config.getValue("network");e||await S(this.config);let t=this.wallet.matrixHomeServer??L[this.config.getValue("network")??"devnet"],i=await E.text({message:"Matrix homeserver URL:",initialValue:t,defaultValue:t,validate(c){return Q(c)}});E.isCancel(i)&&(E.log.error("User cancelled"),process.exit(1));let n=await E.text({message:"Enter a 6-digit PIN to secure your Matrix Vault:",placeholder:"123456",validate(c){return J(c)}});E.isCancel(n)&&(E.log.error("User cancelled"),process.exit(1));let o=await E.text({message:"Enter your oracle name",initialValue:"My oracle",validate(c){return T(c,"Oracle name is required")}});E.isCancel(o)&&(E.log.error("User cancelled"),process.exit(1));let s=await ie({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 re({baseUrl:s.matrixHomeServerUrl,accessToken:s.matrixAccessToken,userId:s.matrixUserId,deviceId:""}),{success:!0,data:s}}};var H=class{constructor(e){this.registry=e}name="help";description="Show help information and available commands";async execute(){return{success:!0,data:`
3
- IXO Oracles CLI - Help
3
+ QiForge CLI - Help
4
4
 
5
5
  USAGE:
6
- oracles-cli [command] [options]
6
+ qiforge-cli [command] [options]
7
7
 
8
8
  COMMANDS:
9
9
  ${this.registry.getAll().map(i=>` ${i.name.padEnd(15)} ${i.description}`).join(`
10
10
  `)}
11
11
 
12
12
  EXAMPLES:
13
- oracles-cli --init Initialize a new IXO Oracle project
14
- oracles-cli Launch interactive menu
15
- oracles-cli help Show this help message
13
+ qiforge-cli --init Initialize a new IXO Oracle project
14
+ qiforge-cli Launch interactive menu
15
+ qiforge-cli help Show this help message
16
16
 
17
17
  OPTIONS:
18
18
  --init Initialize a new project (shortcut)
19
19
  --help, -h Show help information
20
20
 
21
- For more information, visit: https://github.com/ixoworld/ixo-oracles-cli
21
+ For more information, visit: https://www.npmjs.com/package/qiforge-cli
22
22
  `}}};import*as g from"@clack/prompts";import{existsSync as ae}from"fs";import W from"path";import wt from"simple-git";import se from"fs";import oe from"path";function pr(r,e){return`
23
23
  PORT=4000
24
24
  ORACLE_NAME=${e.oracleName}
@@ -73,7 +73,7 @@ SUBSCRIPTION_URL=${Ee[r]}
73
73
  ### BACKUP \u2014 save these securely (values above are already set)
74
74
  # ORACLE_ADDRESS=${e.oracleAddress}
75
75
  # ORACLE_DID=${e.oracleDid}
76
- `}function gr(r,e){return`# To fill in the blank values, run: oracles-cli create-entity (select ${r})
76
+ `}function gr(r,e){return`# To fill in the blank values, run: qiforge-cli create-entity (select ${r})
77
77
 
78
78
  PORT=4000
79
79
  ORACLE_NAME=${e}
@@ -134,7 +134,7 @@ LANGSMITH_PROJECT="${e}_${r}"
134
134
  pnpm install
135
135
  pnpm build
136
136
  cd apps/app
137
- 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=ae(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 ur}from"@clack/prompts";var le=class{constructor(e){this.wallet=e}name="logout";description="Logout command";async execute(){return await ur({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{toHex as fr}from"@cosmjs/encoding";import{createRegistry as hr}from"@ixo/impactxclient-sdk";import{SignX as yt,SIGN_X_LOGIN_ERROR as wr,SIGN_X_LOGIN_SUCCESS as yr,SIGN_X_TRANSACT_ERROR as xr,SIGN_X_TRANSACT_SUCCESS as vr}from"@ixo/signx-sdk";import Cr from"qrcode-terminal";var xt={devnet:"https://signx.devnet.ixo.earth",testnet:"https://signx.testnet.ixo.earth",mainnet:"https://signx.ixo.earth"},X=class{signXClient;_loginData;get loginData(){return this._loginData}static loadFromWallet(e){return new yt({endpoint:xt[e.network],sitename:"IXO Oracles CLI",network:e.network})}constructor(e){this.signXClient=new yt({endpoint:xt[e],sitename:"IXO Oracles 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(`
137
+ 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=ae(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 ur}from"@clack/prompts";var le=class{constructor(e){this.wallet=e}name="logout";description="Logout command";async execute(){return await ur({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{toHex as fr}from"@cosmjs/encoding";import{createRegistry as hr}from"@ixo/impactxclient-sdk";import{SignX as yt,SIGN_X_LOGIN_ERROR as wr,SIGN_X_LOGIN_SUCCESS as yr,SIGN_X_TRANSACT_ERROR as xr,SIGN_X_TRANSACT_SUCCESS as vr}from"@ixo/signx-sdk";import Cr from"qrcode-terminal";var xt={devnet:"https://signx.devnet.ixo.earth",testnet:"https://signx.testnet.ixo.earth",mainnet:"https://signx.ixo.earth"},X=class{signXClient;_loginData;get loginData(){return this._loginData}static loadFromWallet(e){return new yt({endpoint:xt[e.network],sitename:"QiForge CLI",network:e.network})}constructor(e){this.signXClient=new yt({endpoint:xt[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(`
138
138
  `+" ".repeat(5)+"\u{1F510} "+t),console.log(" ".repeat(5)+"\u{1F4F1} Scan with IXO app"),console.log(" ".repeat(5)+"\u2501".repeat(30)),Cr.generate(i,{small:!0}),console.log(" ".repeat(5)+`\u23F3 Waiting...
139
139
  `)}displayQRCode(e){this.displayStyledQRCode(e,"Login with SignX")}async awaitLogin(){return new Promise((e,t)=>{try{this.signXClient.on(yr,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(wr,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=hr();return this.signXClient.transact({address:t.address,did:t.did,pubkey:t.pubKey,timestamp:new Date().toISOString(),transactions:[{sequence:1,txBodyHex:fr(n.encodeTxBody({messages:e,memo:i||""}))}]})}async awaitTransaction(){return new Promise((e,t)=>{try{this.signXClient.on(vr,i=>{e(i.data)}),this.signXClient.on(xr,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 de=class{constructor(e,t){this.wallet=e;this.config=t}name="signx-login";description="Login with SignX wallet";async execute(){try{let e=await S(this.config),t=new X(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 I from"@clack/prompts";var me=class{constructor(e,t){this.wallet=e;this.config=t}name="update-oracle-api-url";description="Update the oracle API domain (default is localhost)";async execute(){this.config.getValue("network")||await S(this.config);let t=await I.group({entityDid:()=>I.text({message:"What is the DID of the entity you want to update?",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(i){return F(i)}}),apiUrl:()=>I.text({message:"What is the new API URL (domain) for the oracle?",initialValue:"http://localhost:4000",validate(i){return _(i,"API URL is required and must be a valid URL")}})},{onCancel:()=>{I.cancel("Operation cancelled."),process.exit(0)}});try{let i=new O(this.wallet,this.config);return I.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 C from"@clack/prompts";var pe=class{constructor(e,t){this.wallet=e;this.config=t;this.createEntity=new O(this.wallet,this.config)}name="update-entity";description="Update an entity (add controllers, etc.)";createEntity;async execute(){this.config.getValue("network")||await S(this.config);let t=await C.group({entityDid:()=>C.text({message:"What is the DID of the entity you want to update?",initialValue:this.config.getValue("entityDid")?.toString()??"",validate(i){return F(i)}}),action:()=>C.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 C.text({message:"What is the DID of the controller you want to add?",validate(o){return F(o)}});return C.isCancel(n)&&(C.cancel("Operation cancelled."),process.exit(0)),n}},{onCancel:()=>{C.cancel("Operation cancelled."),process.exit(0)}});try{if(t.action==="add-controller"&&typeof t.controllerDid=="string"){let i=t.controllerDid,n=t.entityDid;return C.log.info(`Adding controller ${i} to entity ${n}`),await this.createEntity.addControllerToEntity(n,i),C.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 ke=class extends Error{constructor(t,i="CLI_ERROR",n){super(t);this.code=i;this.suggestions=n;this.name="CLIError"}};function ge(r){r instanceof ke&&(console.error(`
140
140
  \u274C ${r.name}: ${r.message}`),r.suggestions?.length&&(console.error(`