ixo-oracles-cli 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{cancel as fe,intro as nr,isCancel as it,log as W,outro as or,select as nt,spinner as sr}from"@clack/prompts";import A from"process";var _=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 p from"@clack/prompts";import{select as at}from"@clack/prompts";import{z as re}from"zod";var j=async r=>{let e=await at({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},we={mainnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d",testnet:"did:ixo:entity:3d079ebc0b332aad3305bb4a51c72edb",devnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d"},w={devnet:"https://devmx.ixo.earth",testnet:"https://testmx.ixo.earth",mainnet:"https://mx.ixo.earth"},k={devnet:"https://rooms.bot.devmx.ixo.earth",testnet:"https://rooms.bot.testmx.ixo.earth",mainnet:"https://rooms.bot.mx.ixo.earth"};var xe={devnet:"https://ixo-portal.vercel.app",testnet:"https://ixo-portal.vercel.app",mainnet:"https://ixo-portal.vercel.app"},O={mainnet:"https://impacthub.ixo.world/rpc/",testnet:"https://testnet.ixo.earth/rpc/",devnet:"https://devnet.ixo.earth/rpc/"},x=(r,e="This field is required")=>{let i=re.string().min(1,e).safeParse(r);if(!i.success)return i.error.message},ie=(r,e="This url is required or a valid URL")=>{let i=re.url(e).safeParse(r);if(!i.success)return i.error.message},Ce=(r,e="This number is required")=>{let i=re.number().min(1,e).safeParse(r);if(!i.success)return i.error.message};import{isCancel as $t,log as h,spinner as Xt,text as Bt}from"@clack/prompts";import{customMessages as Je,ixo as R,utils as me}from"@ixo/impactxclient-sdk";import{utils as de}from"@ixo/impactxclient-sdk";import{createMatrixApiClient as Wt}from"@ixo/matrixclient-sdk";import{sha256 as Et}from"@cosmjs/crypto";import{encrypt as St}from"eciesjs";import{ClientEvent as At,createClient as ae}from"matrix-js-sdk";import bt from"md5";var F=new Map;function ct(r){return F.get(r)instanceof Uint8Array}function lt(r){return F.get(r)}function ne(){F.clear()}async function ve({keys:r}){let e=Object.keys(r),t=e.find(ct);if(console.info("[] getSecretStorageKey",r,e,t),!t)return null;let i=lt(t);return[t,i]}function Re(r,e,t){F.set(r,t)}import{Bip39 as be,EnglishMnemonic as Pe,Secp256k1 as oe,sha256 as pt,Slip10 as Oe,Slip10Curve as Ie,stringToPath as Te}from"@cosmjs/crypto";import{DirectSecp256k1HdWallet as gt}from"@cosmjs/proto-signing";import{createQueryClient as Ne,createSigningClient as ut,customMessages as ft,ixo as ht,utils as yt}from"@ixo/impactxclient-sdk";import{createCipheriv as wt,randomBytes as xt}from"crypto";import{createQueryClient as xr,createRegistry as dt,utils as mt}from"@ixo/impactxclient-sdk";function M(r){try{return mt.proto.fromTimestamp(r).getTime()}catch{return}}var $={BasicAllowance:"/cosmos.feegrant.v1beta1.BasicAllowance",PeriodicAllowance:"/cosmos.feegrant.v1beta1.PeriodicAllowance"};var Ee=r=>{let e=dt();return(r??[]).map(t=>{let i=t.allowance,n=e.decode(i);switch(i.typeUrl){case $.BasicAllowance:return{granter:t.granter,grantee:t.grantee,type:$.BasicAllowance,expiration:n.expiration?M(n.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};case $.PeriodicAllowance:return{granter:t.granter,grantee:t.grantee,type:$.PeriodicAllowance,expiration:n.basic?.expiration?M(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?M(n.expiration):n.basic?.expiration?M(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}}})},Se=r=>{if(r==null)return!1;let e=typeof r=="object"?M(r):r;return e==null?!0:e<Date.now()},Ae=r=>r==null?!1:(typeof r=="object"?Number(r?.amount??0):typeof r=="string"?Number(r??0):r)<=5e-4;async function se(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=O[e];if(!t)throw new Error(`Invalid network: ${e}. Valid networks are: ${Object.keys(O).join(", ")}`);console.log(`\u{1F517} Using RPC URL: ${t}`);try{return!!(await(await Ne(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 Ue(r,e,t){try{let i=await t.getAccounts(),{address:n,pubkey:o}=i[0]??{},s=await Ct(n,e),a=s?.length?Ee(s)?.find(c=>!!c&&!Se(c.expiration)&&!Ae(c.limit))?.granter:void 0,l={typeUrl:"/ixo.iid.v1beta1.MsgCreateIidDocument",value:ht.iid.v1beta1.MsgCreateIidDocument.fromPartial({id:r,verifications:ft.iid.createIidVerificationMethods({did:r,pubkey:o,address:n,controller:r,type:"secp"}),signer:n,controllers:[r]})};await vt({offlineSigner:t,messages:[l],feegrantGranter:a,network:e})}catch(i){throw console.error(i),i}}async function Ct(r,e){try{let t=O[e];if(!t)throw new Error(`Invalid network: ${e}`);return(await(await Ne(t)).cosmos.feegrant.v1beta1.allowances({grantee:r}))?.allowances??[]}catch(t){console.error("queryAddressAllowances::",t.message);return}}var vt=async({offlineSigner:r,messages:e,memo:t="Signing with Mnemonic Demo",feegrantGranter:i,network:n})=>{let o=O[n];if(!o)throw new Error(`Invalid network: ${n}`);let s=await ut(o,r),a=await r.getAccounts(),{address:l}=a[0]??{},c=await s.simulate(l,e,t),y=(c>5e4?c:(e??[]).length*5e5)*1.7,U=Rt(y),E={amount:[{denom:"uixo",amount:String(Math.round(U.average))}],gas:String(Math.round(y)),granter:i},C=await s.signAndBroadcast(l,e,E,t,void 0);if(!!C.code)throw new Error(`Error when broadcasting tx ${C.transactionHash} at height ${C.height}. Code: ${C.code}; Raw log: ${C.rawLog}`)},Rt=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}},X=r=>new Promise(e=>setTimeout(e,r));function ke(r,e){let t=xt(16),i=wt("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 Me=async r=>{let e=await gt.fromMnemonic(r,{prefix:"ixo"}),t=(await e.getAccounts())[0],i=await be.mnemonicToSeed(new Pe(r)),n=Te("m/44'/118'/0'/0/0"),s=Oe.derivePath(Ie.Secp256k1,i,n).privkey,a=await oe.makeKeypair(s),l=oe.compressPubkey(a.pubkey);return{mnemonic:r,did:yt.did.generateSecpDid(t.address),baseAccount:t,async getAccounts(){return await e.getAccounts()},async signDirect(m,y){return await e.signDirect(m,y)},async sign(m){try{let y=await be.mnemonicToSeed(new Pe(r)),U=Te("m/44'/118'/0'/0/0"),{privkey:E}=Oe.derivePath(Ie.Secp256k1,y,U),C=new Uint8Array(Buffer.from(m,"base64")),Y=pt(C);return(await oe.createSignature(Y,E)).toFixedLength().slice(0,64)}catch(y){throw console.error("Error during signature creation:",y),y}}}};var Pt="/.well-known/matrix/client",ce=async({homeServerUrl:r,username:e,password:t,deviceName:i},n=!1)=>{let o=r,s=e,a=s.match(/^@(.+):(.+\..+)$/);a&&(s=a[1],o=a[2],o=n?o:await Mt(o));try{let l=We(o),c=await l.login("m.login.password",{identifier:{type:"m.id.user",user:Dt(s)},password:t,initial_device_display_name:i});return{accessToken:c.access_token,deviceId:c.device_id,userId:c.user_id,baseUrl:n?o:c?.well_known?.["m.homeserver"]?.base_url||l.baseUrl}}catch(l){let c=l.message;throw c==="Unknown message"&&(c="Please check your credentials"),console.error("mxLogin::",c),new Error(c)}};async function Ot(r){let e=await fetch(`${k[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 It(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 Tt(r,e){let t=new Uint8Array(Buffer.from(e,"hex")),i=new Uint8Array(Buffer.from(r,"utf8")),n=St(t,i);return Array.from(n,o=>o.toString(16).padStart(2,"0")).join("")}async function Nt(r,e,t,i,n){let o=await Ot(n),s=Tt(e,o.publicKey),a={address:r,encryptedPassword:s,publicKeyFingerprint:o.fingerprint,secpResult:{signature:t,challenge:i}},l=await fetch(`${k[n]}/user/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!l.ok){let c=await l.json();throw new Error(c.error||"Failed to create user account")}return await l.json()}async function De(r,e,t,i,n){try{let{challengeBase64:o}=It(r),s=await i.sign(o),a=Buffer.from(s).toString("base64");if(!(await Nt(r,e,a,o,n)).success)throw new Error("Failed to create matrix account via API");let c=w[n],m=le(r);return await ce({homeServerUrl:c,username:m,password:e,deviceName:t})}catch(o){throw console.error("mxRegisterWithSecp error:",o),o}}async function Le({homeServerUrl:r,username:e}){let t=We(r);try{return!!await t.isUsernameAvailable(e)}catch{return!1}}function We(r){if(!r)throw new Error("Home server URL is required to instantiate matrix client");return ae({baseUrl:r})}async function Ke({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=ae({baseUrl:r,accessToken:e,userId:t,deviceId:i,timelineSupport:!0,cryptoCallbacks:{getSecretStorageKey:ve,cacheSecretStorageKey:Re},verificationMethods:["m.sas.v1"]});return await n.initRustCrypto({useIndexedDB:!1}),n.setMaxListeners(20),await n.startClient({lazyLoadMembers:!0,includeArchivedRooms:!1}),await new Promise((o,s)=>{let a={NULL:()=>{console.info("[NULL] state")},SYNCING:()=>{},PREPARED:()=>{console.info(`[PREPARED] state: user ${t}`),o()},RECONNECTING:()=>{console.info("[RECONNECTING] state")},CATCHUP:()=>{console.info("[CATCHUP] state")},ERROR:()=>{s(new Error("[ERROR] state: starting matrix client"))},STOPPED:()=>{console.info("[STOPPED] state")}};n.on(At.Sync,l=>{a[l]()})}),n}async function _e({mxClient:r,baseUrl:e,accessToken:t,userId:i,deviceId:n}){let o=r;o||(o=ae({baseUrl:e,accessToken:t,userId:i,deviceId:n})),o&&(o.stopClient(),await o.logout().catch(console.error),o.clearStores())}function je(r){let e=r.getAccountData("m.cross_signing.master");return console.log("hasCrossSigningAccountData::masterKeyData",e),!!e}async function Fe(r,{securityPhrase:e,password:t,forceReset:i=!1,skipBootstrapSecureStorage:n=!1}){i&&ne();let o=r.getCrypto();if(!o)throw new Error("Failed to setup matrix cross signing - failed to get matrix crypto api");if(!n){let a=await o.createRecoveryKeyFromPassphrase(e);ne(),await o.bootstrapSecretStorage({createSecretStorageKey:async()=>a,setupNewSecretStorage:i})}let s=r.getUserId();return await o.bootstrapCrossSigning({authUploadDeviceSigningKeys:async function(a){await a(Lt({userId:s,password:t}))},setupNewCrossSigning:i}),await o.resetKeyBackup(),await X(300),!!r.getAccountData("m.cross_signing.master")}function le(r){if(!r)throw new Error("Address is required to generate matrix username");return"did-ixo-"+r}function $e(r){return Buffer.from(bt(r.replace(/ /g,""))).toString("base64").slice(0,24)}function Xe(r){let e=Et(new TextEncoder().encode(r.replace(/ /g,"")));return Buffer.from(e).toString("base64").slice(0,32)}function Ut(r){return r.replace(/^(https?:\/\/)/,"").replace(/\/$/,"")}function kt(r,e=""){return"did-ixo-"+r+e}function Be(r,e){return"#"+kt(r)+":"+Ut(e)}async function Mt(r){let e="https://";/^https?:\/\//.test(r)&&(e="");let t=`${e}${r}${Pt}`;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 Dt(r){return(r.indexOf("@")===0?r.substring(1):r).trim()}function Lt({userId:r,password:e}){return{type:"m.login.password",password:e,identifier:{type:"m.id.user",user:r}}}var Ve="Oracles CLI";async function qe({pin:r,oracleName:e,network:t,oracleAvatarUrl:i},n){try{let o=de.mnemonic.generateMnemonic(),s=await Me(o),a=s.baseAccount.address;console.log("\u2705 Wallet created:",a),await n(a);let l=de.did.generateSecpDid(a),c=await se(l,t);if(console.log("\u2705 DID exists:",c),!c&&(console.log("\u2705 DID does not exist, creating..."),await Ue(l,t,s),console.log("\u2705 DID created, waiting 500ms..."),await X(500),console.log("\u2705 Checking if DID exists..."),!await se(l,t)))throw new Error("Failed to create DID document");console.log("\u2705 DID created:",l);let m=de.mnemonic.generateMnemonic(12),y=w[t],U=le(a),E=$e(m),C=Xe(m);if(!await Le({homeServerUrl:y,username:U}))throw new Error("Matrix account already exists");let f=await De(a,E,Ve,s,t);if(!f?.accessToken)throw new Error("Failed to register matrix account");console.log("\u2705 Matrix account created:",f.userId);let b=await Ke({homeServerUrl:y,accessToken:f.accessToken,userId:f.userId,deviceId:f.deviceId});try{await Promise.all([b.setDisplayName(e),b.setAvatarUrl(i)])}catch(P){console.error("Failed to set display name or avatar url:",P)}let K=Wt({homeServerUrl:y,accessToken:f.accessToken}),Z=je(b);if(!Z&&(Z=await Fe(b,{securityPhrase:C,password:E,forceReset:!0}),!Z))throw new Error("Failed to setup cross signing");console.log("\u2705 Matrix cross-signing setup completed");let ot=Be(a,f.baseUrl),v=(await K.room.v1beta1.queryId(ot).catch(()=>{}))?.room_id??"";if(!v){let P=await fetch(`${k[t]}/room/source`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({did:l,userMatrixId:f.userId})});if(!P.ok)throw new Error("Failed to create matrix room");if(v=(await P.json()).roomId,!v)throw new Error("Failed to create user matrix room")}let ee=await K.room.v1beta1.listJoinedMembers(v).catch(()=>{}),te=!!ee?.joined?.[f.userId];if(!te){if(!(await K.room.v1beta1.join(v)).room_id)throw new Error("Failed to join matrix room");if(ee=await K.room.v1beta1.listJoinedMembers(v),te=!!ee?.joined?.[f.userId],!te)throw new Error("Failed to join matrix room")}console.log("\u2705 Matrix room created/joined:",v);let st=ke(m,r),ye=await fetch(`${y}/_matrix/client/r0/rooms/${v}/state/ixo.room.state.secure/encrypted_mnemonic`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${f.accessToken}`},body:JSON.stringify({encrypted_mnemonic:st})});if(!ye.ok)throw new Error("Failed to store encrypted mnemonic in matrix room");return await ye.json(),console.log("\u2705 Encrypted Matrix mnemonic stored in room"),await _e({mxClient:b,baseUrl:y,accessToken:f.accessToken,userId:f.userId,deviceId:f.deviceId}),{address:a,did:l,mnemonic:o,matrixUserId:f.userId,matrixRoomId:v,matrixMnemonic:m,matrixPassword:E,matrixAccessToken:f.accessToken,matrixRecoveryPhrase:m,pin:r,matrixDeviceName:Ve}}catch(o){throw console.error("Simplified registration failed:",o),o}}import{createMatrixApiClient as jt,utils as Ft}from"@ixo/matrixclient-sdk";import{CID as Kt}from"multiformats";import{base64 as _t}from"multiformats/bases/base64";import*as Ge from"multiformats/hashes/sha2";async function He(r){let e=r.startsWith("m")?r:"m"+r,t=_t.decode(e),i=await Ge.sha256.digest(t);return Kt.create(1,85,i).toString()}function ze(r){let e=new TextEncoder().encode(r);return btoa(String.fromCharCode(...Array.from(e)))}var D=async({data:r,fileName:e,config:t,wallet:i})=>{let n=jt({homeServerUrl:w[t.getValue("network")??"devnet"],accessToken:i?.matrix?.accessToken??""}),o=new File([JSON.stringify(r)],e+".json",{type:"application/ld+json"}),s=await n.media.v1beta1.upload(o.name,o.type,o),a=Ft.mxc.mxcUrlToHttp(w[t.getValue("network")??"devnet"],s.content_uri);if(!a)throw new Error("Failed to upload file to Matrix");let l=JSON.stringify(r),c=ze(l),m=await He(c);return{encrypted:"false",cid:m,proof:m,serviceEndpoint:a,mxc:s.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,this.MsgCreateEntityParams.value.verification=[...Je.iid.createIidVerificationMethods({did:e.did,pubkey:new Uint8Array(Buffer.from(e.pubKey)),address:e.address,controller:e.did,type:e.algo==="ed25519"?"ed":"secp"})],this.MsgCreateEntityParams.value.context=[],this.MsgCreateEntityParams.value.controller=[e.did],this.MsgCreateEntityParams.value.ownerAddress=e.address,this.MsgCreateEntityParams.value.ownerDid=e.did,this.MsgCreateEntityParams.value.service.push(R.iid.v1beta1.Service.fromPartial({id:"{id}#matrix",type:"Matrix",serviceEndpoint:"devmx.ixo.earth"})),this.MsgCreateEntityParams.value.relayerNode=we[this.config.getValue("network")??"devnet"]}wallet;MsgCreateEntityParams={typeUrl:"/ixo.entity.v1beta1.MsgCreateEntity",value:R.entity.v1beta1.MsgCreateEntity.fromPartial({entityType:"oracle",context:[],entityStatus:0,verification:[],controller:[],ownerAddress:"",ownerDid:"",relayerNode:"",service:[],linkedResource:[],accordedRight:[],linkedEntity:[],linkedClaim:[],startDate:me.proto.toTimestamp(new Date),endDate:me.proto.toTimestamp(new Date(Date.now()+100*365*24*60*60*1e3))})};async createAuthZConfig({oracleAccountAddress:e,oracleName:t,entityDid:i}){let o=await D({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",config:this.config,wallet:this.wallet});return R.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#orz",type:"oracleAuthZConfig",proof:o.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Orale AuthZ Config",serviceEndpoint:o.serviceEndpoint})}async createFeesConfig({entityDid:e,price:t}){let n=await D({data:{"@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:"uixo",priceSpecification:{"@type":"PaymentChargeSpecification",priceCurrency:"uixo",price:t,unitCode:"MON",billingIncrement:1,billingPeriod:"P1M",priceType:"Subscription",maxPrice:t},eligibleQuantity:{"@type":"QuantitativeValue",value:1,unitCode:"MON"}}},fileName:"fees",config:this.config,wallet:this.wallet});return R.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#fee",type:"pricingList",proof:n.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Pricing List",serviceEndpoint:n.serviceEndpoint})}async createOracleConfigFiles({oracleName:e,entityDid:t,price:i,oracleAccountAddress:n}){let o=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!o)throw new Error("SignX client or wallet not found");let a=(await Promise.all([this.createAuthZConfig({oracleName:e,entityDid:t,oracleAccountAddress:n}),this.createFeesConfig({entityDid:t,price:i})])).map(m=>({typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:R.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:t,linkedResource:R.iid.v1beta1.LinkedResource.fromPartial({id:m.id,description:m.description,type:m.type,proof:m.proof,mediaType:m.mediaType,encrypted:m.encrypted,serviceEndpoint:m.serviceEndpoint}),signer:o})}));h.info("Sign to edit the entity and add the config files");let l=await this.wallet.signXClient.transact(a,this.wallet.wallet);return this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(l)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction()}async addPage({content:e,title:t}){let n=await D({data:{title:t,blocks:[{id:"title-block",type:"heading",props:{textColor:"default",backgroundColor:"default",textAlignment:"left"},content:[{type:"text",text:t,styles:{}}]},{id:"content-block",type:"paragraph",props:{textColor:"default",backgroundColor:"default",textAlignment:"left"},content:[{type:"text",text:e,styles:{}}]}]},fileName:"page",config:this.config,wallet:this.wallet}),o={id:"{id}#pag",type:"Settings",description:"Page",mediaType:"application/json",serviceEndpoint:n.serviceEndpoint,proof:n.proof,encrypted:"false",right:""};this.MsgCreateEntityParams.value.linkedResource.push(R.iid.v1beta1.LinkedResource.fromPartial(o))}async addProfile({orgName:e,name:t,logo:i,coverImage:n,location:o,description:s}){let l=await D({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",config:this.config,wallet:this.wallet}),c={id:"{id}#pro",type:"Settings",description:"Profile",mediaType:"application/json",serviceEndpoint:l.serviceEndpoint,proof:l.proof,encrypted:"false",right:""};this.MsgCreateEntityParams.value.linkedResource.push(R.iid.v1beta1.LinkedResource.fromPartial(c))}async addServices(e){this.MsgCreateEntityParams.value.service.push(...e.map(t=>R.iid.v1beta1.Service.fromPartial(t)))}async setParentProtocol(e){this.MsgCreateEntityParams.value.context.push(...Je.iid.createAgentIidContext([{key:"class",val:e}]))}returnExecutableMsg(){return this.MsgCreateEntityParams}async execute(e){h.info("Adding page"),await this.addPage(e.page),h.info("Adding profile"),await this.addProfile(e.profile),h.info("Adding services"),await this.addServices(e.services),h.info("Adding parent protocol"),await this.setParentProtocol(e.parentProtocol);let t=this.returnExecutableMsg();if(!this.wallet.signXClient||!this.wallet.wallet)throw new Error("SignX client not found");h.info("Sign this transaction to create the entity");let i=await this.wallet.signXClient.transact([t],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(i)),await this.wallet.signXClient.pollNextTransaction();let n=await this.wallet.signXClient.awaitTransaction();h.success("Entity created -- wait to attach the required config files"),h.info("Creating Oracle Wallet and Matrix Account");let o=await Bt({message:"Enter a PIN to secure your Matrix Vault:",initialValue:"",defaultValue:"",validate(c){return x(c,"PIN is required")}});$t(o)&&(h.error("User cancelled"),process.exit(1));let s=await qe({pin:o,oracleName:e.oracleConfig.oracleName,network:this.config.getValue("network"),oracleAvatarUrl:e.profile.logo},async c=>{await this.wallet.sendTokens(c,25e4)}),a=me.common.getValueFromEvents(n,"wasm","token_id");await this.createOracleConfigFiles({oracleName:e.oracleConfig.oracleName,price:e.oracleConfig.price,oracleAccountAddress:s.address,entityDid:a}),h.success("Entity created -- config files attached");let l=Xt();return l.start("Creating Entity Matrix Room..."),l.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"),h.info(`Oracle DID: ${s.did}`),h.info(`Oracle Account Address: ${s.address}`),h.info(`Oracle Account Mnemonic: ${s.mnemonic}`),h.info(`Matrix User ID: ${s.matrixUserId}`),h.info(`Matrix Password: ${s.matrixPassword}`),this.config.addValue("registerUserResult",s),this.config.addValue("entityDid",a),a}};var I=class{constructor(e,t){this.wallet=e;this.config=t;this.createEntity=new B(this.wallet,this.config)}name="create-entity";description="Create an entity";createEntity;async execute(){this.config.getValue("network")||await j(this.config);let t=await p.group({oracleName:()=>p.text({message:"What is the name of the oracle?",initialValue:"My oracle",validate(s){return x(s,"Oracle name is required")}}),oraclePrice:()=>p.text({message:"What is the price of the oracle in IXO CREDITS?",initialValue:"100",validate(s){return Ce(parseInt(s),"Oracle price is required and must be a number")}}),page:()=>p.group({title:()=>p.text({message:"What is the title of the oracle entity page?",initialValue:"AI Agent Oracle",validate(s){return x(s,"Title is required")}}),content:()=>p.text({message:"What is the content of the oracle entity page?",initialValue:"### Oracle built to help u with daily tasks",validate(s){return x(s,"Content is required")}})}),profile:()=>p.group({orgName:()=>p.text({message:"What is the name of the organization?",initialValue:"IXO",validate(s){return x(s,"Organization name is required")}}),name:()=>p.text({message:"What is the name of the profile?",initialValue:"My oracle",validate(s){return x(s,"Profile name is required")}}),logo:({results:s})=>p.text({message:"What is the logo of the profile?",initialValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${s?.name??"IXO"}`,defaultValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${s?.name??"IXO"}`,validate(a){return a?ie(a,"Logo is required or a valid URL"):`https://api.dicebear.com/8.x/bottts/svg?seed=${s?.name??"IXO"}`}}),coverImage:({results:s})=>p.text({message:"What is the cover image of the profile?",initialValue:s.logo,defaultValue:s.logo,validate(a){return a?ie(a,"Cover image is required or a valid URL"):s.logo}}),location:()=>p.text({message:"What is the location of your domain?",initialValue:"New York, NY",validate(s){return x(s,"Location is required")}}),description:()=>p.text({message:"What is the description of the entity (profile)?",initialValue:"We are a company that helps you with daily tasks",validate(s){return x(s,"Description is required")}})}),parentProtocol:()=>p.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"})},{onCancel:()=>{p.cancel("Operation cancelled."),process.exit(0)}}),i=await this.createEntity.execute({oracleConfig:{oracleName:t.oracleName,price:parseInt(t.oraclePrice)},page:t.page,profile:{orgName:t.profile.orgName,name:t.profile.name,logo:t.profile.logo,coverImage:t.profile.coverImage,location:t.profile.location,description:t.profile.description},services:[{id:"{id}#api",serviceEndpoint:"http://localhost:4000",type:"oracleService"},{id:"{id}#ws",serviceEndpoint:"http://localhost:4000",type:"wsService"}],parentProtocol:t.parentProtocol});p.log.info("API for the oracle is: http://localhost:4000 | You can change this after you deploy the oracle");let o=`${xe[this.config.getValue("network")??"devnet"]}/oracle/${i}/overview`;return p.log.info(`Oracle created successfully: ${i}`),p.log.info(`Oracle URL: ${o}`),{success:!0,data:`Entity created successfully: ${i}`}}};var L=class{constructor(e){this.registry=e}name="help";description="Show help information and available commands";async execute(){return{success:!0,data:`
2
+ import{cancel as fe,intro as nr,isCancel as it,log as W,outro as or,select as nt,spinner as sr}from"@clack/prompts";import b from"process";var _=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 p from"@clack/prompts";import{select as at}from"@clack/prompts";import{z as re}from"zod";var j=async r=>{let e=await at({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},we={mainnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d",testnet:"did:ixo:entity:3d079ebc0b332aad3305bb4a51c72edb",devnet:"did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d"},x={devnet:"https://devmx.ixo.earth",testnet:"https://testmx.ixo.earth",mainnet:"https://mx.ixo.earth"},k={devnet:"https://rooms.bot.devmx.ixo.earth",testnet:"https://rooms.bot.testmx.ixo.earth",mainnet:"https://rooms.bot.mx.ixo.earth"};var xe={devnet:"https://ixo-portal.vercel.app",testnet:"https://ixo-portal.vercel.app",mainnet:"https://ixo-portal.vercel.app"},I={mainnet:"https://impacthub.ixo.world/rpc/",testnet:"https://testnet.ixo.earth/rpc/",devnet:"https://devnet.ixo.earth/rpc/"},C=(r,e="This field is required")=>{let i=re.string().min(1,e).safeParse(r);if(!i.success)return i.error.message},ie=(r,e="This url is required or a valid URL")=>{let i=re.url(e).safeParse(r);if(!i.success)return i.error.message},Ce=(r,e="This number is required")=>{let i=re.number().min(1,e).safeParse(r);if(!i.success)return i.error.message};import{isCancel as $t,log as y,spinner as Xt,text as Bt}from"@clack/prompts";import{customMessages as Je,ixo as E,utils as me}from"@ixo/impactxclient-sdk";import{utils as de}from"@ixo/impactxclient-sdk";import{createMatrixApiClient as Wt}from"@ixo/matrixclient-sdk";import{sha256 as Et}from"@cosmjs/crypto";import{encrypt as St}from"eciesjs";import{ClientEvent as At,createClient as ae}from"matrix-js-sdk";import bt from"md5";var F=new Map;function ct(r){return F.get(r)instanceof Uint8Array}function lt(r){return F.get(r)}function ne(){F.clear()}async function ve({keys:r}){let e=Object.keys(r),t=e.find(ct);if(console.info("[] getSecretStorageKey",r,e,t),!t)return null;let i=lt(t);return[t,i]}function Re(r,e,t){F.set(r,t)}import{Bip39 as be,EnglishMnemonic as Pe,Secp256k1 as oe,sha256 as pt,Slip10 as Oe,Slip10Curve as Ie,stringToPath as Te}from"@cosmjs/crypto";import{DirectSecp256k1HdWallet as gt}from"@cosmjs/proto-signing";import{createQueryClient as Ne,createSigningClient as ut,customMessages as ft,ixo as ht,utils as yt}from"@ixo/impactxclient-sdk";import{createCipheriv as wt,randomBytes as xt}from"crypto";import{createQueryClient as xr,createRegistry as dt,utils as mt}from"@ixo/impactxclient-sdk";function M(r){try{return mt.proto.fromTimestamp(r).getTime()}catch{return}}var $={BasicAllowance:"/cosmos.feegrant.v1beta1.BasicAllowance",PeriodicAllowance:"/cosmos.feegrant.v1beta1.PeriodicAllowance"};var Ee=r=>{let e=dt();return(r??[]).map(t=>{let i=t.allowance,n=e.decode(i);switch(i.typeUrl){case $.BasicAllowance:return{granter:t.granter,grantee:t.grantee,type:$.BasicAllowance,expiration:n.expiration?M(n.expiration):null,limit:n.spendLimit?.length?n.spendLimit.find(o=>o.denom==="uixo")?.amount:null,msgs:[]};case $.PeriodicAllowance:return{granter:t.granter,grantee:t.grantee,type:$.PeriodicAllowance,expiration:n.basic?.expiration?M(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?M(n.expiration):n.basic?.expiration?M(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}}})},Se=r=>{if(r==null)return!1;let e=typeof r=="object"?M(r):r;return e==null?!0:e<Date.now()},Ae=r=>r==null?!1:(typeof r=="object"?Number(r?.amount??0):typeof r=="string"?Number(r??0):r)<=5e-4;async function se(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=I[e];if(!t)throw new Error(`Invalid network: ${e}. Valid networks are: ${Object.keys(I).join(", ")}`);console.log(`\u{1F517} Using RPC URL: ${t}`);try{return!!(await(await Ne(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 Ue(r,e,t){try{let i=await t.getAccounts(),{address:n,pubkey:o}=i[0]??{},s=await Ct(n,e),a=s?.length?Ee(s)?.find(c=>!!c&&!Se(c.expiration)&&!Ae(c.limit))?.granter:void 0,l={typeUrl:"/ixo.iid.v1beta1.MsgCreateIidDocument",value:ht.iid.v1beta1.MsgCreateIidDocument.fromPartial({id:r,verifications:ft.iid.createIidVerificationMethods({did:r,pubkey:o,address:n,controller:r,type:"secp"}),signer:n,controllers:[r]})};await vt({offlineSigner:t,messages:[l],feegrantGranter:a,network:e})}catch(i){throw console.error(i),i}}async function Ct(r,e){try{let t=I[e];if(!t)throw new Error(`Invalid network: ${e}`);return(await(await Ne(t)).cosmos.feegrant.v1beta1.allowances({grantee:r}))?.allowances??[]}catch(t){console.error("queryAddressAllowances::",t.message);return}}var vt=async({offlineSigner:r,messages:e,memo:t="Signing with Mnemonic Demo",feegrantGranter:i,network:n})=>{let o=I[n];if(!o)throw new Error(`Invalid network: ${n}`);let s=await ut(o,r),a=await r.getAccounts(),{address:l}=a[0]??{},c=await s.simulate(l,e,t),f=(c>5e4?c:(e??[]).length*5e5)*1.7,S=Rt(f),w={amount:[{denom:"uixo",amount:String(Math.round(S.average))}],gas:String(Math.round(f)),granter:i},v=await s.signAndBroadcast(l,e,w,t,void 0);if(!!v.code)throw new Error(`Error when broadcasting tx ${v.transactionHash} at height ${v.height}. Code: ${v.code}; Raw log: ${v.rawLog}`)},Rt=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}},X=r=>new Promise(e=>setTimeout(e,r));function ke(r,e){let t=xt(16),i=wt("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 Me=async r=>{let e=await gt.fromMnemonic(r,{prefix:"ixo"}),t=(await e.getAccounts())[0],i=await be.mnemonicToSeed(new Pe(r)),n=Te("m/44'/118'/0'/0/0"),s=Oe.derivePath(Ie.Secp256k1,i,n).privkey,a=await oe.makeKeypair(s),l=oe.compressPubkey(a.pubkey);return{mnemonic:r,did:yt.did.generateSecpDid(t.address),baseAccount:t,async getAccounts(){return await e.getAccounts()},async signDirect(m,f){return await e.signDirect(m,f)},async sign(m){try{let f=await be.mnemonicToSeed(new Pe(r)),S=Te("m/44'/118'/0'/0/0"),{privkey:w}=Oe.derivePath(Ie.Secp256k1,f,S),v=new Uint8Array(Buffer.from(m,"base64")),Y=pt(v);return(await oe.createSignature(Y,w)).toFixedLength().slice(0,64)}catch(f){throw console.error("Error during signature creation:",f),f}}}};var Pt="/.well-known/matrix/client",ce=async({homeServerUrl:r,username:e,password:t,deviceName:i},n=!1)=>{let o=r,s=e,a=s.match(/^@(.+):(.+\..+)$/);a&&(s=a[1],o=a[2],o=n?o:await Mt(o));try{let l=We(o),c=await l.login("m.login.password",{identifier:{type:"m.id.user",user:Dt(s)},password:t,initial_device_display_name:i});return{accessToken:c.access_token,deviceId:c.device_id,userId:c.user_id,baseUrl:n?o:c?.well_known?.["m.homeserver"]?.base_url||l.baseUrl}}catch(l){let c=l.message;throw c==="Unknown message"&&(c="Please check your credentials"),console.error("mxLogin::",c),new Error(c)}};async function Ot(r){let e=await fetch(`${k[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 It(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 Tt(r,e){let t=new Uint8Array(Buffer.from(e,"hex")),i=new Uint8Array(Buffer.from(r,"utf8")),n=St(t,i);return Array.from(n,o=>o.toString(16).padStart(2,"0")).join("")}async function Nt(r,e,t,i,n){let o=await Ot(n),s=Tt(e,o.publicKey),a={address:r,encryptedPassword:s,publicKeyFingerprint:o.fingerprint,secpResult:{signature:t,challenge:i}},l=await fetch(`${k[n]}/user/create`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)});if(!l.ok){let c=await l.json();throw new Error(c.error||"Failed to create user account")}return await l.json()}async function De(r,e,t,i,n){try{let{challengeBase64:o}=It(r),s=await i.sign(o),a=Buffer.from(s).toString("base64");if(!(await Nt(r,e,a,o,n)).success)throw new Error("Failed to create matrix account via API");let c=x[n],m=le(r);return await ce({homeServerUrl:c,username:m,password:e,deviceName:t})}catch(o){throw console.error("mxRegisterWithSecp error:",o),o}}async function Le({homeServerUrl:r,username:e}){let t=We(r);try{return!!await t.isUsernameAvailable(e)}catch{return!1}}function We(r){if(!r)throw new Error("Home server URL is required to instantiate matrix client");return ae({baseUrl:r})}async function Ke({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=ae({baseUrl:r,accessToken:e,userId:t,deviceId:i,timelineSupport:!0,cryptoCallbacks:{getSecretStorageKey:ve,cacheSecretStorageKey:Re},verificationMethods:["m.sas.v1"]});return await n.initRustCrypto({useIndexedDB:!1}),n.setMaxListeners(20),await n.startClient({lazyLoadMembers:!0,includeArchivedRooms:!1}),await new Promise((o,s)=>{let a={NULL:()=>{console.info("[NULL] state")},SYNCING:()=>{},PREPARED:()=>{console.info(`[PREPARED] state: user ${t}`),o()},RECONNECTING:()=>{console.info("[RECONNECTING] state")},CATCHUP:()=>{console.info("[CATCHUP] state")},ERROR:()=>{s(new Error("[ERROR] state: starting matrix client"))},STOPPED:()=>{console.info("[STOPPED] state")}};n.on(At.Sync,l=>{a[l]()})}),n}async function _e({mxClient:r,baseUrl:e,accessToken:t,userId:i,deviceId:n}){let o=r;o||(o=ae({baseUrl:e,accessToken:t,userId:i,deviceId:n})),o&&(o.stopClient(),await o.logout().catch(console.error),o.clearStores())}function je(r){let e=r.getAccountData("m.cross_signing.master");return console.log("hasCrossSigningAccountData::masterKeyData",e),!!e}async function Fe(r,{securityPhrase:e,password:t,forceReset:i=!1,skipBootstrapSecureStorage:n=!1}){i&&ne();let o=r.getCrypto();if(!o)throw new Error("Failed to setup matrix cross signing - failed to get matrix crypto api");if(!n){let a=await o.createRecoveryKeyFromPassphrase(e);ne(),await o.bootstrapSecretStorage({createSecretStorageKey:async()=>a,setupNewSecretStorage:i})}let s=r.getUserId();return await o.bootstrapCrossSigning({authUploadDeviceSigningKeys:async function(a){await a(Lt({userId:s,password:t}))},setupNewCrossSigning:i}),await o.resetKeyBackup(),await X(300),!!r.getAccountData("m.cross_signing.master")}function le(r){if(!r)throw new Error("Address is required to generate matrix username");return"did-ixo-"+r}function $e(r){return Buffer.from(bt(r.replace(/ /g,""))).toString("base64").slice(0,24)}function Xe(r){let e=Et(new TextEncoder().encode(r.replace(/ /g,"")));return Buffer.from(e).toString("base64").slice(0,32)}function Ut(r){return r.replace(/^(https?:\/\/)/,"").replace(/\/$/,"")}function kt(r,e=""){return"did-ixo-"+r+e}function Be(r,e){return"#"+kt(r)+":"+Ut(e)}async function Mt(r){let e="https://";/^https?:\/\//.test(r)&&(e="");let t=`${e}${r}${Pt}`;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 Dt(r){return(r.indexOf("@")===0?r.substring(1):r).trim()}function Lt({userId:r,password:e}){return{type:"m.login.password",password:e,identifier:{type:"m.id.user",user:r}}}var Ve="Oracles CLI";async function qe({pin:r,oracleName:e,network:t,oracleAvatarUrl:i},n){try{let o=de.mnemonic.generateMnemonic(),s=await Me(o),a=s.baseAccount.address;console.log("\u2705 Wallet created:",a),await n(a);let l=de.did.generateSecpDid(a),c=await se(l,t);if(console.log("\u2705 DID exists:",c),!c&&(console.log("\u2705 DID does not exist, creating..."),await Ue(l,t,s),console.log("\u2705 DID created, waiting 500ms..."),await X(500),console.log("\u2705 Checking if DID exists..."),!await se(l,t)))throw new Error("Failed to create DID document");console.log("\u2705 DID created:",l);let m=de.mnemonic.generateMnemonic(12),f=x[t],S=le(a),w=$e(m),v=Xe(m);if(!await Le({homeServerUrl:f,username:S}))throw new Error("Matrix account already exists");let h=await De(a,w,Ve,s,t);if(!h?.accessToken)throw new Error("Failed to register matrix account");console.log("\u2705 Matrix account created:",h.userId);let P=await Ke({homeServerUrl:f,accessToken:h.accessToken,userId:h.userId,deviceId:h.deviceId});try{await Promise.all([P.setDisplayName(e),P.setAvatarUrl(i)])}catch(O){console.error("Failed to set display name or avatar url:",O)}let K=Wt({homeServerUrl:f,accessToken:h.accessToken}),Z=je(P);if(!Z&&(Z=await Fe(P,{securityPhrase:v,password:w,forceReset:!0}),!Z))throw new Error("Failed to setup cross signing");console.log("\u2705 Matrix cross-signing setup completed");let ot=Be(a,h.baseUrl),R=(await K.room.v1beta1.queryId(ot).catch(()=>{}))?.room_id??"";if(!R){let O=await fetch(`${k[t]}/room/source`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({did:l,userMatrixId:h.userId})});if(!O.ok)throw new Error("Failed to create matrix room");if(R=(await O.json()).roomId,!R)throw new Error("Failed to create user matrix room")}let ee=await K.room.v1beta1.listJoinedMembers(R).catch(()=>{}),te=!!ee?.joined?.[h.userId];if(!te){if(!(await K.room.v1beta1.join(R)).room_id)throw new Error("Failed to join matrix room");if(ee=await K.room.v1beta1.listJoinedMembers(R),te=!!ee?.joined?.[h.userId],!te)throw new Error("Failed to join matrix room")}console.log("\u2705 Matrix room created/joined:",R);let st=ke(m,r),ye=await fetch(`${f}/_matrix/client/r0/rooms/${R}/state/ixo.room.state.secure/encrypted_mnemonic`,{method:"PUT",headers:{"Content-Type":"application/json",Authorization:`Bearer ${h.accessToken}`},body:JSON.stringify({encrypted_mnemonic:st})});if(!ye.ok)throw new Error("Failed to store encrypted mnemonic in matrix room");return await ye.json(),console.log("\u2705 Encrypted Matrix mnemonic stored in room"),await _e({mxClient:P,baseUrl:f,accessToken:h.accessToken,userId:h.userId,deviceId:h.deviceId}),{address:a,did:l,mnemonic:o,matrixUserId:h.userId,matrixRoomId:R,matrixMnemonic:m,matrixPassword:w,matrixAccessToken:h.accessToken,matrixRecoveryPhrase:m,pin:r,matrixDeviceName:Ve}}catch(o){throw console.error("Simplified registration failed:",o),o}}import{createMatrixApiClient as jt,utils as Ft}from"@ixo/matrixclient-sdk";import{CID as Kt}from"multiformats";import{base64 as _t}from"multiformats/bases/base64";import*as Ge from"multiformats/hashes/sha2";async function He(r){let e=r.startsWith("m")?r:"m"+r,t=_t.decode(e),i=await Ge.sha256.digest(t);return Kt.create(1,85,i).toString()}function ze(r){let e=new TextEncoder().encode(r);return btoa(String.fromCharCode(...Array.from(e)))}var D=async({data:r,fileName:e,config:t,wallet:i})=>{let n=jt({homeServerUrl:x[t.getValue("network")??"devnet"],accessToken:i?.matrix?.accessToken??""}),o=JSON.stringify(r),s=Buffer.from(o,"utf8"),a=e+".json",c=await n.media.v1beta1.upload(a,"application/ld+json",s),m=Ft.mxc.mxcUrlToHttp(x[t.getValue("network")??"devnet"],c.content_uri);if(!m)throw new Error("Failed to upload file to Matrix");let f=JSON.stringify(r),S=ze(f),w=await He(S);return{encrypted:"false",cid:w,proof:w,serviceEndpoint:m,mxc:c.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,this.MsgCreateEntityParams.value.verification=[...Je.iid.createIidVerificationMethods({did:e.did,pubkey:new Uint8Array(Buffer.from(e.pubKey)),address:e.address,controller:e.did,type:e.algo==="ed25519"?"ed":"secp"})],this.MsgCreateEntityParams.value.context=[],this.MsgCreateEntityParams.value.controller=[e.did],this.MsgCreateEntityParams.value.ownerAddress=e.address,this.MsgCreateEntityParams.value.ownerDid=e.did,this.MsgCreateEntityParams.value.service.push(E.iid.v1beta1.Service.fromPartial({id:"{id}#matrix",type:"Matrix",serviceEndpoint:"devmx.ixo.earth"})),this.MsgCreateEntityParams.value.relayerNode=we[this.config.getValue("network")??"devnet"]}wallet;MsgCreateEntityParams={typeUrl:"/ixo.entity.v1beta1.MsgCreateEntity",value:E.entity.v1beta1.MsgCreateEntity.fromPartial({entityType:"oracle",context:[],entityStatus:0,verification:[],controller:[],ownerAddress:"",ownerDid:"",relayerNode:"",service:[],linkedResource:[],accordedRight:[],linkedEntity:[],linkedClaim:[],startDate:me.proto.toTimestamp(new Date),endDate:me.proto.toTimestamp(new Date(Date.now()+100*365*24*60*60*1e3))})};async createAuthZConfig({oracleAccountAddress:e,oracleName:t,entityDid:i}){let o=await D({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",config:this.config,wallet:this.wallet});return E.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#orz",type:"oracleAuthZConfig",proof:o.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Orale AuthZ Config",serviceEndpoint:o.serviceEndpoint})}async createFeesConfig({entityDid:e,price:t}){let n=await D({data:{"@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:"uixo",priceSpecification:{"@type":"PaymentChargeSpecification",priceCurrency:"uixo",price:t,unitCode:"MON",billingIncrement:1,billingPeriod:"P1M",priceType:"Subscription",maxPrice:t},eligibleQuantity:{"@type":"QuantitativeValue",value:1,unitCode:"MON"}}},fileName:"fees",config:this.config,wallet:this.wallet});return E.iid.v1beta1.LinkedResource.fromPartial({id:"{id}#fee",type:"pricingList",proof:n.proof,right:"",encrypted:"false",mediaType:"application/json",description:"Pricing List",serviceEndpoint:n.serviceEndpoint})}async createOracleConfigFiles({oracleName:e,entityDid:t,price:i,oracleAccountAddress:n}){let o=this.wallet.wallet?.address;if(!this.wallet.signXClient||!this.wallet.wallet||!o)throw new Error("SignX client or wallet not found");let a=(await Promise.all([this.createAuthZConfig({oracleName:e,entityDid:t,oracleAccountAddress:n}),this.createFeesConfig({entityDid:t,price:i})])).map(m=>({typeUrl:"/ixo.iid.v1beta1.MsgAddLinkedResource",value:E.iid.v1beta1.MsgAddLinkedResource.fromPartial({id:t,linkedResource:E.iid.v1beta1.LinkedResource.fromPartial({id:m.id,description:m.description,type:m.type,proof:m.proof,mediaType:m.mediaType,encrypted:m.encrypted,serviceEndpoint:m.serviceEndpoint}),signer:o})}));y.info("Sign to edit the entity and add the config files");let l=await this.wallet.signXClient.transact(a,this.wallet.wallet);return this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(l)),await this.wallet.signXClient.pollNextTransaction(),await this.wallet.signXClient.awaitTransaction()}async addPage({content:e,title:t}){let n=await D({data:{title:t,blocks:[{id:"title-block",type:"heading",props:{textColor:"default",backgroundColor:"default",textAlignment:"left"},content:[{type:"text",text:t,styles:{}}]},{id:"content-block",type:"paragraph",props:{textColor:"default",backgroundColor:"default",textAlignment:"left"},content:[{type:"text",text:e,styles:{}}]}]},fileName:"page",config:this.config,wallet:this.wallet}),o={id:"{id}#pag",type:"Settings",description:"Page",mediaType:"application/json",serviceEndpoint:n.serviceEndpoint,proof:n.proof,encrypted:"false",right:""};this.MsgCreateEntityParams.value.linkedResource.push(E.iid.v1beta1.LinkedResource.fromPartial(o))}async addProfile({orgName:e,name:t,logo:i,coverImage:n,location:o,description:s}){let l=await D({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",config:this.config,wallet:this.wallet}),c={id:"{id}#pro",type:"Settings",description:"Profile",mediaType:"application/json",serviceEndpoint:l.serviceEndpoint,proof:l.proof,encrypted:"false",right:""};this.MsgCreateEntityParams.value.linkedResource.push(E.iid.v1beta1.LinkedResource.fromPartial(c))}async addServices(e){this.MsgCreateEntityParams.value.service.push(...e.map(t=>E.iid.v1beta1.Service.fromPartial(t)))}async setParentProtocol(e){this.MsgCreateEntityParams.value.context.push(...Je.iid.createAgentIidContext([{key:"class",val:e}]))}returnExecutableMsg(){return this.MsgCreateEntityParams}async execute(e){y.info("Adding page"),await this.addPage(e.page),y.info("Adding profile"),await this.addProfile(e.profile),y.info("Adding services"),await this.addServices(e.services),y.info("Adding parent protocol"),await this.setParentProtocol(e.parentProtocol);let t=this.returnExecutableMsg();if(!this.wallet.signXClient||!this.wallet.wallet)throw new Error("SignX client not found");y.info("Sign this transaction to create the entity");let i=await this.wallet.signXClient.transact([t],this.wallet.wallet);this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(i)),await this.wallet.signXClient.pollNextTransaction();let n=await this.wallet.signXClient.awaitTransaction();y.success("Entity created -- wait to attach the required config files"),y.info("Creating Oracle Wallet and Matrix Account");let o=await Bt({message:"Enter a PIN to secure your Matrix Vault:",initialValue:"",defaultValue:"",validate(c){return C(c,"PIN is required")}});$t(o)&&(y.error("User cancelled"),process.exit(1));let s=await qe({pin:o,oracleName:e.oracleConfig.oracleName,network:this.config.getValue("network"),oracleAvatarUrl:e.profile.logo},async c=>{await this.wallet.sendTokens(c,25e4)}),a=me.common.getValueFromEvents(n,"wasm","token_id");await this.createOracleConfigFiles({oracleName:e.oracleConfig.oracleName,price:e.oracleConfig.price,oracleAccountAddress:s.address,entityDid:a}),y.success("Entity created -- config files attached");let l=Xt();return l.start("Creating Entity Matrix Room..."),l.stop("Room created -- room joined"),y.warn("Please save the following information in a secure location as it is not stored:"),y.info("ORACLE ACCOUNT DETAILS"),y.info(`Oracle DID: ${s.did}`),y.info(`Oracle Account Address: ${s.address}`),y.info(`Oracle Account Mnemonic: ${s.mnemonic}`),y.info(`Matrix User ID: ${s.matrixUserId}`),y.info(`Matrix Password: ${s.matrixPassword}`),this.config.addValue("registerUserResult",s),this.config.addValue("entityDid",a),a}};var T=class{constructor(e,t){this.wallet=e;this.config=t;this.createEntity=new B(this.wallet,this.config)}name="create-entity";description="Create an entity";createEntity;async execute(){this.config.getValue("network")||await j(this.config);let t=await p.group({oracleName:()=>p.text({message:"What is the name of the oracle?",initialValue:"My oracle",validate(s){return C(s,"Oracle name is required")}}),oraclePrice:()=>p.text({message:"What is the price of the oracle in IXO CREDITS?",initialValue:"100",validate(s){return Ce(parseInt(s),"Oracle price is required and must be a number")}}),page:()=>p.group({title:()=>p.text({message:"What is the title of the oracle entity page?",initialValue:"AI Agent Oracle",validate(s){return C(s,"Title is required")}}),content:()=>p.text({message:"What is the content of the oracle entity page?",initialValue:"### Oracle built to help u with daily tasks",validate(s){return C(s,"Content is required")}})}),profile:()=>p.group({orgName:()=>p.text({message:"What is the name of the organization?",initialValue:"IXO",validate(s){return C(s,"Organization name is required")}}),name:()=>p.text({message:"What is the name of the profile?",initialValue:"My oracle",validate(s){return C(s,"Profile name is required")}}),logo:({results:s})=>p.text({message:"What is the logo of the profile?",initialValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${s?.name??"IXO"}`,defaultValue:`https://api.dicebear.com/8.x/bottts/svg?seed=${s?.name??"IXO"}`,validate(a){return a?ie(a,"Logo is required or a valid URL"):`https://api.dicebear.com/8.x/bottts/svg?seed=${s?.name??"IXO"}`}}),coverImage:({results:s})=>p.text({message:"What is the cover image of the profile?",initialValue:s.logo,defaultValue:s.logo,validate(a){return a?ie(a,"Cover image is required or a valid URL"):s.logo}}),location:()=>p.text({message:"What is the location of your domain?",initialValue:"New York, NY",validate(s){return C(s,"Location is required")}}),description:()=>p.text({message:"What is the description of the entity (profile)?",initialValue:"We are a company that helps you with daily tasks",validate(s){return C(s,"Description is required")}})}),parentProtocol:()=>p.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"})},{onCancel:()=>{p.cancel("Operation cancelled."),process.exit(0)}}),i=await this.createEntity.execute({oracleConfig:{oracleName:t.oracleName,price:parseInt(t.oraclePrice)},page:t.page,profile:{orgName:t.profile.orgName,name:t.profile.name,logo:t.profile.logo,coverImage:t.profile.coverImage,location:t.profile.location,description:t.profile.description},services:[{id:"{id}#api",serviceEndpoint:"http://localhost:4000",type:"oracleService"},{id:"{id}#ws",serviceEndpoint:"http://localhost:4000",type:"wsService"}],parentProtocol:t.parentProtocol});p.log.info("API for the oracle is: http://localhost:4000 | You can change this after you deploy the oracle");let o=`${xe[this.config.getValue("network")??"devnet"]}/oracle/${i}/overview`;return p.log.info(`Oracle created successfully: ${i}`),p.log.info(`Oracle URL: ${o}`),{success:!0,data:`Entity created successfully: ${i}`}}};var L=class{constructor(e){this.registry=e}name="help";description="Show help information and available commands";async execute(){return{success:!0,data:`
3
3
  IXO Oracles CLI - Help
4
4
 
5
5
  USAGE:
@@ -19,12 +19,12 @@ OPTIONS:
19
19
  --help, -h Show help information
20
20
 
21
21
  For more information, visit: https://github.com/ixoworld/ixo-oracles-cli
22
- `}}};import*as d from"@clack/prompts";import{existsSync as V}from"fs";import T from"path";import Ze from"simple-git";import pe from"fs";import Qe from"path";var Ye=async r=>{let e=await ce({homeServerUrl:w[r.getOrThrow("network")],username:r.getOrThrow("registerUserResult").matrixUserId,password:r.getOrThrow("registerUserResult").matrixPassword,deviceName:r.getOrThrow("registerUserResult").matrixDeviceName}),t=r.getOrThrow("network"),i=r.getOrThrow("projectPath"),n=Qe.join(i,"apps","app",".env");console.log("Creating .env file at:",n),console.log("Project path:",i);let o=Qe.dirname(n);pe.existsSync(o)||(console.log("Creating directory:",o),pe.mkdirSync(o,{recursive:!0}));let s=`
22
+ `}}};import*as d from"@clack/prompts";import{existsSync as V}from"fs";import N from"path";import Ze from"simple-git";import pe from"fs";import Qe from"path";var Ye=async r=>{let e=await ce({homeServerUrl:x[r.getOrThrow("network")],username:r.getOrThrow("registerUserResult").matrixUserId,password:r.getOrThrow("registerUserResult").matrixPassword,deviceName:r.getOrThrow("registerUserResult").matrixDeviceName}),t=r.getOrThrow("network"),i=r.getOrThrow("projectPath"),n=Qe.join(i,"apps","app",".env");console.log("Creating .env file at:",n),console.log("Project path:",i);let o=Qe.dirname(n);pe.existsSync(o)||(console.log("Creating directory:",o),pe.mkdirSync(o,{recursive:!0}));let s=`
23
23
  PORT=4000
24
24
  ORACLE_NAME=${r.getValue("projectName")}
25
25
 
26
26
  # Matrix
27
- MATRIX_BASE_URL=${w[t]}
27
+ MATRIX_BASE_URL=${x[t]}
28
28
  MATRIX_ORACLE_ADMIN_ACCESS_TOKEN=${e.accessToken}
29
29
  MATRIX_ORACLE_ADMIN_PASSWORD=${r.getOrThrow("registerUserResult").matrixPassword}
30
30
  MATRIX_ORACLE_ADMIN_USER_ID=${r.getOrThrow("registerUserResult").matrixUserId}
@@ -48,21 +48,21 @@ ORACLE_DID=${r.getOrThrow("registerUserResult").did}
48
48
  ORACLE_MNEMONIC=${r.getOrThrow("registerUserResult").mnemonic}
49
49
  MATRIX_VAULT_PIN=${r.getOrThrow("registerUserResult").pin}
50
50
  ENTITY_DID=${r.getOrThrow("entityDid")}
51
- `;try{pe.writeFileSync(n,s),console.log("\u2705 .env file created successfully at:",n)}catch(a){throw console.error("\u274C Failed to create .env file:",a),a}};var q=class{constructor(e,t){this.config=e;this.wallet=t}name="init";description="Initialize Project";async getProjectInput(){let e=await d.text({message:"What is your project named?",placeholder:"my-ixo-project",validate(o){if(!o)return"Project name is required"}});d.isCancel(e)&&(d.cancel("Operation cancelled."),process.exit(0));let t=String(e),i,n;return t.includes("/")||t.includes("\\")?(i=t,n=T.basename(t)):(n=t,i=T.join(process.cwd(),n)),this.isValidProjectName(n)||(d.note("Invalid project name. Using a valid name instead.","Warning"),n=this.sanitizeProjectName(n),i=T.join(T.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(V(e)){let o=await d.confirm({message:`Directory "${e}" already exists. Do you want to overwrite it?`,initialValue:!1});return d.isCancel(o)&&(d.cancel("Operation cancelled."),process.exit(0)),o}let n=await d.confirm({message:`Create IXO project "${t}" in "${e}"?`,initialValue:!0});return d.isCancel(n)&&(d.cancel("Operation cancelled."),process.exit(0)),n}async selectRepo(){let e=await d.select({message:"Select a template to clone",options:[{value:"git@github.com:ixoworld/ixo-oracles-boilerplate.git",label:"IXO Oracles (Default)"},{label:"Custom template",value:"custom"}]});if(d.isCancel(e)&&(d.cancel("Operation cancelled."),process.exit(0)),e==="custom"){let t=await d.text({message:"Enter the custom template URL"});return d.isCancel(t)&&(d.cancel("Operation cancelled."),process.exit(0)),t}return e}async cloneRepo(e,t,i=!1){let n=Ze(),o=d.spinner();try{if(o.start("Cloning repository..."),i&&V(t)){let{rmSync:c}=await import("fs");c(t,{recursive:!0,force:!0})}await n.clone(e,t);let s=T.join(t,".git");if(V(s)){let{rmSync:c}=await import("fs");c(s,{recursive:!0,force:!0})}await Ze(t).init(),o.stop("Repository cloned successfully"),d.log.info("Creating Oracle Entity and Matrix Account"),(await new I(this.wallet,this.config).execute()).success?d.log.info("Oracle Entity and Matrix Account created successfully"):d.log.error("Failed to create Oracle Entity and Matrix Account"),await Ye(this.config),d.log.success(`
51
+ `;try{pe.writeFileSync(n,s),console.log("\u2705 .env file created successfully at:",n)}catch(a){throw console.error("\u274C Failed to create .env file:",a),a}};var q=class{constructor(e,t){this.config=e;this.wallet=t}name="init";description="Initialize Project";async getProjectInput(){let e=await d.text({message:"What is your project named?",placeholder:"my-ixo-project",validate(o){if(!o)return"Project name is required"}});d.isCancel(e)&&(d.cancel("Operation cancelled."),process.exit(0));let t=String(e),i,n;return t.includes("/")||t.includes("\\")?(i=t,n=N.basename(t)):(n=t,i=N.join(process.cwd(),n)),this.isValidProjectName(n)||(d.note("Invalid project name. Using a valid name instead.","Warning"),n=this.sanitizeProjectName(n),i=N.join(N.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(V(e)){let o=await d.confirm({message:`Directory "${e}" already exists. Do you want to overwrite it?`,initialValue:!1});return d.isCancel(o)&&(d.cancel("Operation cancelled."),process.exit(0)),o}let n=await d.confirm({message:`Create IXO project "${t}" in "${e}"?`,initialValue:!0});return d.isCancel(n)&&(d.cancel("Operation cancelled."),process.exit(0)),n}async selectRepo(){let e=await d.select({message:"Select a template to clone",options:[{value:"git@github.com:ixoworld/ixo-oracles-boilerplate.git",label:"IXO Oracles (Default)"},{label:"Custom template",value:"custom"}]});if(d.isCancel(e)&&(d.cancel("Operation cancelled."),process.exit(0)),e==="custom"){let t=await d.text({message:"Enter the custom template URL"});return d.isCancel(t)&&(d.cancel("Operation cancelled."),process.exit(0)),t}return e}async cloneRepo(e,t,i=!1){let n=Ze(),o=d.spinner();try{if(o.start("Cloning repository..."),i&&V(t)){let{rmSync:c}=await import("fs");c(t,{recursive:!0,force:!0})}await n.clone(e,t);let s=N.join(t,".git");if(V(s)){let{rmSync:c}=await import("fs");c(s,{recursive:!0,force:!0})}await Ze(t).init(),o.stop("Repository cloned successfully"),d.log.info("Creating Oracle Entity and Matrix Account"),(await new T(this.wallet,this.config).execute()).success?d.log.info("Oracle Entity and Matrix Account created successfully"):d.log.error("Failed to create Oracle Entity and Matrix Account"),await Ye(this.config),d.log.success(`
52
52
  \u2705 IXO project created successfully!
53
53
 
54
54
  \u{1F4C1} Location: ${t}
55
55
  \u{1F680} Next steps:
56
- cd ${T.basename(t)}
56
+ cd ${N.basename(t)}
57
57
  pnpm install
58
58
  pnpm build
59
59
  cd apps/app
60
- 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=V(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 Vt}from"@clack/prompts";var G=class{constructor(e){this.wallet=e}name="logout";description="Logout command";async execute(){return await Vt({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 qt}from"@cosmjs/encoding";import{createRegistry as Gt}from"@ixo/impactxclient-sdk";import{SignX as et,SIGN_X_LOGIN_ERROR as Ht,SIGN_X_LOGIN_SUCCESS as zt,SIGN_X_TRANSACT_ERROR as Jt,SIGN_X_TRANSACT_SUCCESS as Qt}from"@ixo/signx-sdk";import Yt from"qrcode-terminal";var tt={devnet:"https://signx.devnet.ixo.earth",testnet:"https://signx.testnet.ixo.earth",mainnet:"https://signx.ixo.earth"},N=class{signXClient;_loginData;get loginData(){return this._loginData}static loadFromWallet(e){return new et({endpoint:tt[e.network],sitename:"IXO Oracles CLI",network:e.network})}constructor(e){this.signXClient=new et({endpoint:tt[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(`
60
+ 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=V(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 Vt}from"@clack/prompts";var G=class{constructor(e){this.wallet=e}name="logout";description="Logout command";async execute(){return await Vt({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 qt}from"@cosmjs/encoding";import{createRegistry as Gt}from"@ixo/impactxclient-sdk";import{SignX as et,SIGN_X_LOGIN_ERROR as Ht,SIGN_X_LOGIN_SUCCESS as zt,SIGN_X_TRANSACT_ERROR as Jt,SIGN_X_TRANSACT_SUCCESS as Qt}from"@ixo/signx-sdk";import Yt from"qrcode-terminal";var tt={devnet:"https://signx.devnet.ixo.earth",testnet:"https://signx.testnet.ixo.earth",mainnet:"https://signx.ixo.earth"},U=class{signXClient;_loginData;get loginData(){return this._loginData}static loadFromWallet(e){return new et({endpoint:tt[e.network],sitename:"IXO Oracles CLI",network:e.network})}constructor(e){this.signXClient=new et({endpoint:tt[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(`
61
61
  `+" ".repeat(5)+"\u{1F510} "+t),console.log(" ".repeat(5)+"\u{1F4F1} Scan with IXO app"),console.log(" ".repeat(5)+"\u2501".repeat(30)),Yt.generate(i,{small:!0}),console.log(" ".repeat(5)+`\u23F3 Waiting...
62
- `)}displayQRCode(e){this.displayStyledQRCode(e,"Login with SignX")}async awaitLogin(){return new Promise((e,t)=>{try{this.signXClient.on(zt,async i=>{e(i.data)}),this.signXClient.on(Ht,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=Gt();return this.signXClient.transact({address:t.address,did:t.did,pubkey:t.pubKey,timestamp:new Date().toISOString(),transactions:[{sequence:1,txBodyHex:qt(n.encodeTxBody({messages:e,memo:i||""}))}]})}async awaitTransaction(){return new Promise((e,t)=>{try{this.signXClient.on(Qt,i=>{e(i.data)}),this.signXClient.on(Jt,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 H=class{constructor(e,t){this.wallet=e;this.config=t}name="signx-login";description="Login with SignX wallet";async execute(){try{let e=await j(this.config),t=new N(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"}}}};var ge=class extends Error{constructor(t,i="CLI_ERROR",n){super(t);this.code=i;this.suggestions=n;this.name="CLIError"}};function z(r){r instanceof ge&&(console.error(`
62
+ `)}displayQRCode(e){this.displayStyledQRCode(e,"Login with SignX")}async awaitLogin(){return new Promise((e,t)=>{try{this.signXClient.on(zt,async i=>{e(i.data)}),this.signXClient.on(Ht,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=Gt();return this.signXClient.transact({address:t.address,did:t.did,pubkey:t.pubKey,timestamp:new Date().toISOString(),transactions:[{sequence:1,txBodyHex:qt(n.encodeTxBody({messages:e,memo:i||""}))}]})}async awaitTransaction(){return new Promise((e,t)=>{try{this.signXClient.on(Qt,i=>{e(i.data)}),this.signXClient.on(Jt,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 H=class{constructor(e,t){this.wallet=e;this.config=t}name="signx-login";description="Login with SignX wallet";async execute(){try{let e=await j(this.config),t=new U(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"}}}};var ge=class extends Error{constructor(t,i="CLI_ERROR",n){super(t);this.code=i;this.suggestions=n;this.name="CLIError"}};function z(r){r instanceof ge&&(console.error(`
63
63
  \u274C ${r.name}: ${r.message}`),r.suggestions?.length&&(console.error(`
64
64
  Suggestions:`),r.suggestions.forEach(e=>console.error(` \u2022 ${e}`))),process.exit(1)),r instanceof Error&&(console.error(`
65
65
  \u274C Unexpected Error: ${r.message}`),r.stack&&(console.error(`
66
66
  Stack trace:`),console.error(r.stack)),process.exit(1)),console.error(`
67
- \u274C Unknown error occurred`),process.exit(1)}var J=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{cosmos as rt}from"@ixo/impactxclient-sdk";import{existsSync as ue,readFileSync as Zt,writeFileSync as er}from"fs";import{unlink as tr}from"fs/promises";import rr from"os";import ir from"path";var S=ir.join(rr.homedir(),".wallet.json"),Q=class{wallet;signXClient;constructor(){this.loadWallet()}setSignXClient(e){this.signXClient=e}loadWallet(){if(ue(S))try{let e=Zt(S,"utf8");this.wallet=JSON.parse(e),this.setSignXClient(new N(this.wallet.network??"devnet")),console.log("Wallet loaded successfully")}catch(e){console.warn("Failed to load wallet file:",e),this.wallet=void 0}else console.log("No wallet file found")}setWallet(e){try{this.wallet=e;let t=JSON.stringify(e,null,2);er(S,t,"utf8"),console.log("Wallet saved successfully to:",S)}catch(t){throw console.error("Failed to save wallet:",t),new Error("Failed to save wallet file")}}checkWalletExists(){return ue(S)&&this.wallet!==void 0}async clearWallet(){this.wallet=void 0;try{ue(S)&&(await tr(S),console.log("Wallet file deleted successfully"))}catch(e){console.error("Failed to delete wallet file:",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}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:rt.bank.v1beta1.MsgSend.fromPartial({fromAddress:this.address,toAddress:e,amount:[rt.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 he=class{registry;config;wallet;constructor(){this.registry=new _,this.config=J.getInstance(),this.wallet=new Q}registerCommands(){this.registry.register(new q(this.config,this.wallet)),this.registry.register(new I(this.wallet,this.config)),this.registry.register(new G(this.wallet)),this.registry.register(new L(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 L(this.registry).execute();t.success&&t.data&&console.log(t.data)}async handleAuthentication(){if(!this.wallet.checkWalletExists()){let e=await nt({message:"Login with SignX",options:[{value:"login",label:"Login"},{value:"exit",label:"Exit"}]});switch(it(e)&&(fe("Operation cancelled."),A.exit(0)),String(e)){case"login":(await new H(this.wallet,this.config).execute()).success&&W.success("Login successful");break;case"exit":fe("Operation cancelled."),A.exit(0);default:throw new Error(`Unknown command: ${e}`)}}}async executeCommand(e){let t=this.registry.get(e);if(!t)throw new Error(`Unknown command: ${e}`);let i=sr();i.start(`Executing ${t.name}...`);let n=await t.execute();i.stop(`${t.name} completed`),n.success?(W.success(`${t.name} completed successfully!`),n.data&&W.info(JSON.stringify(n.data,null,2))):W.error(`${t.name} failed: ${n.error}`)}async interactiveMode(){nr("IXO CLI"),W.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 nt({message:`Welcome ${this.wallet.name}, what would you like to do?`,options:[...this.registry.getCommandOptions()],initialValue:"init"});it(e)&&(fe("Operation cancelled."),A.exit(0)),await this.executeCommand(String(e))}async argumentMode(e){let t=e[0];if(!t){await this.interactiveMode();return}if(t==="--init"){await this.handleAuthentication(),this.registerCommands(),await this.executeCommand("init");return}if(t==="--help"||t==="-h"){await this.showHelp();return}await this.handleAuthentication(),this.registerCommands(),await this.executeCommand(t)}async run(e){try{let t=e.slice(2);t.length===0?await this.interactiveMode():await this.argumentMode(t)}catch(t){z(t)}or("Thanks for using IXO CLI!"),A.exit(0)}};A.on("uncaughtException",z);A.on("unhandledRejection",z);var ar=new he;ar.run(A.argv);
67
+ \u274C Unknown error occurred`),process.exit(1)}var J=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{cosmos as rt}from"@ixo/impactxclient-sdk";import{existsSync as ue,readFileSync as Zt,writeFileSync as er}from"fs";import{unlink as tr}from"fs/promises";import rr from"os";import ir from"path";var A=ir.join(rr.homedir(),".wallet.json"),Q=class{wallet;signXClient;constructor(){this.loadWallet()}setSignXClient(e){this.signXClient=e}loadWallet(){if(ue(A))try{let e=Zt(A,"utf8");this.wallet=JSON.parse(e),this.setSignXClient(new U(this.wallet.network??"devnet")),console.log("Wallet loaded successfully")}catch(e){console.warn("Failed to load wallet file:",e),this.wallet=void 0}else console.log("No wallet file found")}setWallet(e){try{this.wallet=e;let t=JSON.stringify(e,null,2);er(A,t,"utf8"),console.log("Wallet saved successfully to:",A)}catch(t){throw console.error("Failed to save wallet:",t),new Error("Failed to save wallet file")}}checkWalletExists(){return ue(A)&&this.wallet!==void 0}async clearWallet(){this.wallet=void 0;try{ue(A)&&(await tr(A),console.log("Wallet file deleted successfully"))}catch(e){console.error("Failed to delete wallet file:",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}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:rt.bank.v1beta1.MsgSend.fromPartial({fromAddress:this.address,toAddress:e,amount:[rt.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 he=class{registry;config;wallet;constructor(){this.registry=new _,this.config=J.getInstance(),this.wallet=new Q}registerCommands(){this.registry.register(new q(this.config,this.wallet)),this.registry.register(new T(this.wallet,this.config)),this.registry.register(new G(this.wallet)),this.registry.register(new L(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 L(this.registry).execute();t.success&&t.data&&console.log(t.data)}async handleAuthentication(){if(!this.wallet.checkWalletExists()){let e=await nt({message:"Login with SignX",options:[{value:"login",label:"Login"},{value:"exit",label:"Exit"}]});switch(it(e)&&(fe("Operation cancelled."),b.exit(0)),String(e)){case"login":(await new H(this.wallet,this.config).execute()).success&&W.success("Login successful");break;case"exit":fe("Operation cancelled."),b.exit(0);default:throw new Error(`Unknown command: ${e}`)}}}async executeCommand(e){let t=this.registry.get(e);if(!t)throw new Error(`Unknown command: ${e}`);let i=sr();i.start(`Executing ${t.name}...`);let n=await t.execute();i.stop(`${t.name} completed`),n.success?(W.success(`${t.name} completed successfully!`),n.data&&W.info(JSON.stringify(n.data,null,2))):W.error(`${t.name} failed: ${n.error}`)}async interactiveMode(){nr("IXO CLI"),W.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 nt({message:`Welcome ${this.wallet.name}, what would you like to do?`,options:[...this.registry.getCommandOptions()],initialValue:"init"});it(e)&&(fe("Operation cancelled."),b.exit(0)),await this.executeCommand(String(e))}async argumentMode(e){let t=e[0];if(!t){await this.interactiveMode();return}if(t==="--init"){await this.handleAuthentication(),this.registerCommands(),await this.executeCommand("init");return}if(t==="--help"||t==="-h"){await this.showHelp();return}await this.handleAuthentication(),this.registerCommands(),await this.executeCommand(t)}async run(e){try{let t=e.slice(2);t.length===0?await this.interactiveMode():await this.argumentMode(t)}catch(t){z(t)}or("Thanks for using IXO CLI!"),b.exit(0)}};b.on("uncaughtException",z);b.on("unhandledRejection",z);var ar=new he;ar.run(b.argv);
68
68
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/index.ts","../src/commands/create-entity-command.ts","../src/utils/common.ts","../src/utils/entity.ts","../src/utils/account/simplifiedRegistration.ts","../src/utils/account/matrix.ts","../src/utils/account/secretStorageKeys.ts","../src/utils/account/utils.ts","../src/utils/account/feegrant.ts","../src/utils/matrix/upload-to-matrix.ts","../src/utils/createCIDFromBase64.ts","../src/commands/help.command.ts","../src/commands/init.command.ts","../src/utils/create-project-env-file.ts","../src/commands/logout.commands.ts","../src/utils/signx/signx.ts","../src/commands/signX.commands.ts","../src/utils/errors.ts","../src/utils/runtime-config.ts","../src/utils/wallet.ts"],"sourcesContent":["import { cancel, intro, isCancel, log, outro, select, spinner } from '@clack/prompts';\nimport process from 'node:process';\nimport { CommandRegistry } from './commands';\nimport { CreateEntityCommand } from './commands/create-entity-command';\nimport { HelpCommand } from './commands/help.command';\nimport { InitCommand } from './commands/init.command';\nimport { LogoutCommand } from './commands/logout.commands';\nimport { SignXLoginCommand } from './commands/signX.commands';\nimport { handleError } from './utils/errors';\nimport { RuntimeConfig } from './utils/runtime-config';\nimport { Wallet } from './utils/wallet';\n\nclass CLIManager {\n private registry: CommandRegistry;\n private config: RuntimeConfig;\n private wallet: Wallet;\n\n constructor() {\n this.registry = new CommandRegistry();\n this.config = RuntimeConfig.getInstance();\n this.wallet = new Wallet();\n }\n\n private registerCommands(): void {\n this.registry.register(new InitCommand(this.config, this.wallet));\n this.registry.register(new CreateEntityCommand(this.wallet, this.config));\n this.registry.register(new LogoutCommand(this.wallet));\n this.registry.register(new HelpCommand(this.registry));\n }\n\n private async showHelp(): Promise<void> {\n // add fake wallet to the config\n this.wallet.setWallet({\n address: '0x0000000000000000000000000000000000000000',\n algo: 'secp',\n did: 'did:ixo:entity:1a76366f16570483cea72b111b27fd78',\n network: 'devnet',\n name: 'My oracle',\n pubKey:\n '0x0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',\n ledgered: false,\n matrix: {\n accessToken: '',\n userId: '0x0000000000000000000000000000000000000000',\n address: '',\n roomId: '',\n },\n });\n this.registerCommands();\n const helpCommand = new HelpCommand(this.registry);\n const result = await helpCommand.execute();\n if (result.success && result.data) {\n console.log(result.data);\n }\n }\n\n private async handleAuthentication(): Promise<void> {\n if (!this.wallet.checkWalletExists()) {\n const login = await select({\n message: 'Login with SignX',\n options: [\n { value: 'login', label: 'Login' },\n { value: 'exit', label: 'Exit' },\n ],\n });\n\n if (isCancel(login)) {\n cancel('Operation cancelled.');\n process.exit(0);\n }\n\n switch (String(login)) {\n case 'login':\n const loginCommand = new SignXLoginCommand(this.wallet, this.config);\n const result = await loginCommand.execute();\n if (result.success) {\n log.success('Login successful');\n }\n break;\n case 'exit':\n cancel('Operation cancelled.');\n process.exit(0);\n default:\n throw new Error(`Unknown command: ${login}`);\n }\n }\n }\n\n private async executeCommand(commandName: string): Promise<void> {\n const command = this.registry.get(commandName);\n if (!command) {\n throw new Error(`Unknown command: ${commandName}`);\n }\n\n const s = spinner();\n s.start(`Executing ${command.name}...`);\n\n const result = await command.execute();\n s.stop(`${command.name} completed`);\n\n if (result.success) {\n log.success(`${command.name} completed successfully!`);\n if (result.data) {\n log.info(JSON.stringify(result.data, null, 2));\n }\n } else {\n log.error(`${command.name} failed: ${result.error}`);\n }\n }\n\n private async interactiveMode(): Promise<void> {\n intro('IXO CLI');\n log.warn('Keep your IXO Mobile App open while running the CLI; So u do not interrupt the signX session');\n\n await this.handleAuthentication();\n this.registerCommands();\n\n const action = await select({\n message: `Welcome ${this.wallet.name}, what would you like to do?`,\n options: [...this.registry.getCommandOptions()],\n initialValue: 'init',\n });\n\n if (isCancel(action)) {\n cancel('Operation cancelled.');\n process.exit(0);\n }\n\n await this.executeCommand(String(action));\n }\n\n private async argumentMode(args: string[]): Promise<void> {\n const command = args[0];\n\n if (!command) {\n await this.interactiveMode();\n return;\n }\n\n // Handle special flags\n if (command === '--init') {\n await this.handleAuthentication();\n this.registerCommands();\n await this.executeCommand('init');\n return;\n }\n\n // Handle help\n if (command === '--help' || command === '-h') {\n await this.showHelp();\n return;\n }\n\n // Handle direct command execution\n await this.handleAuthentication();\n this.registerCommands();\n await this.executeCommand(command);\n }\n\n async run(args: string[]): Promise<void> {\n try {\n // Remove the first two args (node path and script path)\n const userArgs = args.slice(2);\n\n if (userArgs.length === 0) {\n await this.interactiveMode();\n } else {\n await this.argumentMode(userArgs);\n }\n } catch (error) {\n handleError(error);\n }\n\n outro('Thanks for using IXO CLI!');\n process.exit(0);\n }\n}\n\n// Handle uncaught errors\nprocess.on('uncaughtException', handleError);\nprocess.on('unhandledRejection', handleError);\n\n// Start the CLI\nconst cli = new CLIManager();\ncli.run(process.argv);\n","import { CLIResult } from '../types';\n\nexport interface Command {\n name: string;\n description: string;\n execute: (...args: any[]) => Promise<CLIResult>;\n}\n\nexport class CommandRegistry {\n private commands: Map<string, Command>;\n\n constructor() {\n this.commands = new Map();\n }\n\n register(command: Command): void {\n this.commands.set(command.name, command);\n }\n\n get(name: string): Command | undefined {\n return this.commands.get(name);\n }\n\n getAll(): Command[] {\n return Array.from(this.commands.values());\n }\n\n getCommandOptions() {\n return this.getAll().map((cmd) => ({\n value: cmd.name,\n label: cmd.name,\n hint: cmd.description,\n }));\n }\n}\n","import * as p from '@clack/prompts';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { Command } from '.';\nimport { CLIResult } from '../types';\nimport { checkRequiredNumber, checkRequiredString, checkRequiredURL, PORTAL_URL, selectNetwork } from '../utils/common';\nimport { CreateEntity } from '../utils/entity';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { Wallet } from '../utils/wallet';\nexport class CreateEntityCommand implements Command {\n name = 'create-entity';\n description = 'Create an entity';\n private readonly createEntity: CreateEntity;\n\n constructor(private wallet: Wallet, private config: RuntimeConfig) {\n this.createEntity = new CreateEntity(this.wallet, this.config);\n }\n\n async execute(): Promise<CLIResult> {\n const network = this.config.getValue('network') as NETWORK;\n if (!network) {\n await selectNetwork(this.config);\n }\n const results = await p.group(\n {\n oracleName: () =>\n p.text({\n message: 'What is the name of the oracle?',\n initialValue: 'My oracle',\n validate(value) {\n return checkRequiredString(value, 'Oracle name is required');\n },\n }),\n oraclePrice: () =>\n p.text({\n message: 'What is the price of the oracle in IXO CREDITS?',\n initialValue: '100',\n validate(value) {\n return checkRequiredNumber(parseInt(value), 'Oracle price is required and must be a number');\n },\n }),\n page: () =>\n p.group({\n title: () =>\n p.text({\n message: 'What is the title of the oracle entity page?',\n initialValue: 'AI Agent Oracle',\n validate(value) {\n return checkRequiredString(value, 'Title is required');\n },\n }),\n content: () =>\n p.text({\n message: 'What is the content of the oracle entity page?',\n initialValue: '### Oracle built to help u with daily tasks',\n validate(value) {\n return checkRequiredString(value, 'Content is required');\n },\n }),\n }),\n profile: () =>\n p.group({\n orgName: () =>\n p.text({\n message: 'What is the name of the organization?',\n initialValue: 'IXO',\n validate(value) {\n return checkRequiredString(value, 'Organization name is required');\n },\n }),\n name: () =>\n p.text({\n message: 'What is the name of the profile?',\n initialValue: 'My oracle',\n validate(value) {\n return checkRequiredString(value, 'Profile name is required');\n },\n }),\n logo: ({ results }) =>\n p.text({\n message: 'What is the logo of the profile?',\n initialValue: `https://api.dicebear.com/8.x/bottts/svg?seed=${results?.name ?? 'IXO'}`,\n defaultValue: `https://api.dicebear.com/8.x/bottts/svg?seed=${results?.name ?? 'IXO'}`,\n validate(value) {\n if (!value) return `https://api.dicebear.com/8.x/bottts/svg?seed=${results?.name ?? 'IXO'}`;\n return checkRequiredURL(value, 'Logo is required or a valid URL');\n },\n }),\n coverImage: ({ results }) =>\n p.text({\n message: 'What is the cover image of the profile?',\n initialValue: results.logo as string,\n defaultValue: results.logo as string,\n validate(value) {\n if (!value) return results.logo as string;\n return checkRequiredURL(value, 'Cover image is required or a valid URL');\n },\n }),\n location: () =>\n p.text({\n message: 'What is the location of your domain?',\n initialValue: 'New York, NY',\n validate(value) {\n return checkRequiredString(value, 'Location is required');\n },\n }),\n description: () =>\n p.text({\n message: 'What is the description of the entity (profile)?',\n initialValue: 'We are a company that helps you with daily tasks',\n validate(value) {\n return checkRequiredString(value, 'Description is required');\n },\n }),\n }),\n parentProtocol: () =>\n p.select({\n message: 'What is the parent protocol of the entity?',\n options: [\n {\n value: 'did:ixo:entity:1a76366f16570483cea72b111b27fd78',\n label: 'IXO Oracle Protocol',\n hint: 'default protocol',\n },\n ],\n initialValue: 'did:ixo:entity:1a76366f16570483cea72b111b27fd78',\n }),\n },\n {\n // On Cancel callback that wraps the group\n // So if the user cancels one of the prompts in the group this function will be called\n onCancel: () => {\n p.cancel('Operation cancelled.');\n process.exit(0);\n },\n }\n );\n\n const did = await this.createEntity.execute({\n oracleConfig: {\n oracleName: results.oracleName,\n price: parseInt(results.oraclePrice),\n },\n page: results.page,\n profile: {\n orgName: results.profile.orgName,\n name: results.profile.name,\n logo: results.profile.logo as string,\n coverImage: results.profile.coverImage as string,\n location: results.profile.location,\n description: results.profile.description,\n },\n services: [\n {\n id: '{id}#api',\n serviceEndpoint: 'http://localhost:4000',\n type: 'oracleService',\n },\n {\n id: '{id}#ws',\n serviceEndpoint: 'http://localhost:4000',\n type: 'wsService',\n },\n ],\n parentProtocol: results.parentProtocol,\n });\n\n p.log.info(`API for the oracle is: http://localhost:4000 | You can change this after you deploy the oracle`);\n\n // add to portal\n const portalBaseUrl = PORTAL_URL[(this.config.getValue('network') as NETWORK) ?? 'devnet'];\n\n const portalUrl = `${portalBaseUrl}/oracle/${did}/overview`;\n\n p.log.info(`Oracle created successfully: ${did}`);\n p.log.info(`Oracle URL: ${portalUrl}`);\n\n return {\n success: true,\n data: `Entity created successfully: ${did}`,\n };\n }\n}\n","import { select } from '@clack/prompts';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { z } from 'zod';\nimport { RuntimeConfig } from './runtime-config';\n\nexport const selectNetwork = async (config: RuntimeConfig) => {\n const network = await select({\n message: 'Select network: (default: devnet)',\n options: [\n { value: 'mainnet', label: 'Mainnet' },\n { value: 'testnet', label: 'Testnet' },\n { value: 'devnet', label: 'Devnet' },\n ],\n initialValue: 'devnet',\n maxItems: 1,\n });\n\n config.addValue('network', network as NETWORK);\n\n return network as NETWORK;\n};\n\nexport const RELAYER_NODE_DID = {\n mainnet: 'did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d',\n testnet: 'did:ixo:entity:3d079ebc0b332aad3305bb4a51c72edb',\n devnet: 'did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d',\n};\n\nexport const MatrixHomeServerUrl: Record<NETWORK, string> = {\n devnet: 'https://devmx.ixo.earth',\n testnet: 'https://testmx.ixo.earth',\n mainnet: 'https://mx.ixo.earth',\n};\n\nexport const MatrixRoomBotServerUrl: Record<NETWORK, string> = {\n devnet: 'https://rooms.bot.devmx.ixo.earth',\n testnet: 'https://rooms.bot.testmx.ixo.earth',\n mainnet: 'https://rooms.bot.mx.ixo.earth',\n};\n\nexport const MatrixBotHomeServerUrl: Record<NETWORK, string> = {\n devnet: 'https://state.bot.devmx.ixo.earth',\n testnet: 'https://state.bot.testmx.ixo.earth',\n mainnet: 'https://state.bot.mx.ixo.earth',\n};\nexport const PORTAL_URL = {\n devnet: 'https://ixo-portal.vercel.app',\n testnet: 'https://ixo-portal.vercel.app',\n mainnet: 'https://ixo-portal.vercel.app',\n};\n\nexport const CHAIN_RPC = {\n mainnet: 'https://impacthub.ixo.world/rpc/',\n testnet: 'https://testnet.ixo.earth/rpc/',\n devnet: 'https://devnet.ixo.earth/rpc/',\n};\n\nexport const checkRequiredString = (value: string, message = 'This field is required') => {\n const schema = z.string().min(1, message);\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n\nexport const checkRequiredURL = (value: string, message = 'This url is required or a valid URL') => {\n const schema = z.url(message);\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n\nexport const checkRequiredNumber = (value: number, message = 'This number is required') => {\n const schema = z.number().min(1, message);\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n","import { isCancel, log, spinner, text } from '@clack/prompts';\nimport { customMessages, ixo, utils } from '@ixo/impactxclient-sdk';\nimport { LinkedResource, Service } from '@ixo/impactxclient-sdk/types/codegen/ixo/iid/v1beta1/types';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { registerUserSimplified } from './account/simplifiedRegistration';\nimport { checkRequiredString, RELAYER_NODE_DID } from './common';\nimport { publicUpload } from './matrix/upload-to-matrix';\nimport { RuntimeConfig } from './runtime-config';\nimport { Wallet } from './wallet';\n\ninterface BlockNoteBlock {\n id: string;\n type: string;\n props: {\n textColor: string;\n backgroundColor: string;\n textAlignment: string;\n level?: number;\n };\n content: Array<{\n type: string;\n text: string;\n styles: Record<string, any>;\n }>;\n children?: any[];\n}\ninterface BlockNotePage {\n title: string;\n blocks: BlockNoteBlock[] | null;\n}\n\ninterface CreateEntityParams {\n profile: {\n orgName: string;\n name: string;\n logo: string;\n coverImage: string;\n location: string;\n description: string;\n };\n page: {\n title: string;\n content: string;\n };\n services: Service[];\n parentProtocol: string;\n oracleConfig: {\n oracleName: string;\n price: number;\n };\n}\n\nexport class CreateEntity {\n private readonly wallet: Wallet;\n constructor(wallet: Wallet, private config: RuntimeConfig) {\n if (!wallet.did || !wallet.pubKey || !wallet.address || !wallet.algo) {\n throw new Error('Wallet not found');\n }\n this.wallet = wallet;\n this.MsgCreateEntityParams.value.verification = [\n ...customMessages.iid.createIidVerificationMethods({\n did: wallet.did,\n pubkey: new Uint8Array(Buffer.from(wallet.pubKey)),\n address: wallet.address,\n controller: wallet.did,\n type: wallet.algo === 'ed25519' ? 'ed' : 'secp',\n }),\n ];\n\n this.MsgCreateEntityParams.value.context = [];\n this.MsgCreateEntityParams.value.controller = [wallet.did];\n this.MsgCreateEntityParams.value.ownerAddress = wallet.address;\n this.MsgCreateEntityParams.value.ownerDid = wallet.did;\n this.MsgCreateEntityParams.value.service.push(\n ixo.iid.v1beta1.Service.fromPartial({\n id: '{id}#matrix',\n type: 'Matrix',\n serviceEndpoint: 'devmx.ixo.earth',\n })\n );\n\n this.MsgCreateEntityParams.value.relayerNode =\n RELAYER_NODE_DID[(this.config.getValue('network') as NETWORK) ?? 'devnet'];\n }\n private MsgCreateEntityParams = {\n typeUrl: '/ixo.entity.v1beta1.MsgCreateEntity',\n value: ixo.entity.v1beta1.MsgCreateEntity.fromPartial({\n entityType: 'oracle',\n context: [],\n entityStatus: 0,\n verification: [],\n controller: [],\n ownerAddress: '',\n ownerDid: '',\n relayerNode: '',\n service: [],\n linkedResource: [],\n accordedRight: [],\n linkedEntity: [],\n linkedClaim: [],\n startDate: utils.proto.toTimestamp(new Date()),\n endDate: utils.proto.toTimestamp(new Date(Date.now() + 100 * 365 * 24 * 60 * 60 * 1000)),\n }),\n };\n\n private async createAuthZConfig({\n oracleAccountAddress,\n oracleName,\n entityDid,\n }: {\n oracleAccountAddress: string;\n oracleName: string;\n entityDid: string;\n }): Promise<LinkedResource> {\n const config = {\n '@context': [\n 'https://schema.org',\n {\n ixo: 'https://w3id.org/ixo/context/v1',\n oracle: {\n '@id': entityDid,\n '@type': '@id',\n },\n },\n ],\n '@type': 'Service',\n '@id': 'oracle:OracleAuthorization',\n name: 'OracleAuthorization',\n description: 'OracleAuthorization',\n serviceType: 'OracleClaimAuthorizationService',\n requiredPermissions: ['/ixo.claims.v1beta1.MsgCreateClaimAuthorization'],\n granteeAddress: oracleAccountAddress,\n granterAddress: '',\n oracleName: oracleName,\n };\n const response = await publicUpload({\n data: config,\n fileName: 'authz',\n config: this.config,\n wallet: this.wallet,\n });\n\n return ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: '{id}#orz',\n type: 'oracleAuthZConfig',\n proof: response.proof,\n right: '',\n encrypted: 'false',\n mediaType: 'application/json',\n description: 'Orale AuthZ Config',\n serviceEndpoint: response.serviceEndpoint,\n });\n }\n\n /**\n * Create Fees Config\n * @param entityDid\n * @param price\n *\n * The fees config is used to set the pricing for the oracle -- this config is fetched by the Frontend and any client to use the pricing for the oracle and grant max amount permissions\n */\n private async createFeesConfig({ entityDid, price }: { entityDid: string; price: number }): Promise<LinkedResource> {\n const config = {\n '@context': [\n 'https://schema.org',\n {\n ixo: 'https://w3id.org/ixo/context/v1',\n oracle: {\n '@id': entityDid,\n '@type': '@id',\n },\n },\n ],\n '@type': 'Service',\n '@id': 'oracle:ServiceFeeModel',\n name: 'Pricing',\n description: 'Pricing',\n serviceType: '',\n offers: {\n '@type': 'Offer',\n priceCurrency: 'uixo',\n priceSpecification: {\n '@type': 'PaymentChargeSpecification',\n priceCurrency: 'uixo',\n price: price,\n unitCode: 'MON',\n billingIncrement: 1,\n billingPeriod: 'P1M',\n priceType: 'Subscription',\n maxPrice: price,\n },\n eligibleQuantity: {\n '@type': 'QuantitativeValue',\n value: 1,\n unitCode: 'MON',\n },\n },\n };\n const response = await publicUpload({\n data: config,\n fileName: 'fees',\n config: this.config,\n wallet: this.wallet,\n });\n return ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: '{id}#fee',\n type: 'pricingList',\n proof: response.proof,\n right: '',\n encrypted: 'false',\n mediaType: 'application/json',\n description: 'Pricing List',\n serviceEndpoint: response.serviceEndpoint,\n });\n }\n\n /**\n * Create Oracle Config Files\n * @param oracleAccountAddress\n * @param oracleName\n * @param entityDid\n * @param price\n *\n * Using this after the entity is created to upload the config files to the entity using it's did\n * this will do entity update to add the config files to the entity\n */\n private async createOracleConfigFiles({\n oracleName,\n entityDid,\n price,\n oracleAccountAddress,\n }: CreateEntityParams['oracleConfig'] & { entityDid: string; oracleAccountAddress: string }) {\n const walletAddress = this.wallet.wallet?.address;\n\n if (!this.wallet.signXClient || !this.wallet.wallet || !walletAddress) {\n throw new Error('SignX client or wallet not found');\n }\n\n const resources = await Promise.all([\n this.createAuthZConfig({\n oracleName,\n entityDid,\n oracleAccountAddress,\n }),\n this.createFeesConfig({\n entityDid,\n price,\n }),\n ]);\n const linkedResourcesMsgs = resources.map((resource) => ({\n typeUrl: '/ixo.iid.v1beta1.MsgAddLinkedResource',\n value: ixo.iid.v1beta1.MsgAddLinkedResource.fromPartial({\n id: entityDid,\n linkedResource: ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: resource.id,\n description: resource.description,\n type: resource.type,\n proof: resource.proof,\n mediaType: resource.mediaType,\n encrypted: resource.encrypted,\n serviceEndpoint: resource.serviceEndpoint,\n }),\n signer: walletAddress,\n }),\n }));\n\n // sign and send the msgs\n log.info('Sign to edit the entity and add the config files');\n const tx = await this.wallet.signXClient.transact(linkedResourcesMsgs, this.wallet.wallet);\n this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(tx));\n await this.wallet.signXClient.pollNextTransaction();\n const response = await this.wallet.signXClient.awaitTransaction();\n return response;\n }\n\n private async addPage({ content, title }: CreateEntityParams['page']) {\n const blockNotePage: BlockNotePage = {\n title,\n blocks: [\n {\n id: 'title-block',\n type: 'heading',\n props: { textColor: 'default', backgroundColor: 'default', textAlignment: 'left' },\n content: [{ type: 'text', text: title, styles: {} }],\n },\n {\n id: 'content-block',\n type: 'paragraph',\n props: {\n textColor: 'default',\n backgroundColor: 'default',\n textAlignment: 'left',\n },\n content: [{ type: 'text', text: content, styles: {} }],\n },\n ],\n };\n\n const response = await publicUpload({\n data: blockNotePage,\n fileName: 'page',\n config: this.config,\n wallet: this.wallet,\n });\n\n const pageResource = {\n id: '{id}#pag',\n type: 'Settings',\n description: 'Page',\n mediaType: 'application/json',\n serviceEndpoint: response.serviceEndpoint,\n proof: response.proof,\n encrypted: 'false',\n right: '',\n };\n this.MsgCreateEntityParams.value.linkedResource.push(ixo.iid.v1beta1.LinkedResource.fromPartial(pageResource));\n }\n\n private async addProfile({ orgName, name, logo, coverImage, location, description }: CreateEntityParams['profile']) {\n const profileData = {\n '@context': {\n ixo: 'https://w3id.org/ixo/ns/protocol/',\n '@id': '@type',\n type: '@type',\n '@protected': false,\n },\n id: 'ixo:entity#profile',\n type: 'profile',\n orgName,\n name,\n image: coverImage,\n logo,\n brand: orgName,\n location,\n description,\n };\n\n const response = await publicUpload({\n data: profileData,\n fileName: 'profile',\n config: this.config,\n wallet: this.wallet,\n });\n\n const profileResource = {\n id: '{id}#pro',\n type: 'Settings',\n description: 'Profile',\n mediaType: 'application/json',\n serviceEndpoint: response.serviceEndpoint,\n proof: response.proof,\n encrypted: 'false',\n right: '',\n };\n this.MsgCreateEntityParams.value.linkedResource.push(ixo.iid.v1beta1.LinkedResource.fromPartial(profileResource));\n }\n\n private async addServices(services: Service[]) {\n this.MsgCreateEntityParams.value.service.push(\n ...services.map((service) => ixo.iid.v1beta1.Service.fromPartial(service))\n );\n }\n\n private async setParentProtocol(parentProtocol: string) {\n this.MsgCreateEntityParams.value.context.push(\n ...customMessages.iid.createAgentIidContext([{ key: 'class', val: parentProtocol }])\n );\n }\n\n public returnExecutableMsg() {\n return this.MsgCreateEntityParams;\n }\n\n public async execute(params: CreateEntityParams): Promise<string> {\n log.info('Adding page');\n await this.addPage(params.page);\n log.info('Adding profile');\n await this.addProfile(params.profile);\n log.info('Adding services');\n await this.addServices(params.services);\n log.info('Adding parent protocol');\n await this.setParentProtocol(params.parentProtocol);\n\n const msg = this.returnExecutableMsg();\n if (!this.wallet.signXClient || !this.wallet.wallet) {\n throw new Error('SignX client not found');\n }\n log.info('Sign this transaction to create the entity');\n const tx = await this.wallet.signXClient.transact([msg], this.wallet.wallet);\n this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(tx));\n await this.wallet.signXClient.pollNextTransaction();\n\n // Wait for transaction completion\n const response = await this.wallet.signXClient.awaitTransaction();\n log.success('Entity created -- wait to attach the required config files');\n\n log.info('Creating Oracle Wallet and Matrix Account');\n const pin = await text({\n message: 'Enter a PIN to secure your Matrix Vault:',\n initialValue: '',\n defaultValue: '',\n validate(value) {\n return checkRequiredString(value, 'PIN is required');\n },\n });\n if (isCancel(pin)) {\n log.error('User cancelled');\n process.exit(1);\n }\n const registerResult = await registerUserSimplified(\n {\n pin,\n oracleName: params.oracleConfig.oracleName,\n network: this.config.getValue('network') as NETWORK,\n oracleAvatarUrl: params.profile.logo,\n },\n async (address) => {\n await this.wallet.sendTokens(address, 250_000); // 250,000 uixo = 0.25 IXO;\n }\n );\n\n // upload resources\n const did = utils.common.getValueFromEvents(response as any, 'wasm', 'token_id');\n await this.createOracleConfigFiles({\n oracleName: params.oracleConfig.oracleName,\n price: params.oracleConfig.price,\n oracleAccountAddress: registerResult.address,\n entityDid: did,\n });\n log.success('Entity created -- config files attached');\n const s = spinner();\n s.start('Creating Entity Matrix Room...');\n s.stop('Room created -- room joined');\n log.warn('Please save the following information in a secure location as it is not stored:');\n log.info(`ORACLE ACCOUNT DETAILS`);\n log.info(`Oracle DID: ${registerResult.did}`);\n log.info(`Oracle Account Address: ${registerResult.address}`);\n log.info(`Oracle Account Mnemonic: ${registerResult.mnemonic}`);\n log.info(`Matrix User ID: ${registerResult.matrixUserId}`);\n log.info(`Matrix Password: ${registerResult.matrixPassword}`);\n this.config.addValue('registerUserResult', registerResult);\n this.config.addValue('entityDid', did);\n return did;\n }\n}\n","import { utils } from '@ixo/impactxclient-sdk';\nimport { createMatrixApiClient } from '@ixo/matrixclient-sdk';\n\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { MatrixHomeServerUrl, MatrixRoomBotServerUrl } from '../common';\nimport {\n checkIsUsernameAvailable,\n createMatrixClient,\n generatePassphraseFromMnemonic,\n generatePasswordFromMnemonic,\n generateUsernameFromAddress,\n generateUserRoomAliasFromAddress,\n hasCrossSigningAccountData,\n logoutMatrixClient,\n mxRegisterWithSecp,\n setupCrossSigning,\n} from './matrix';\nimport { checkIidDocumentExists, createIidDocument, delay, encrypt, getSecpClient } from './utils';\n\nexport interface SimplifiedRegistrationResult {\n address: string;\n did: string;\n mnemonic: string;\n matrixUserId: string;\n matrixRoomId: string;\n matrixMnemonic: string;\n matrixPassword: string;\n matrixAccessToken: string;\n matrixRecoveryPhrase: string;\n pin: string;\n matrixDeviceName: string;\n}\n\nconst DEVICE_NAME = 'Oracles CLI';\n/**\n * Simplified user registration flow without email verification or passkey authentication\n * Includes: wallet creation, DID creation, Matrix account with secp auth, Matrix room setup, encrypted mnemonic storage\n * @param pin - User PIN for encrypting Matrix mnemonic\n * @returns Registration result with wallet and Matrix account details\n */\nexport async function registerUserSimplified(\n {\n pin,\n oracleName,\n network,\n oracleAvatarUrl,\n }: {\n pin: string;\n oracleName: string;\n network: NETWORK;\n oracleAvatarUrl: string;\n },\n transferTokens: (address: string) => Promise<void>\n): Promise<SimplifiedRegistrationResult> {\n try {\n // =================================================================================================\n // 1. CREATE WALLET\n // =================================================================================================\n const mnemonic = utils.mnemonic.generateMnemonic();\n const wallet = await getSecpClient(mnemonic);\n const address = wallet.baseAccount.address;\n console.log('✅ Wallet created:', address);\n\n // transfer tokens\n await transferTokens(address);\n\n // =================================================================================================\n // 2. DID CREATION\n // =================================================================================================\n const did = utils.did.generateSecpDid(address);\n const didExists = await checkIidDocumentExists(did, network);\n console.log('✅ DID exists:', didExists);\n if (!didExists) {\n console.log('✅ DID does not exist, creating...');\n await createIidDocument(did, network, wallet);\n console.log('✅ DID created, waiting 500ms...');\n await delay(500);\n console.log('✅ Checking if DID exists...');\n const didExistsAfterCreation = await checkIidDocumentExists(did, network);\n if (!didExistsAfterCreation) {\n throw new Error('Failed to create DID document');\n }\n }\n console.log('✅ DID created:', did);\n\n // =================================================================================================\n // 3. MATRIX ACCOUNT CREATION\n // =================================================================================================\n const mxMnemonic = utils.mnemonic.generateMnemonic(12);\n const homeServerUrl = MatrixHomeServerUrl[network];\n const mxUsername = generateUsernameFromAddress(address);\n const mxPassword = generatePasswordFromMnemonic(mxMnemonic);\n const mxPassphrase = generatePassphraseFromMnemonic(mxMnemonic);\n\n // Check if username is available\n const isUsernameAvailable = await checkIsUsernameAvailable({\n homeServerUrl: homeServerUrl,\n username: mxUsername,\n });\n if (!isUsernameAvailable) {\n throw new Error('Matrix account already exists');\n }\n\n // Clear any residual matrix data\n // await logoutMatrixClient({ baseUrl: homeServerUrl, accessToken: '', userId: '', deviceId: '' });\n\n // Register using secp256k1 signature (not passkey)\n const account = await mxRegisterWithSecp(address, mxPassword, DEVICE_NAME, wallet, network);\n if (!account?.accessToken) {\n throw new Error('Failed to register matrix account');\n }\n console.log('✅ Matrix account created:', account.userId);\n\n // =================================================================================================\n // 4. MATRIX CLIENT SETUP\n // =================================================================================================\n const mxClient = await createMatrixClient({\n homeServerUrl,\n accessToken: account.accessToken,\n userId: account.userId,\n deviceId: account.deviceId,\n });\n\n try {\n await Promise.all([mxClient.setDisplayName(oracleName), mxClient.setAvatarUrl(oracleAvatarUrl)]);\n } catch (error) {\n console.error('Failed to set display name or avatar url:', error);\n }\n\n const matrixApiClient = createMatrixApiClient({\n homeServerUrl: homeServerUrl,\n accessToken: account.accessToken,\n });\n\n // Setup cross signing\n let hasCrossSigning = hasCrossSigningAccountData(mxClient);\n if (!hasCrossSigning) {\n hasCrossSigning = await setupCrossSigning(mxClient, {\n securityPhrase: mxPassphrase,\n password: mxPassword,\n forceReset: true,\n });\n if (!hasCrossSigning) {\n throw new Error('Failed to setup cross signing');\n }\n }\n console.log('✅ Matrix cross-signing setup completed');\n\n // =================================================================================================\n // 5. MATRIX ROOM CREATION/JOIN\n // =================================================================================================\n const mxRoomAlias = generateUserRoomAliasFromAddress(address, account.baseUrl);\n const queryIdResponse = await matrixApiClient.room.v1beta1.queryId(mxRoomAlias).catch(() => undefined);\n let roomId: string = queryIdResponse?.room_id ?? '';\n\n if (!roomId) {\n // Create room via bot\n const response = await fetch(`${MatrixRoomBotServerUrl[network]}/room/source`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n did: did,\n userMatrixId: account.userId,\n }),\n });\n if (!response.ok) {\n throw new Error('Failed to create matrix room');\n }\n const data = (await response.json()) as { roomId: string };\n roomId = data.roomId;\n if (!roomId) {\n throw new Error('Failed to create user matrix room');\n }\n }\n\n // Ensure room is joined\n let joinedMembers = await matrixApiClient.room.v1beta1.listJoinedMembers(roomId).catch(() => undefined);\n let joined = !!joinedMembers?.joined?.[account.userId];\n if (!joined) {\n const joinResponse = await matrixApiClient.room.v1beta1.join(roomId);\n if (!joinResponse.room_id) {\n throw new Error('Failed to join matrix room');\n }\n joinedMembers = await matrixApiClient.room.v1beta1.listJoinedMembers(roomId);\n joined = !!joinedMembers?.joined?.[account.userId];\n if (!joined) {\n throw new Error('Failed to join matrix room');\n }\n }\n console.log('✅ Matrix room created/joined:', roomId);\n\n // =================================================================================================\n // 6. ENCRYPT AND STORE MATRIX MNEMONIC\n // =================================================================================================\n const encryptedMnemonic = encrypt(mxMnemonic, pin);\n const storeEncryptedMnemonicResponse = await fetch(\n `${homeServerUrl}/_matrix/client/r0/rooms/${roomId}/state/ixo.room.state.secure/encrypted_mnemonic`,\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${account.accessToken as string}`,\n },\n body: JSON.stringify({\n encrypted_mnemonic: encryptedMnemonic,\n }),\n }\n );\n if (!storeEncryptedMnemonicResponse.ok) {\n throw new Error('Failed to store encrypted mnemonic in matrix room');\n }\n await storeEncryptedMnemonicResponse.json();\n console.log('✅ Encrypted Matrix mnemonic stored in room');\n\n // =================================================================================================\n // 7. LOGOUT MATRIX CLIENT\n // =================================================================================================\n await logoutMatrixClient({\n mxClient,\n baseUrl: homeServerUrl,\n accessToken: account.accessToken,\n userId: account.userId,\n deviceId: account.deviceId,\n });\n\n // =================================================================================================\n // 7. RETURN REGISTRATION RESULT\n // =================================================================================================\n return {\n address: address,\n did: did,\n mnemonic: mnemonic, // Wallet mnemonic - store securely!\n matrixUserId: account.userId,\n matrixRoomId: roomId,\n matrixMnemonic: mxMnemonic, // Matrix mnemonic - also store securely!\n matrixPassword: mxPassword,\n matrixAccessToken: account.accessToken,\n matrixRecoveryPhrase: mxMnemonic,\n pin: pin,\n matrixDeviceName: DEVICE_NAME,\n };\n } catch (error) {\n console.error('Simplified registration failed:', error);\n throw error;\n }\n}\n","import { sha256 } from '@cosmjs/crypto';\nimport { encrypt as eciesEncrypt } from 'eciesjs';\nimport { ClientEvent, createClient, MatrixClient } from 'matrix-js-sdk';\nimport { CryptoApi } from 'matrix-js-sdk/lib/crypto-api';\nimport md5 from 'md5';\n\n// import cons from '@constants/matrix';\n// import { isAuthenticated, secret } from '@utils/secrets';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { MatrixHomeServerUrl, MatrixRoomBotServerUrl } from '../common';\nimport { cacheSecretStorageKey, clearSecretStorageKeys, getSecretStorageKey } from './secretStorageKeys';\nimport { delay } from './utils';\n\nconst WELL_KNOWN_URI = '/.well-known/matrix/client';\n\n// =================================================================================================\n// AUTH\n// =================================================================================================\ninterface AuthResponse {\n accessToken: string;\n deviceId: string;\n userId: string;\n baseUrl: string;\n}\nexport const mxLogin = async (\n {\n homeServerUrl,\n username,\n password,\n deviceName,\n }: { homeServerUrl: string; username: string; password: string; deviceName: string },\n localMatrix = false\n) => {\n let mxHomeServerUrl = homeServerUrl;\n let mxUsername = username;\n const mxIdMatch = mxUsername.match(/^@(.+):(.+\\..+)$/);\n if (mxIdMatch) {\n mxUsername = mxIdMatch[1] as string;\n mxHomeServerUrl = mxIdMatch[2] as string;\n mxHomeServerUrl = localMatrix ? mxHomeServerUrl : await getBaseUrl(mxHomeServerUrl);\n }\n\n try {\n const client = createTemporaryClient(mxHomeServerUrl);\n const response = await client.login('m.login.password', {\n identifier: {\n type: 'm.id.user',\n user: normalizeUsername(mxUsername),\n },\n password,\n initial_device_display_name: deviceName,\n });\n const data: AuthResponse = {\n accessToken: response.access_token,\n deviceId: response.device_id,\n userId: response.user_id,\n baseUrl: localMatrix ? mxHomeServerUrl : response?.well_known?.['m.homeserver']?.base_url || client.baseUrl,\n };\n return data;\n } catch (error) {\n let msg = (error as any).message;\n if (msg === 'Unknown message') {\n msg = 'Please check your credentials';\n }\n console.error(`mxLogin::`, msg);\n throw new Error(msg);\n }\n};\n\n// =================================================================================================\n// NEW API-BASED REGISTRATION\n// =================================================================================================\n\ninterface PublicKeyResponse {\n publicKey: string;\n fingerprint: string;\n algorithm: string;\n usage: string;\n}\n\ninterface UserCreationChallenge {\n timestamp: string;\n address: string;\n service: string;\n type: string;\n}\n\ninterface UserCreationRequest {\n address: string;\n encryptedPassword: string;\n publicKeyFingerprint: string;\n authnResult?: any;\n secpResult?: {\n signature: string;\n challenge: string;\n };\n}\n\ninterface UserCreationResponse {\n success: boolean;\n matrixUserId: string;\n address: string;\n message: string;\n}\n\n/**\n * Fetch the public key for password encryption from the user creation API\n * @returns Public key information for encryption\n */\nexport async function getPublicKeyForEncryption(network: NETWORK): Promise<PublicKeyResponse> {\n const response = await fetch(`${MatrixRoomBotServerUrl[network]}/public-key`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error('Failed to fetch public key for encryption');\n }\n\n const data = (await response.json()) as PublicKeyResponse;\n return data;\n}\n\n/**\n * Create a structured challenge for user creation\n * @param address The user's address (without did:ixo: prefix)\n * @returns The challenge object and its base64 representation\n */\nexport function createUserCreationChallenge(address: string): {\n challenge: UserCreationChallenge;\n challengeBase64: string;\n} {\n const challenge: UserCreationChallenge = {\n timestamp: new Date().toISOString(),\n address: address,\n service: 'matrix',\n type: 'create-account',\n };\n\n const challengeBase64 = Buffer.from(JSON.stringify(challenge)).toString('base64');\n\n return { challenge, challengeBase64 };\n}\n\n/**\n * Encrypt password using ECIES with the provided public key\n * @param password The password to encrypt\n * @param publicKey The public key in hex format\n * @returns The encrypted password in hex format\n */\nexport function encryptPasswordWithECIES(password: string, publicKey: string): string {\n const publicKeyBytes = new Uint8Array(Buffer.from(publicKey, 'hex'));\n const passwordBytes = new Uint8Array(Buffer.from(password, 'utf8'));\n const encryptedPassword = eciesEncrypt(publicKeyBytes, passwordBytes);\n return Array.from(encryptedPassword, (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * Create user account using WebAuthn/Passkey authentication\n * @param address The user's address\n * @param password The matrix password\n * @param authnResult The WebAuthn assertion result\n * @returns The user creation response\n */\nexport async function createUserAccountWithPasskey(\n address: string,\n password: string,\n authnResult: any,\n network: NETWORK\n): Promise<UserCreationResponse> {\n const publicKeyInfo = await getPublicKeyForEncryption(network);\n const encryptedPassword = encryptPasswordWithECIES(password, publicKeyInfo.publicKey);\n\n const request: UserCreationRequest = {\n address,\n encryptedPassword,\n publicKeyFingerprint: publicKeyInfo.fingerprint,\n authnResult,\n };\n\n const response = await fetch(`${MatrixRoomBotServerUrl[network]}/user/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const errorData = (await response.json()) as { error: string };\n throw new Error(errorData.error || 'Failed to create user account');\n }\n\n return (await response.json()) as UserCreationResponse;\n}\n\n/**\n * Create user account using secp256k1 signature authentication\n * @param address The user's address\n * @param password The matrix password\n * @param signature The secp256k1 signature (base64)\n * @param challenge The challenge that was signed (base64)\n * @returns The user creation response\n */\nexport async function createUserAccountWithSecp(\n address: string,\n password: string,\n signature: string,\n challenge: string,\n network: NETWORK\n): Promise<UserCreationResponse> {\n const publicKeyInfo = await getPublicKeyForEncryption(network);\n const encryptedPassword = encryptPasswordWithECIES(password, publicKeyInfo.publicKey);\n\n const request: UserCreationRequest = {\n address,\n encryptedPassword,\n publicKeyFingerprint: publicKeyInfo.fingerprint,\n secpResult: {\n signature,\n challenge,\n },\n };\n\n const response = await fetch(`${MatrixRoomBotServerUrl[network]}/user/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const errorData = (await response.json()) as { error: string };\n throw new Error(errorData.error || 'Failed to create user account');\n }\n\n return (await response.json()) as UserCreationResponse;\n}\n\n// =================================================================================================\n// UPDATED REGISTRATION FUNCTIONS\n// =================================================================================================\n\n/**\n * Register matrix account using the new API with WebAuthn/Passkey authentication\n * @param address The user's address\n * @param password The matrix password\n * @param authnResult The WebAuthn assertion result\n * @returns AuthResponse with access token and user details\n */\nexport async function mxRegisterWithPasskey(\n address: string,\n password: string,\n authnResult: any,\n deviceName: string,\n network: NETWORK\n): Promise<AuthResponse> {\n try {\n const userCreationResult = await createUserAccountWithPasskey(address, password, authnResult, network);\n\n if (!userCreationResult.success) {\n throw new Error('Failed to create matrix account via API');\n }\n\n // Now login to get the access token\n const homeServerUrl = MatrixHomeServerUrl[network];\n const username = generateUsernameFromAddress(address);\n\n const loginResult = await mxLogin({\n homeServerUrl,\n username,\n password,\n deviceName,\n });\n\n return loginResult;\n } catch (error) {\n console.error('mxRegisterWithPasskey error:', error);\n throw error;\n }\n}\n\n/**\n * Register matrix account using the new API with secp256k1 signature authentication\n * @param address The user's address\n * @param password The matrix password\n * @param wallet The secp wallet for signing\n * @returns AuthResponse with access token and user details\n */\nexport async function mxRegisterWithSecp(\n address: string,\n password: string,\n deviceName: string,\n wallet: { sign: (message: string) => Promise<Uint8Array> },\n network: NETWORK\n): Promise<AuthResponse> {\n try {\n // Create challenge and sign it\n const { challengeBase64 } = createUserCreationChallenge(address);\n const signatureBytes = await wallet.sign(challengeBase64);\n const signature = Buffer.from(signatureBytes).toString('base64');\n\n const userCreationResult = await createUserAccountWithSecp(address, password, signature, challengeBase64, network);\n\n if (!userCreationResult.success) {\n throw new Error('Failed to create matrix account via API');\n }\n\n // Now login to get the access token\n const homeServerUrl = MatrixHomeServerUrl[network];\n const username = generateUsernameFromAddress(address);\n\n const loginResult = await mxLogin({\n homeServerUrl,\n username,\n password,\n deviceName,\n });\n\n return loginResult;\n } catch (error) {\n console.error('mxRegisterWithSecp error:', error);\n throw error;\n }\n}\n\n// =================================================================================================\n// UPDATED LEGACY REGISTRATION (DEPRECATED)\n// =================================================================================================\n\n// Keep the old functions for backward compatibility but mark as deprecated\nasync function getRegisterFlow(homeServerUrl: string) {\n try {\n const client = createTemporaryClient(homeServerUrl);\n // @ts-ignore\n const [registerResponse] = await Promise.allSettled([client.register()]);\n const registerFlow = registerResponse.status === 'rejected' ? registerResponse?.reason?.data : undefined;\n console.log('registerFlow', registerFlow);\n if (registerFlow === undefined) {\n throw new Error('Failed to setup home server config.');\n }\n return registerFlow;\n } catch (error) {\n if ((error as any).data) {\n console.log('registerFlow', (error as any).data);\n return (error as any).data;\n }\n throw new Error('Failed to get matrix register flow.');\n }\n}\n\nexport async function loginOrRegisterMatrixAccount({\n homeServerUrl,\n username,\n password,\n wallet,\n accessToken,\n deviceName,\n network,\n}: {\n homeServerUrl: string;\n username: string;\n password: string;\n accessToken?: string;\n wallet?: { sign: (message: string) => Promise<Uint8Array>; baseAccount: { address: string } };\n deviceName: string;\n network: NETWORK;\n}) {\n const isAuthenticated = !!accessToken;\n let isUsernameAvailable = await checkIsUsernameAvailable({ homeServerUrl, username });\n let res: AuthResponse | undefined;\n if (isUsernameAvailable && wallet) {\n // Use new API-based registration with secp256k1 authentication\n res = await mxRegisterWithSecp(wallet.baseAccount.address, password, deviceName, wallet, network);\n if (!res?.accessToken) {\n throw new Error('Failed to register matrix account');\n }\n console.log('mxRegisterWithSecp', res);\n }\n if (!isAuthenticated) {\n res = await mxLogin({\n homeServerUrl,\n username,\n password,\n deviceName,\n });\n if (!res?.accessToken) {\n throw new Error('Failed to login to matrix account');\n }\n console.log('mxLogin', res);\n }\n return res;\n}\n\nexport async function checkIsUsernameAvailable({\n homeServerUrl,\n username,\n}: {\n homeServerUrl: string;\n username: string;\n}) {\n const client = createTemporaryClient(homeServerUrl);\n try {\n const isUsernameAvailable = await client.isUsernameAvailable(username);\n return !!isUsernameAvailable;\n } catch (error) {\n return false;\n }\n}\n\n// =================================================================================================\n// CLIENT\n// =================================================================================================\n/**\n * Creates a temporary matrix client, used for matrix login or registration to get access tokens\n * @param homeServerUrl - the home server url to instantiate the matrix client\n * @returns matrix client\n */\nexport function createTemporaryClient(homeServerUrl: string) {\n if (!homeServerUrl) {\n throw new Error('Home server URL is required to instantiate matrix client');\n }\n return createClient({\n baseUrl: homeServerUrl,\n });\n}\n\nexport async function createMatrixClient({\n homeServerUrl,\n accessToken,\n userId,\n deviceId,\n}: {\n homeServerUrl: string;\n accessToken: string;\n userId: string;\n deviceId: string;\n}) {\n console.log('createMatrixClient::', { homeServerUrl, accessToken, userId, deviceId });\n\n if (!homeServerUrl || !accessToken || !userId || !deviceId) {\n throw new Error('Login to Matrix account before trying to instantiate Matrix client.');\n }\n\n // const indexedDBStore = new IndexedDBStore({\n // indexedDB: global.indexedDB,\n // dbName: 'matrix-sync-store',\n // });\n // const legacyCryptoStore = new IndexedDBCryptoStore()\n\n const mxClient = createClient({\n baseUrl: homeServerUrl,\n accessToken,\n userId,\n // store: indexedDBStore,\n // cryptoStore: legacyCryptoStore,\n deviceId,\n timelineSupport: true,\n cryptoCallbacks: {\n getSecretStorageKey: getSecretStorageKey,\n cacheSecretStorageKey: cacheSecretStorageKey,\n },\n verificationMethods: ['m.sas.v1'],\n });\n // await indexedDBStore.startup();\n await mxClient.initRustCrypto({\n useIndexedDB: false,\n });\n // mxClient.setGlobalErrorOnUnknownDevices(false);\n mxClient.setMaxListeners(20);\n // const filter = new Filter(userId);\n // filter.setDefinition({\n // room: {\n // state: {\n // lazy_load_members: true,\n // types: [],\n // },\n // timeline: {\n // types: [],\n // },\n // },\n // // Disable unnecessary features\n // presence: {\n // types: [], // No presence updates needed\n // },\n // account_data: {\n // types: ['m.cross_signing.master'], // No account data needed\n // },\n // });\n await mxClient.startClient({\n lazyLoadMembers: true,\n // initialSyncLimit: 1,\n includeArchivedRooms: false,\n // pollTimeout: 2 * 60 * 1000, // poll every 2 minutes\n // filter: filter,\n });\n await new Promise<void>((resolve, reject) => {\n const sync = {\n NULL: () => {\n console.info('[NULL] state');\n },\n SYNCING: () => {\n void 0;\n },\n PREPARED: () => {\n console.info(`[PREPARED] state: user ${userId}`);\n resolve();\n },\n RECONNECTING: () => {\n console.info('[RECONNECTING] state');\n },\n CATCHUP: () => {\n console.info('[CATCHUP] state');\n },\n ERROR: () => {\n reject(new Error('[ERROR] state: starting matrix client'));\n },\n STOPPED: () => {\n console.info('[STOPPED] state');\n },\n };\n mxClient.on(ClientEvent.Sync, (state) => {\n sync[state]();\n });\n });\n return mxClient;\n}\n\nexport async function logoutMatrixClient({\n mxClient,\n baseUrl,\n accessToken,\n userId,\n deviceId,\n}: {\n mxClient?: MatrixClient;\n baseUrl: string;\n accessToken: string;\n userId: string;\n deviceId: string;\n}) {\n let client = mxClient;\n if (!client) {\n client = createClient({\n baseUrl: baseUrl,\n accessToken,\n userId,\n deviceId,\n });\n }\n if (client) {\n client.stopClient();\n await client.logout().catch(console.error);\n client.clearStores();\n }\n}\n\n// =================================================================================================\n// CROSS SIGNING\n// =================================================================================================\n/**\n * Check if the user has cross-signing account data.\n * @param {MatrixClient} mxClient - The matrix client to check.\n * @returns {boolean} True if the user has cross-signing account data, otherwise false.\n */\nexport function hasCrossSigningAccountData(mxClient: MatrixClient): boolean {\n const masterKeyData = mxClient.getAccountData('m.cross_signing.master');\n console.log('hasCrossSigningAccountData::masterKeyData', masterKeyData);\n return !!masterKeyData;\n}\n\n/**\n * Setup cross signing and secret storage for the current user\n * @param {MatrixClient} mxClient - The matrix client to setup cross signing for\n * @param {string} securityPhrase - the security phrase to use for secret storage\n * @param {string} password - the password for the matrix account\n * @param {boolean} forceReset - if to force reset the cross signing keys (NB, only do if you know what you are doing!!!)\n * @param {boolean} skipBootstrapSS - if to skip bootstrapping secret storage\n * @returns {boolean} True if the cross signing was setup successfully, otherwise false.\n */\nexport async function setupCrossSigning(\n mxClient: MatrixClient,\n {\n securityPhrase,\n password,\n forceReset = false,\n skipBootstrapSecureStorage = false,\n }: { securityPhrase: string; password: string; forceReset?: boolean; skipBootstrapSecureStorage?: boolean }\n): Promise<boolean> {\n if (forceReset) {\n clearSecretStorageKeys();\n }\n\n const mxCrypto = mxClient.getCrypto() as CryptoApi;\n if (!mxCrypto) {\n throw new Error('Failed to setup matrix cross signing - failed to get matrix crypto api');\n }\n if (!skipBootstrapSecureStorage) {\n const recoveryKey = await mxCrypto.createRecoveryKeyFromPassphrase(securityPhrase);\n clearSecretStorageKeys();\n await mxCrypto.bootstrapSecretStorage({\n createSecretStorageKey: async () => recoveryKey!,\n setupNewSecretStorage: forceReset,\n });\n }\n const userId = mxClient.getUserId()!;\n await mxCrypto.bootstrapCrossSigning({\n authUploadDeviceSigningKeys: async function (makeRequest) {\n await makeRequest(getAuthId({ userId, password }));\n },\n setupNewCrossSigning: forceReset,\n });\n await mxCrypto.resetKeyBackup();\n\n await delay(300);\n\n return !!mxClient.getAccountData('m.cross_signing.master');\n}\n\n// =================================================================================================\n// GENERAL\n// =================================================================================================\n/**\n * Generates a username from an address, used for matrix login, generated an account did\n * @param {string} address - the address to generate the username from\n * @returns {string} username\n */\nexport function generateUsernameFromAddress(address: string): string {\n if (!address) {\n throw new Error('Address is required to generate matrix username');\n }\n return 'did-ixo-' + address;\n}\n\n/**\n * Generates a password from a mnemonic, used for matrix login, generated using the first 24 bytes of the base64 encoded md5 hash of the mnemonic\n * @param {string} mnemonic - the mnemonic to generate the password from\n * @returns {string} password\n */\nexport function generatePasswordFromMnemonic(mnemonic: string): string {\n const base64 = Buffer.from(md5(mnemonic.replace(/ /g, ''))).toString('base64');\n return base64.slice(0, 24);\n}\n\n/**\n * Generates a recovery phrase from a mnemonic, used for matrix recovery, generated using the first 32 bytes of the base64 encoded sha256 hash of the mnemonic\n * @param {string} mnemonic - the mnemonic to generate the recovery phrase from\n * @returns {string} recoveryPhrase\n */\nexport function generateRecoveryPhraseFromMnemonic(mnemonic: string): string {\n const hash = sha256(new TextEncoder().encode(mnemonic.replace(/ /g, '')));\n const base64 = Buffer.from(hash).toString('base64');\n return base64.slice(0, 32);\n}\n\n/**\n * Extracts the home server URL from a user ID.\n * @param {string} userId - The user ID to extract the homeserver URL from.\n * @returns {string} The homeserver URL.\n */\nexport function extractHomeServerUrlFromUserId(userId: string): string {\n const parts = userId.split(':');\n if (parts.length < 2) {\n throw new Error('Invalid userId');\n }\n return parts.slice(1).join(':');\n}\n\n/**\n * Generates a recovery phrase from a mnemonic, used for matrix recovery, generated using the first 32 bytes of the base64 encoded sha256 hash of the mnemonic\n * @param {string} mnemonic - the mnemonic to generate the recovery phrase from\n * @returns {string} passphrase\n */\nexport function generatePassphraseFromMnemonic(mnemonic: string): string {\n const hash = sha256(new TextEncoder().encode(mnemonic.replace(/ /g, '')));\n const base64 = Buffer.from(hash).toString('base64');\n return base64.slice(0, 32);\n}\n\n/**\n * Cleans a home server URL by removing protocol and trailing slashes\n * @param {string} homeServer - the homeserver URL to clean\n * @returns {string} cleaned homeserver URL\n */\nexport function cleanMatrixHomeServerUrl(homeServer: string): string {\n return homeServer.replace(/^(https?:\\/\\/)/, '').replace(/\\/$/, '');\n}\n\n/**\n * Generates a room name from an account address, used for matrix user room where user can manage their own data\n * @param {string} address - the address of the user\n * @param {string} postpend - the postpend of the room name (for testing)\n * @returns {string} roomName\n */\nexport function generateUserRoomNameFromAddress(address: string, postpend = ''): string {\n return 'did-ixo-' + address + postpend;\n}\n\n/**\n * Generates a room alias from an account address, used for matrix user room where user can manage their own data\n * @param {string} address - the address of the user\n * @param {string} postpend - the postpend of the room alias (for testing)\n * @returns {string} roomAlias\n */\nexport function generateUserRoomAliasFromAddress(address: string, homeServerUrl: string): string {\n return '#' + generateUserRoomNameFromAddress(address) + ':' + cleanMatrixHomeServerUrl(homeServerUrl);\n}\n\n/**\n * Get the base URL for a given servername.\n * @param servername The servername to get the base URL for.\n * @returns The base URL for the servername.\n */\nexport async function getBaseUrl(servername: string): Promise<string> {\n let protocol = 'https://';\n if (/^https?:\\/\\//.test(servername)) {\n protocol = '';\n }\n const serverDiscoveryUrl = `${protocol}${servername}${WELL_KNOWN_URI}`;\n try {\n const response = await fetch(serverDiscoveryUrl, { method: 'GET' });\n const result = await response.json();\n const baseUrl = (result as { 'm.homeserver': { base_url: string } })['m.homeserver']?.base_url;\n if (baseUrl === undefined) {\n throw new Error();\n }\n return baseUrl;\n } catch (e) {\n return `${protocol}${servername}`;\n }\n}\n\n/**\n * Normalize a username by removing leading '@' and trimming whitespace.\n * @param {string} rawUsername - The raw username to normalize.\n * @returns {string} The normalized username.\n */\nexport function normalizeUsername(rawUsername: string): string {\n const noLeadingAt = rawUsername.indexOf('@') === 0 ? rawUsername.substring(1) : rawUsername;\n return noLeadingAt.trim();\n}\n\n/**\n * Generates the authentication identifier for matrix login\n * @param {string} password - the password for the matrix account\n * @returns {object} authId - the authentication identifier\n */\nexport function getAuthId({ userId, password }: { userId: string; password: string }): {\n type: string;\n password: string;\n identifier: { type: string; user: string };\n} {\n return {\n type: 'm.login.password',\n password,\n identifier: {\n type: 'm.id.user',\n user: userId,\n },\n };\n}\n","const secretStorageKeys = new Map();\n\nexport function storePrivateKey(keyId: string, privateKey: Uint8Array) {\n if (privateKey instanceof Uint8Array === false) {\n throw new Error('Unable to store, privateKey is invalid.');\n }\n\n secretStorageKeys.set(keyId, privateKey);\n}\n\nexport function hasPrivateKey(keyId: string) {\n return secretStorageKeys.get(keyId) instanceof Uint8Array;\n}\n\nexport function getPrivateKey(keyId: string) {\n return secretStorageKeys.get(keyId);\n}\n\nexport function deletePrivateKey(keyId: string) {\n secretStorageKeys.delete(keyId);\n}\n\nexport function clearSecretStorageKeys() {\n secretStorageKeys.clear();\n}\n\nexport async function getSecretStorageKey({ keys }: { keys: any }): Promise<[string, Uint8Array] | null> {\n const keyIds = Object.keys(keys);\n const keyId = keyIds.find(hasPrivateKey);\n console.info('[] getSecretStorageKey', keys, keyIds, keyId);\n\n if (!keyId) {\n return null;\n }\n\n const privateKey = getPrivateKey(keyId);\n\n return [keyId, privateKey];\n}\n\nexport function cacheSecretStorageKey(keyId: string, keyInfo: any, privateKey: Uint8Array) {\n secretStorageKeys.set(keyId, privateKey);\n}\n","import { Bip39, EnglishMnemonic, Secp256k1, sha256, Slip10, Slip10Curve, stringToPath } from '@cosmjs/crypto';\nimport { AccountData, DirectSecp256k1HdWallet, OfflineSigner } from '@cosmjs/proto-signing';\nimport { createQueryClient, createSigningClient, customMessages, ixo, utils } from '@ixo/impactxclient-sdk';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { createCipheriv, randomBytes } from 'crypto';\nimport { CHAIN_RPC } from '../common';\nimport { decodeGrants, isAllowanceExpired, isAllowanceLimitReached } from './feegrant';\n/**\n * Checks if an iid document (did) exists\n * @param did - The did to check for\n * @returns True if the iid document exists, false otherwise\n */\nexport async function checkIidDocumentExists(did: string, network: NETWORK) {\n if (!network) {\n throw new Error('Network parameter is required but was undefined');\n }\n\n console.log(`🔍 Checking IID document for DID: ${did} on network: ${network}`);\n\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}. Valid networks are: ${Object.keys(CHAIN_RPC).join(', ')}`);\n }\n\n console.log(`🔗 Using RPC URL: ${url}`);\n\n try {\n const queryClient = await createQueryClient(url);\n const iidDocumentResponse = await queryClient.ixo.iid.v1beta1.iidDocument({ id: did });\n if (!iidDocumentResponse?.iidDocument?.id) {\n return false;\n }\n return true;\n } catch (error) {\n if ((error as Error).message?.includes('did document not found') || (error as Error).message?.includes('(22)')) {\n return false;\n }\n console.error('Error checking IID document:', error);\n throw error;\n }\n}\n\n/**\n * Creates an iid document (did)\n * Must be signed by base account mnemonic (not passkey signer)\n * @param did - The did to create iid document for\n * @param offlineSigner - The offline signer to use to create iid document\n */\nexport async function createIidDocument(did: string, network: NETWORK, offlineSigner: OfflineSigner) {\n try {\n const accounts = await offlineSigner.getAccounts();\n const { address, pubkey } = (accounts[0] ?? {}) as AccountData;\n const allowances = await queryAddressAllowances(address, network);\n const feegrantGranter = allowances?.length\n ? decodeGrants(allowances)?.find(\n (allowance) =>\n !!allowance &&\n !isAllowanceExpired(allowance.expiration as number) &&\n !isAllowanceLimitReached(allowance.limit)\n )?.granter\n : undefined;\n const trx = {\n typeUrl: '/ixo.iid.v1beta1.MsgCreateIidDocument',\n value: ixo.iid.v1beta1.MsgCreateIidDocument.fromPartial({\n id: did,\n verifications: customMessages.iid.createIidVerificationMethods({\n did: did,\n pubkey: pubkey,\n address: address,\n controller: did,\n type: 'secp',\n }),\n signer: address,\n controllers: [did],\n }),\n };\n // if (!feegrantGranter) {\n // throw new Error('No feegrant granter found');\n // }\n await signAndBroadcastWithMnemonic({\n offlineSigner: offlineSigner,\n messages: [trx],\n feegrantGranter: feegrantGranter as string,\n network,\n });\n } catch (error) {\n console.error(error);\n throw error;\n }\n}\n\nexport async function queryAddressAllowances(address: string, network: NETWORK) {\n try {\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}`);\n }\n const queryClient = await createQueryClient(url);\n const allowancesResponse = await queryClient.cosmos.feegrant.v1beta1.allowances({\n grantee: address,\n });\n return allowancesResponse?.allowances ?? [];\n } catch (error) {\n console.error('queryAddressAllowances::', (error as Error).message);\n return undefined;\n }\n}\n\n/**\n * Signs and broadcasts a transaction with a mnemonic\n * @param offlineSigner - The offline signer\n * @param messages - The messages to sign and broadcast\n * @param memo - The memo for the transaction\n * @param feegrantGranter - The granter for the transaction\n * @returns The deliver tx response\n */\nexport const signAndBroadcastWithMnemonic = async ({\n offlineSigner,\n messages,\n memo = 'Signing with Mnemonic Demo',\n feegrantGranter,\n network,\n}: {\n offlineSigner: OfflineSigner;\n messages: any[];\n memo?: string;\n feegrantGranter: string;\n network: NETWORK;\n}) => {\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}`);\n }\n const signingClient = await createSigningClient(url, offlineSigner);\n const accounts = await offlineSigner.getAccounts();\n const { address } = (accounts[0] ?? {}) as AccountData;\n\n const simGas = await signingClient.simulate(address, messages, memo);\n const gasUsed = simGas > 50000 ? simGas : (messages ?? []).length * 500000;\n const gas = gasUsed * 1.7;\n const gasOptions = calculateTrxGasOptions(gas);\n const fee = {\n amount: [\n {\n denom: 'uixo',\n amount: String(Math.round(gasOptions.average)),\n },\n ],\n gas: String(Math.round(gas)),\n granter: feegrantGranter,\n };\n const result = await signingClient.signAndBroadcast(address, messages, fee, memo, undefined);\n const isDeliverTxFailure = !!result.code;\n if (isDeliverTxFailure) {\n throw new Error(\n `Error when broadcasting tx ${result.transactionHash} at height ${result.height}. Code: ${result.code}; Raw log: ${result.rawLog}`\n );\n }\n};\n\nconst calculateTrxGasOptions = (gasUsed: number) => {\n const gasPriceStep = {\n low: 0.02,\n average: 0.035,\n high: 0.045,\n };\n const gas = gasUsed < 0.01 ? 0.01 : gasUsed;\n const gasOptions = {\n low: gas * gasPriceStep.low,\n average: gas * gasPriceStep.average,\n high: gas * gasPriceStep.high,\n };\n\n return gasOptions;\n};\n\nexport const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport function encrypt(text: string, password: string) {\n const iv = randomBytes(16);\n\n const cipher = createCipheriv('aes-256-cbc', Buffer.from(password.padEnd(32)), iv);\n let encrypted = cipher.update(text);\n encrypted = Buffer.concat([encrypted, cipher.final()]);\n return iv.toString('hex') + ':' + encrypted.toString('hex');\n}\n\nexport type SecpClient = Awaited<ReturnType<typeof getSecpClient>>;\nexport const getSecpClient = async (mnemonic: string) => {\n const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {\n prefix: 'ixo',\n });\n const account = (await wallet.getAccounts())[0];\n\n // Debug: Derive and verify keys manually for comparison\n const seed = await Bip39.mnemonicToSeed(new EnglishMnemonic(mnemonic));\n const hdPath = stringToPath(\"m/44'/118'/0'/0/0\");\n const slip10Result = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath);\n const privkey = slip10Result.privkey;\n // Derive the compressed public key from the private key\n const keypair = await Secp256k1.makeKeypair(privkey);\n const compressedPubkey = Secp256k1.compressPubkey(keypair.pubkey);\n // Log keys and addresses for comparison\n // console.log({\n // walletPubkey: account!.pubkey ? Buffer.from(account!.pubkey).toString('hex') : 'not available',\n // derivedPubkey: Buffer.from(compressedPubkey).toString('hex'),\n // });\n\n const secpClient = {\n mnemonic,\n did: utils.did.generateSecpDid(account!.address),\n baseAccount: account!,\n\n async getAccounts() {\n return (await wallet.getAccounts()) as AccountData[];\n },\n\n async signDirect(signerAddress: any, signDoc: any) {\n return await wallet.signDirect(signerAddress, signDoc);\n },\n\n /**\n * Sign a message with the secp256k1 private key derived from the mnemonic\n * @param message - The message to sign (usually a challenge string - base64 encoded)\n * @returns The signature as a Uint8Array\n */\n async sign(message: string): Promise<Uint8Array> {\n // Use the wallet's signDirect method to ensure consistent signing\n try {\n // Derive keypair from mnemonic directly\n const seed = await Bip39.mnemonicToSeed(new EnglishMnemonic(mnemonic));\n\n // NOTE: need to do checking here if it produces matched address to signed in one, maybe user is using a different derivation path\n // Use the standard Cosmos HD path (m/44'/118'/0'/0/0)\n const hdPath = stringToPath(\"m/44'/118'/0'/0/0\");\n\n // Derive the private key using SLIP-10\n const { privkey } = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath);\n\n // For the challenge (base64 encoded string), decode to get the original bytes\n const challengeBytes = new Uint8Array(Buffer.from(message, 'base64'));\n\n // Hash the challenge bytes using SHA-256\n const messageHash = sha256(challengeBytes);\n\n // Sign the hash with the derived private key\n const signature = await Secp256k1.createSignature(messageHash, privkey);\n\n // Get the fixed-length signature, which is r (32 bytes) | s (32 bytes) | recovery param (1 byte)\n const fixedLengthSignature = signature.toFixedLength();\n\n // Remove the recovery parameter byte (last byte) to get only r and s\n // This gives us exactly 64 bytes which is what the verification expects\n return fixedLengthSignature.slice(0, 64);\n } catch (error) {\n console.error('Error during signature creation:', error);\n throw error;\n }\n },\n };\n\n return secpClient;\n};\n","import { Coin, DecodeObject } from '@cosmjs/proto-signing';\nimport { createQueryClient, createRegistry, utils } from '@ixo/impactxclient-sdk';\nimport { Grant } from '@ixo/impactxclient-sdk/types/codegen/cosmos/feegrant/v1beta1/feegrant';\nimport { Timestamp } from '@ixo/impactxclient-sdk/types/codegen/google/protobuf/timestamp';\n\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { CHAIN_RPC } from '../common';\n\n/**\n * Converts a timestamp object to a timestamp\n * @param timestamp - The timestamp object to convert\n * @returns The timestamp\n */\nexport function convertTimestampObjectToTimestamp(timestamp: Timestamp): number | undefined {\n try {\n const date = utils.proto.fromTimestamp(timestamp);\n\n return date.getTime();\n } catch (error) {\n return undefined;\n }\n}\n\nexport enum FeegrantTypes {\n BASIC_ALLOWANCE = 'BasicAllowance',\n PERIODIC_ALLOWANCE = 'PeriodicAllowance',\n}\n\nexport const FEEGRANT_TYPES: Record<FeegrantTypes, string> = {\n BasicAllowance: '/cosmos.feegrant.v1beta1.BasicAllowance',\n PeriodicAllowance: '/cosmos.feegrant.v1beta1.PeriodicAllowance',\n};\n\n/**\n * Queries the address allowances from the IXO blockchain\n * @param address - The address to query allowances for\n * @returns The allowances for the address\n */\nexport async function queryAddressAllowances(address: string, network: NETWORK) {\n try {\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}`);\n }\n const queryClient = await createQueryClient(url);\n const allowancesResponse = await queryClient.cosmos.feegrant.v1beta1.allowances({\n grantee: address,\n });\n return allowancesResponse?.allowances ?? [];\n } catch (error) {\n console.error('queryAddressAllowances::', (error as Error).message);\n return undefined;\n }\n}\n\n/**\n * Checks if the address has a valid feegrant (not expired yet and limit not reached yet)\n * @param address - The address to check feegrant for\n * @returns True if the address has a valid feegrant, false otherwise\n */\nexport async function checkAddressFeegrant(address: string, network: NETWORK) {\n try {\n const allowancesResponse = await queryAddressAllowances(address, network);\n console.log('allowancesResponse', allowancesResponse);\n if (!allowancesResponse?.length) {\n return false;\n }\n const allowances = decodeGrants(allowancesResponse);\n return allowances.some(\n (allowance) =>\n !!allowance && !isAllowanceExpired(allowance.expiration as number) && !isAllowanceLimitReached(allowance.limit)\n );\n } catch (error) {\n console.error('checkAddressFeegrant::', (error as Error).message);\n throw error;\n }\n}\n\n/**\n * Decodes the grant values from the the user's list of allowances\n * @param grants - The grants to decode\n * @returns The decoded grants\n */\nexport const decodeGrants = (grants: Grant[]) => {\n const registry = createRegistry();\n\n return (grants ?? []).map((grant) => {\n const allowance = grant.allowance as DecodeObject;\n const decodedAllowance = registry.decode(allowance);\n // decodedAllowance.\n switch (allowance.typeUrl) {\n case FEEGRANT_TYPES.BasicAllowance:\n return {\n granter: grant.granter,\n grantee: grant.grantee,\n type: FEEGRANT_TYPES.BasicAllowance,\n expiration: decodedAllowance.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.expiration)\n : null,\n limit: decodedAllowance.spendLimit?.length\n ? decodedAllowance.spendLimit.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : null,\n msgs: [],\n };\n case FEEGRANT_TYPES.PeriodicAllowance:\n return {\n granter: grant.granter,\n grantee: grant.grantee,\n type: FEEGRANT_TYPES.PeriodicAllowance,\n expiration: decodedAllowance.basic?.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.basic.expiration)\n : null,\n limit: decodedAllowance?.periodCanSpend\n ? decodedAllowance?.periodCanSpend?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : decodedAllowance?.basic?.spendLimit?.length\n ? decodedAllowance?.basic?.spendLimit?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : null,\n msgs: [],\n };\n default:\n return {\n type: allowance.typeUrl,\n granter: grant.granter,\n grantee: grant.grantee,\n expiration: decodedAllowance.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.expiration)\n : decodedAllowance.basic?.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.basic.expiration)\n : null,\n limit: decodedAllowance.spendLimit?.length\n ? decodedAllowance.spendLimit.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : decodedAllowance?.periodCanSpend\n ? decodedAllowance?.periodCanSpend?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : decodedAllowance?.basic?.spendLimit?.length\n ? decodedAllowance?.basic?.spendLimit?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : null,\n msgs: decodedAllowance.allowedMessages,\n };\n }\n });\n};\n\n/**\n * Checks if the allowance has expired\n * @param expiration - The expiration of the allowance\n * @returns True if the allowance has expired, false otherwise\n */\nexport const isAllowanceExpired = (expiration: number | Timestamp) => {\n if (expiration === null || expiration === undefined) {\n return false;\n }\n const expirationTimestamp =\n typeof expiration === 'object' ? convertTimestampObjectToTimestamp(expiration) : expiration;\n if (expirationTimestamp === undefined || expirationTimestamp === null) {\n // failed to decode or convert - assume expired\n return true;\n }\n return expirationTimestamp < Date.now();\n};\n\n/**\n * Checks if the allowance limit has been reached\n * @param limit - The limit of the allowance\n * @returns True if the allowance limit has been reached, false otherwise\n */\nexport const isAllowanceLimitReached = (limit: number | string | Coin) => {\n if (limit === null || limit === undefined) {\n return false;\n }\n const limitAmount =\n typeof limit === 'object' ? Number(limit?.amount ?? 0) : typeof limit === 'string' ? Number(limit ?? 0) : limit;\n return limitAmount <= 0.0005;\n};\n","import { createMatrixApiClient, utils as mxUtils } from '@ixo/matrixclient-sdk';\nimport { UploadContentType } from '@ixo/matrixclient-sdk/types/api/media/v1beta1';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { MatrixHomeServerUrl } from '../common';\nimport { createCIDFromBase64, jsonToBase64 } from '../createCIDFromBase64';\nimport { RuntimeConfig } from '../runtime-config';\nimport { Wallet } from '../wallet';\n\nexport const publicUpload = async ({\n data,\n fileName,\n config,\n wallet,\n}: {\n data: object;\n fileName: string;\n config: RuntimeConfig;\n wallet: Wallet;\n}) => {\n const matrixAPIClient = createMatrixApiClient({\n homeServerUrl: MatrixHomeServerUrl[(config.getValue('network') as NETWORK) ?? 'devnet'],\n accessToken: wallet?.matrix?.accessToken ?? '',\n });\n\n const file = new File([JSON.stringify(data)], fileName + '.json', {\n type: 'application/ld+json',\n });\n\n const response = await matrixAPIClient.media.v1beta1.upload(file.name, file.type as UploadContentType, file);\n const httpUrl = mxUtils.mxc.mxcUrlToHttp(\n MatrixHomeServerUrl[(config.getValue('network') as NETWORK) ?? 'devnet'], // homeServerUrl\n response.content_uri // the mxc url\n );\n\n if (!httpUrl) {\n throw new Error('Failed to upload file to Matrix');\n }\n\n const jsonString = JSON.stringify(data);\n const base64String = jsonToBase64(jsonString);\n const cid = await createCIDFromBase64(base64String);\n\n return {\n encrypted: 'false',\n cid,\n proof: cid,\n serviceEndpoint: httpUrl,\n mxc: response.content_uri,\n };\n};\n","import { CID } from 'multiformats';\nimport { base64 } from 'multiformats/bases/base64';\nimport * as mfsha2 from 'multiformats/hashes/sha2';\n\nexport async function createCIDFromBase64(base64String: string): Promise<string> {\n // Add 'm' prefix if not present\n const multibaseString = base64String.startsWith('m') ? base64String : 'm' + base64String;\n\n // Decode base64 to bytes\n const bytes = base64.decode(multibaseString);\n\n // Create SHA-256 hash of the bytes\n const hash = await mfsha2.sha256.digest(bytes);\n\n // Create CID (using SHA-256 and RAW codec)\n const cid = CID.create(1, 0x55, hash);\n\n return cid.toString();\n}\n\nexport function jsonToBase64(jsonString: string): string {\n const uint8Array = new TextEncoder().encode(jsonString);\n return btoa(String.fromCharCode(...Array.from(uint8Array)));\n}\n","import { CLIResult } from '../types';\nimport { Command, CommandRegistry } from './index';\n\nexport class HelpCommand implements Command {\n name = 'help';\n description = 'Show help information and available commands';\n\n constructor(private registry: CommandRegistry) {}\n\n async execute(): Promise<CLIResult> {\n const commands = this.registry.getAll();\n\n const helpText = `\nIXO Oracles CLI - Help\n\nUSAGE:\n oracles-cli [command] [options]\n\nCOMMANDS:\n${commands.map((cmd) => ` ${cmd.name.padEnd(15)} ${cmd.description}`).join('\\n')}\n\nEXAMPLES:\n oracles-cli --init Initialize a new IXO Oracle project\n oracles-cli Launch interactive menu\n oracles-cli help Show this help message\n\nOPTIONS:\n --init Initialize a new project (shortcut)\n --help, -h Show help information\n\nFor more information, visit: https://github.com/ixoworld/ixo-oracles-cli\n`;\n\n return {\n success: true,\n data: helpText,\n };\n }\n}\n","import * as p from '@clack/prompts';\nimport { existsSync } from 'fs';\nimport path from 'path';\nimport simpleGit from 'simple-git';\nimport { Command } from '.';\nimport { CLIResult } from '../types';\nimport { createProjectEnvFile } from '../utils/create-project-env-file';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { Wallet } from '../utils/wallet';\nimport { CreateEntityCommand } from './create-entity-command';\n\nexport class InitCommand implements Command {\n name = 'init';\n description = 'Initialize Project';\n\n constructor(private readonly config: RuntimeConfig, private readonly wallet: Wallet) {}\n\n private async getProjectInput(): Promise<{ projectPath: string; projectName: string }> {\n // Get the input from user (could be path, name, or both)\n const input = await p.text({\n message: 'What is your project named?',\n placeholder: 'my-ixo-project',\n validate(value) {\n if (!value) {\n return 'Project name is required';\n }\n return undefined;\n },\n });\n\n if (p.isCancel(input)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n // Parse the input to determine if it's a path, name, or both\n const inputStr = String(input);\n let projectPath: string;\n let projectName: string;\n\n // Check if input contains path separators (is a path)\n if (inputStr.includes('/') || inputStr.includes('\\\\')) {\n // Input is a path\n projectPath = inputStr;\n projectName = path.basename(inputStr);\n } else {\n // Input is just a name, create in current directory\n projectName = inputStr;\n projectPath = path.join(process.cwd(), projectName);\n }\n\n // Ensure the project name is valid\n if (!this.isValidProjectName(projectName)) {\n p.note('Invalid project name. Using a valid name instead.', 'Warning');\n projectName = this.sanitizeProjectName(projectName);\n projectPath = path.join(path.dirname(projectPath), projectName);\n }\n\n return { projectPath, projectName };\n }\n\n private isValidProjectName(name: string): boolean {\n // Check if name is valid (no special characters, starts with letter, etc.)\n const validNameRegex = /^[a-zA-Z][a-zA-Z0-9-_]*$/;\n return validNameRegex.test(name) && name.length > 0 && name.length <= 50;\n }\n\n private sanitizeProjectName(name: string): string {\n // Convert invalid characters to valid ones\n return name\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n .replace(/^-+|-+$/g, '') // Remove leading/trailing dashes\n .toLowerCase()\n .substring(0, 50);\n }\n\n private async confirmProjectCreation(projectPath: string, projectName: string): Promise<boolean> {\n const isDirExists = existsSync(projectPath);\n\n if (isDirExists) {\n const overwrite = await p.confirm({\n message: `Directory \"${projectPath}\" already exists. Do you want to overwrite it?`,\n initialValue: false,\n });\n\n if (p.isCancel(overwrite)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n return overwrite;\n }\n\n // Show confirmation for new project\n const confirm = await p.confirm({\n message: `Create IXO project \"${projectName}\" in \"${projectPath}\"?`,\n initialValue: true,\n });\n\n if (p.isCancel(confirm)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n return confirm;\n }\n\n private async selectRepo() {\n const repo = await p.select({\n message: 'Select a template to clone',\n options: [\n {\n value: 'git@github.com:ixoworld/ixo-oracles-boilerplate.git',\n label: 'IXO Oracles (Default)',\n },\n {\n label: 'Custom template',\n value: 'custom',\n },\n ],\n });\n\n if (p.isCancel(repo)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n if (repo === 'custom') {\n const customRepo = await p.text({\n message: 'Enter the custom template URL',\n });\n\n if (p.isCancel(customRepo)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n return customRepo;\n }\n\n return repo;\n }\n\n private async cloneRepo(repo: string, projectPath: string, shouldOverwrite: boolean = false) {\n const git = simpleGit();\n const cloneSpinner = p.spinner();\n\n try {\n cloneSpinner.start('Cloning repository...');\n\n // If overwriting, remove the existing directory first\n if (shouldOverwrite && existsSync(projectPath)) {\n const { rmSync } = await import('fs');\n rmSync(projectPath, { recursive: true, force: true });\n }\n\n // Create directory if it doesn't exist\n\n await git.clone(repo, projectPath);\n\n // Clean repo and create new git\n const gitFolder = path.join(projectPath, '.git');\n if (existsSync(gitFolder)) {\n const { rmSync } = await import('fs');\n rmSync(gitFolder, { recursive: true, force: true });\n }\n await simpleGit(projectPath).init();\n\n cloneSpinner.stop('Repository cloned successfully');\n\n p.log.info('Creating Oracle Entity and Matrix Account');\n const command = new CreateEntityCommand(this.wallet, this.config);\n const result = await command.execute();\n if (result.success) {\n p.log.info('Oracle Entity and Matrix Account created successfully');\n } else {\n p.log.error('Failed to create Oracle Entity and Matrix Account');\n }\n\n await createProjectEnvFile(this.config);\n // Show success message with next steps\n p.log.success(\n `\\n✅ IXO project created successfully!\\n\\n` +\n `📁 Location: ${projectPath}\\n` +\n `🚀 Next steps:\\n` +\n ` cd ${path.basename(projectPath)}\\n` +\n ` pnpm install\\n` +\n ` pnpm build \\n` +\n ` cd apps/app\\n` +\n ` pnpm start:dev`\n );\n } catch (error) {\n cloneSpinner.stop('Failed to clone repository');\n throw error;\n }\n }\n\n async execute(): Promise<CLIResult> {\n try {\n // Get project input (path and/or name)\n const { projectPath, projectName } = await this.getProjectInput();\n\n // Confirm project creation\n const shouldProceed = await this.confirmProjectCreation(projectPath, projectName);\n\n if (!shouldProceed) {\n return { success: false, data: 'Project creation cancelled' };\n }\n\n // Store in config\n this.config.addValue('projectPath', projectPath);\n this.config.addValue('projectName', projectName);\n\n // Select repository template\n const repo = await this.selectRepo();\n this.config.addValue('repo', repo);\n\n // Check if we need to overwrite\n const shouldOverwrite = existsSync(projectPath);\n\n // Clone the repository\n await this.cloneRepo(repo, projectPath, shouldOverwrite);\n\n return {\n success: true,\n data: `Project \"${projectName}\" created successfully in \"${projectPath}\"`,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error occurred',\n };\n }\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { mxLogin } from './account/matrix';\nimport { MatrixHomeServerUrl } from './common';\nimport { RuntimeConfig } from './runtime-config';\nexport const createProjectEnvFile = async (config: RuntimeConfig) => {\n const freshMx = await mxLogin({\n homeServerUrl: MatrixHomeServerUrl[config.getOrThrow('network')],\n username: config.getOrThrow('registerUserResult').matrixUserId,\n password: config.getOrThrow('registerUserResult').matrixPassword,\n deviceName: config.getOrThrow('registerUserResult').matrixDeviceName,\n });\n const network = config.getOrThrow('network');\n const projectPath = config.getOrThrow('projectPath');\n const envFile = path.join(projectPath, 'apps', 'app', '.env');\n\n console.log('Creating .env file at:', envFile);\n console.log('Project path:', projectPath);\n\n // Ensure the directory exists\n const envDir = path.dirname(envFile);\n if (!fs.existsSync(envDir)) {\n console.log('Creating directory:', envDir);\n fs.mkdirSync(envDir, { recursive: true });\n }\n const envContent = `\nPORT=4000 \nORACLE_NAME=${config.getValue('projectName')}\n\n# Matrix\nMATRIX_BASE_URL=${MatrixHomeServerUrl[network]}\nMATRIX_ORACLE_ADMIN_ACCESS_TOKEN=${freshMx.accessToken}\nMATRIX_ORACLE_ADMIN_PASSWORD=${config.getOrThrow('registerUserResult').matrixPassword}\nMATRIX_ORACLE_ADMIN_USER_ID=${config.getOrThrow('registerUserResult').matrixUserId}\nMATRIX_RECOVERY_PHRASE=${config.getOrThrow('registerUserResult').matrixRecoveryPhrase}\n\n# OPENAI\nOPENAI_API_KEY=\n\n# Langfuse\nLANGFUSE_PUBLIC_KEY=\nLANGFUSE_SECRET_KEY=\nLANGFUSE_HOST=https://cloud.langfuse.com\n\nOPEN_ROUTER_API_KEY=\"sk-\"\n\n\n### NOT REQUIRED FOR THE APP BUT SAVE THEM IN SAFE PLACE\n# ORACLE ACCOUNT DETAILS\nORACLE_ADDRESS=${config.getOrThrow('registerUserResult').address}\nORACLE_DID=${config.getOrThrow('registerUserResult').did}\nORACLE_MNEMONIC=${config.getOrThrow('registerUserResult').mnemonic}\nMATRIX_VAULT_PIN=${config.getOrThrow('registerUserResult').pin}\nENTITY_DID=${config.getOrThrow('entityDid')}\n`;\n try {\n fs.writeFileSync(envFile, envContent);\n console.log('✅ .env file created successfully at:', envFile);\n } catch (error) {\n console.error('❌ Failed to create .env file:', error);\n throw error;\n }\n};\n","import { confirm } from '@clack/prompts';\nimport { CLIResult } from '../types';\nimport { Wallet } from '../utils/wallet';\nimport { Command } from './index';\n\nexport class LogoutCommand implements Command {\n name = 'logout';\n description = 'Logout command';\n\n constructor(private wallet: Wallet) {}\n\n async execute(): Promise<CLIResult> {\n const shouldClear = await confirm({\n message: 'Are you sure you want to logout?',\n initialValue: false,\n });\n if (shouldClear) {\n await this.wallet.clearWallet();\n return {\n success: true,\n data: 'Logged out successfully',\n };\n }\n return {\n success: false,\n error: 'Logout cancelled',\n };\n }\n}\n","'use server';\nimport { toHex } from '@cosmjs/encoding';\nimport { EncodeObject } from '@cosmjs/proto-signing';\nimport { createRegistry } from '@ixo/impactxclient-sdk';\nimport {\n SignX as IxoSignX,\n SIGN_X_LOGIN_ERROR,\n SIGN_X_LOGIN_SUCCESS,\n SIGN_X_TRANSACT_ERROR,\n SIGN_X_TRANSACT_SUCCESS,\n} from '@ixo/signx-sdk';\nimport { LOGIN_DATA } from '@ixo/signx-sdk/types/types/transact';\nimport qrcode from 'qrcode-terminal';\nimport { WalletProps } from './types';\n\nconst SignXEndpoints = {\n devnet: 'https://signx.devnet.ixo.earth',\n testnet: 'https://signx.testnet.ixo.earth',\n mainnet: 'https://signx.ixo.earth',\n};\n\nexport class SignXClient {\n private readonly signXClient: IxoSignX;\n private _loginData?: LOGIN_DATA;\n public get loginData() {\n return this._loginData;\n }\n\n static loadFromWallet(wallet: WalletProps) {\n return new IxoSignX({\n endpoint: SignXEndpoints[wallet.network],\n sitename: 'IXO Oracles CLI',\n network: wallet.network,\n });\n }\n\n constructor(chainNetwork: keyof typeof SignXEndpoints) {\n this.signXClient = new IxoSignX({\n endpoint: SignXEndpoints[chainNetwork],\n sitename: 'IXO Oracles CLI',\n network: chainNetwork,\n });\n }\n\n async login() {\n const loginData = await this.signXClient.login({ pollingInterval: 2000, matrix: true });\n this._loginData = loginData;\n return loginData;\n }\n\n private displayStyledQRCode(qrCodeData: string | LOGIN_DATA, title: string) {\n const qrCodeStr = typeof qrCodeData === 'string' ? qrCodeData : JSON.stringify(qrCodeData);\n\n // Display title with emoji\n console.log('\\n' + ' '.repeat(5) + '🔐 ' + title);\n console.log(' '.repeat(5) + '📱 Scan with IXO app');\n console.log(' '.repeat(5) + '━'.repeat(30));\n\n // Generate very compact QR code\n qrcode.generate(qrCodeStr, {\n small: true,\n });\n console.log(' '.repeat(5) + '⏳ Waiting...\\n');\n }\n\n public displayQRCode(qrCodeData: string | LOGIN_DATA) {\n this.displayStyledQRCode(qrCodeData, 'Login with SignX');\n }\n\n async awaitLogin() {\n return new Promise<WalletProps>((resolve, reject) => {\n try {\n this.signXClient.on(SIGN_X_LOGIN_SUCCESS, async (response: { data: WalletProps }) => {\n resolve(response.data); // Resolve the promise with the login success data\n });\n\n this.signXClient.on(SIGN_X_LOGIN_ERROR, (error) => {\n console.log('Login error:', error);\n reject(error); // Reject the promise with the login error\n });\n\n // Use loginRequest data to show QR code to user for scanning by mobile app\n } catch (error) {\n console.error('Error in connecting:', error);\n reject(error); // Reject the promise with any other errors\n }\n });\n }\n\n async transact(messages: readonly EncodeObject[], wallet: WalletProps, memo?: string) {\n const registry = createRegistry();\n\n return this.signXClient.transact({\n address: wallet.address,\n did: wallet.did,\n pubkey: wallet.pubKey,\n timestamp: new Date().toISOString(),\n transactions: [\n {\n sequence: 1,\n txBodyHex: toHex(registry.encodeTxBody({ messages: messages, memo: memo || '' })),\n },\n ],\n });\n }\n\n async awaitTransaction() {\n return new Promise((resolve, reject) => {\n try {\n this.signXClient.on(SIGN_X_TRANSACT_SUCCESS, (result) => {\n resolve(result.data); // Resolve the promise with the login success data\n });\n\n this.signXClient.on(SIGN_X_TRANSACT_ERROR, (error) => {\n reject(error); // Reject the promise with the login error\n });\n // Use loginRequest data to show QR code to user for scanning by mobile app\n } catch (error) {\n console.error('Error in connecting:', error);\n reject(error); // Reject the promise with any other errors\n }\n });\n }\n\n async pollNextTransaction() {\n return this.signXClient.pollNextTransaction();\n }\n\n displayTransactionQRCode(qrCodeData: string) {\n this.displayStyledQRCode(qrCodeData, 'SIGNX TRANSACTION');\n }\n}\n","import { CLIResult } from '../types';\nimport { selectNetwork } from '../utils/common';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { SignXClient } from '../utils/signx/signx';\nimport { Wallet } from '../utils/wallet';\nimport { Command } from './index';\n\nexport class SignXLoginCommand implements Command {\n name = 'signx-login';\n description = 'Login with SignX wallet';\n\n constructor(private wallet: Wallet, private config: RuntimeConfig) {}\n\n async execute(): Promise<CLIResult> {\n try {\n // Select network and create SignX client\n const network = await selectNetwork(this.config);\n const signXClient = new SignXClient(network);\n\n // Start login process\n const loginData = await signXClient.login();\n\n // Display QR code for user to scan\n signXClient.displayQRCode(loginData);\n\n // Wait for login completion\n const loginResult = await signXClient.awaitLogin();\n this.wallet.setWallet(loginResult);\n this.wallet.setSignXClient(signXClient);\n return {\n success: true,\n data: {\n message: 'Successfully logged in with SignX!',\n wallet: {\n address: loginResult.address,\n did: loginResult.did,\n name: loginResult.name,\n },\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? `SignX login failed: ${error.message}` : 'Unknown error',\n };\n }\n }\n}\n","export class CLIError extends Error {\n constructor(message: string, public code: string = 'CLI_ERROR', public suggestions?: string[]) {\n super(message);\n this.name = 'CLIError';\n }\n}\n\nexport class ConfigError extends CLIError {\n constructor(message: string, suggestions?: string[]) {\n super(message, 'CONFIG_ERROR', suggestions);\n this.name = 'ConfigError';\n }\n}\n\nexport class NetworkError extends CLIError {\n constructor(message: string, suggestions?: string[]) {\n super(message, 'NETWORK_ERROR', suggestions);\n this.name = 'NetworkError';\n }\n}\n\nexport class ValidationError extends CLIError {\n constructor(message: string, suggestions?: string[]) {\n super(message, 'VALIDATION_ERROR', suggestions);\n this.name = 'ValidationError';\n }\n}\n\nexport function handleError(error: unknown): never {\n if (error instanceof CLIError) {\n console.error(`\\n❌ ${error.name}: ${error.message}`);\n if (error.suggestions?.length) {\n console.error('\\nSuggestions:');\n error.suggestions.forEach((suggestion) => console.error(` • ${suggestion}`));\n }\n process.exit(1);\n }\n\n if (error instanceof Error) {\n console.error(`\\n❌ Unexpected Error: ${error.message}`);\n if (error.stack) {\n console.error('\\nStack trace:');\n console.error(error.stack);\n }\n process.exit(1);\n }\n\n console.error('\\n❌ Unknown error occurred');\n process.exit(1);\n}\n","import { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { SimplifiedRegistrationResult } from './account/simplifiedRegistration';\n\ninterface Config {\n authZFile: string;\n feesFile: string;\n projectPath: string;\n projectName: string;\n entityDid: string;\n network: NETWORK;\n repo: string;\n registerUserResult: SimplifiedRegistrationResult & {\n matrixDeviceName: string;\n };\n}\n\nexport class RuntimeConfig {\n private config: Partial<Config> = {};\n private static instance: RuntimeConfig;\n private constructor() {}\n\n public static getInstance(): RuntimeConfig {\n if (!RuntimeConfig.instance) {\n RuntimeConfig.instance = new RuntimeConfig();\n }\n return RuntimeConfig.instance;\n }\n\n public addValue<K extends keyof Config>(key: K, value: Config[K]) {\n this.config[key] = value;\n }\n\n public getValue(key: keyof Config) {\n return this.config[key];\n }\n\n public getOrThrow<K extends keyof Config>(key: K): Config[K] {\n const value = this.getValue(key);\n if (!value) {\n throw new Error(`Value ${key} is not set`);\n }\n return value as Config[K];\n }\n\n public getConfig() {\n return this.config;\n }\n\n public deleteValue(key: keyof Config) {\n delete this.config[key];\n }\n}\n","import { cosmos } from '@ixo/impactxclient-sdk';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\nimport { unlink } from 'fs/promises';\nimport os from 'os';\nimport path from 'path';\nimport { SignXClient } from './signx/signx';\nimport { WalletProps } from './signx/types';\n\n// Use hidden .wallet.json file in user's home directory\nconst WALLET_PATH = path.join(os.homedir(), '.wallet.json');\n\n// for dev make it here\n// const WALLET_PATH = path.join(__dirname, '.wallet.json');\n\nexport class Wallet {\n public wallet: WalletProps | undefined;\n public signXClient?: SignXClient;\n\n constructor() {\n this.loadWallet();\n }\n\n public setSignXClient(signXClient: SignXClient) {\n this.signXClient = signXClient;\n }\n\n private loadWallet() {\n if (existsSync(WALLET_PATH)) {\n try {\n const walletData = readFileSync(WALLET_PATH, 'utf8');\n this.wallet = JSON.parse(walletData) as WalletProps;\n // set signx client\n this.setSignXClient(new SignXClient(this.wallet.network ?? 'devnet'));\n console.log('Wallet loaded successfully');\n } catch (error) {\n console.warn('Failed to load wallet file:', error);\n this.wallet = undefined;\n }\n } else {\n console.log('No wallet file found');\n }\n }\n\n setWallet(wallet: WalletProps) {\n try {\n this.wallet = wallet;\n const walletJson = JSON.stringify(wallet, null, 2);\n writeFileSync(WALLET_PATH, walletJson, 'utf8');\n console.log('Wallet saved successfully to:', WALLET_PATH);\n } catch (error) {\n console.error('Failed to save wallet:', error);\n throw new Error('Failed to save wallet file');\n }\n }\n\n public checkWalletExists() {\n return existsSync(WALLET_PATH) && this.wallet !== undefined;\n }\n\n public async clearWallet() {\n this.wallet = undefined;\n try {\n if (existsSync(WALLET_PATH)) {\n await unlink(WALLET_PATH);\n console.log('Wallet file deleted successfully');\n }\n } catch (error) {\n console.error('Failed to delete wallet file:', error);\n }\n }\n\n get did() {\n return this.wallet?.did;\n }\n\n get address() {\n return this.wallet?.address;\n }\n\n get name() {\n return this.wallet?.name;\n }\n\n get pubKey() {\n return this.wallet?.pubKey;\n }\n\n get algo() {\n return this.wallet?.algo;\n }\n\n get matrix() {\n return this.wallet?.matrix;\n }\n\n public reloadWallet() {\n this.loadWallet();\n }\n\n async sendTokens(address: string, amount: number) {\n if (!this.address || !this.signXClient || !this.wallet) {\n throw new Error('Wallet not loaded');\n }\n const sendTokensToUserMsg = {\n typeUrl: '/cosmos.bank.v1beta1.MsgSend',\n value: cosmos.bank.v1beta1.MsgSend.fromPartial({\n fromAddress: this.address,\n toAddress: address,\n amount: [\n cosmos.base.v1beta1.Coin.fromPartial({\n amount: amount.toString(),\n denom: 'uixo',\n }),\n ],\n }),\n };\n const tx = await this.signXClient?.transact([sendTokensToUserMsg], this.wallet);\n this.signXClient?.displayTransactionQRCode(JSON.stringify(tx));\n await this.signXClient?.pollNextTransaction();\n const response = await this.signXClient?.awaitTransaction();\n return response;\n }\n}\n"],"mappings":"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","names":["cancel","intro","isCancel","log","outro","select","spinner","process","CommandRegistry","command","name","cmd","select","z","selectNetwork","config","network","RELAYER_NODE_DID","MatrixHomeServerUrl","MatrixRoomBotServerUrl","PORTAL_URL","CHAIN_RPC","checkRequiredString","value","message","result","z","checkRequiredURL","checkRequiredNumber","isCancel","log","spinner","text","customMessages","ixo","utils","utils","createMatrixApiClient","sha256","eciesEncrypt","ClientEvent","createClient","md5","secretStorageKeys","hasPrivateKey","keyId","secretStorageKeys","getPrivateKey","clearSecretStorageKeys","secretStorageKeys","getSecretStorageKey","keys","keyIds","keyId","hasPrivateKey","privateKey","getPrivateKey","cacheSecretStorageKey","keyInfo","Bip39","EnglishMnemonic","Secp256k1","sha256","Slip10","Slip10Curve","stringToPath","DirectSecp256k1HdWallet","createQueryClient","createSigningClient","customMessages","ixo","utils","createCipheriv","randomBytes","createQueryClient","createRegistry","utils","convertTimestampObjectToTimestamp","timestamp","utils","FEEGRANT_TYPES","decodeGrants","grants","registry","createRegistry","grant","allowance","decodedAllowance","FEEGRANT_TYPES","convertTimestampObjectToTimestamp","limit","isAllowanceExpired","expiration","expirationTimestamp","isAllowanceLimitReached","checkIidDocumentExists","did","network","url","CHAIN_RPC","createQueryClient","error","createIidDocument","offlineSigner","accounts","address","pubkey","allowances","queryAddressAllowances","feegrantGranter","decodeGrants","allowance","isAllowanceExpired","isAllowanceLimitReached","trx","ixo","customMessages","signAndBroadcastWithMnemonic","messages","memo","signingClient","createSigningClient","simGas","gas","gasOptions","calculateTrxGasOptions","fee","result","gasUsed","gasPriceStep","delay","ms","resolve","encrypt","text","password","iv","randomBytes","cipher","createCipheriv","encrypted","getSecpClient","mnemonic","wallet","DirectSecp256k1HdWallet","account","seed","Bip39","EnglishMnemonic","hdPath","stringToPath","privkey","Slip10","Slip10Curve","keypair","Secp256k1","compressedPubkey","utils","signerAddress","signDoc","message","challengeBytes","messageHash","sha256","WELL_KNOWN_URI","mxLogin","homeServerUrl","username","password","deviceName","localMatrix","mxHomeServerUrl","mxUsername","mxIdMatch","getBaseUrl","client","createTemporaryClient","response","normalizeUsername","error","msg","getPublicKeyForEncryption","network","MatrixRoomBotServerUrl","createUserCreationChallenge","address","challenge","challengeBase64","encryptPasswordWithECIES","publicKey","publicKeyBytes","passwordBytes","encryptedPassword","eciesEncrypt","byte","createUserAccountWithSecp","address","password","signature","challenge","network","publicKeyInfo","getPublicKeyForEncryption","encryptedPassword","encryptPasswordWithECIES","request","response","MatrixRoomBotServerUrl","errorData","mxRegisterWithSecp","address","password","deviceName","wallet","network","challengeBase64","createUserCreationChallenge","signatureBytes","signature","createUserAccountWithSecp","homeServerUrl","MatrixHomeServerUrl","username","generateUsernameFromAddress","mxLogin","error","checkIsUsernameAvailable","homeServerUrl","username","client","createTemporaryClient","createClient","createMatrixClient","accessToken","userId","deviceId","mxClient","getSecretStorageKey","cacheSecretStorageKey","resolve","reject","sync","ClientEvent","state","logoutMatrixClient","baseUrl","hasCrossSigningAccountData","masterKeyData","setupCrossSigning","securityPhrase","password","forceReset","skipBootstrapSecureStorage","clearSecretStorageKeys","mxCrypto","recoveryKey","makeRequest","getAuthId","delay","generateUsernameFromAddress","address","generatePasswordFromMnemonic","mnemonic","md5","generatePassphraseFromMnemonic","mnemonic","hash","sha256","cleanMatrixHomeServerUrl","homeServer","generateUserRoomNameFromAddress","address","postpend","generateUserRoomAliasFromAddress","homeServerUrl","getBaseUrl","servername","protocol","serverDiscoveryUrl","WELL_KNOWN_URI","baseUrl","normalizeUsername","rawUsername","getAuthId","userId","password","DEVICE_NAME","registerUserSimplified","pin","oracleName","network","oracleAvatarUrl","transferTokens","mnemonic","utils","wallet","getSecpClient","address","did","didExists","checkIidDocumentExists","createIidDocument","delay","mxMnemonic","homeServerUrl","MatrixHomeServerUrl","mxUsername","generateUsernameFromAddress","mxPassword","generatePasswordFromMnemonic","mxPassphrase","generatePassphraseFromMnemonic","checkIsUsernameAvailable","account","mxRegisterWithSecp","mxClient","createMatrixClient","error","matrixApiClient","createMatrixApiClient","hasCrossSigning","hasCrossSigningAccountData","setupCrossSigning","mxRoomAlias","generateUserRoomAliasFromAddress","roomId","response","MatrixRoomBotServerUrl","joinedMembers","joined","encryptedMnemonic","encrypt","storeEncryptedMnemonicResponse","logoutMatrixClient","createMatrixApiClient","mxUtils","CID","base64","mfsha2","createCIDFromBase64","base64String","multibaseString","bytes","hash","jsonToBase64","jsonString","uint8Array","publicUpload","data","fileName","config","wallet","matrixAPIClient","createMatrixApiClient","MatrixHomeServerUrl","file","response","httpUrl","mxUtils","jsonString","base64String","jsonToBase64","cid","createCIDFromBase64","CreateEntity","wallet","config","customMessages","ixo","RELAYER_NODE_DID","utils","oracleAccountAddress","oracleName","entityDid","response","publicUpload","price","walletAddress","linkedResourcesMsgs","resource","log","tx","content","title","pageResource","orgName","name","logo","coverImage","location","description","profileResource","services","service","parentProtocol","params","msg","pin","text","value","checkRequiredString","isCancel","registerResult","registerUserSimplified","address","did","s","spinner","CreateEntityCommand","wallet","config","CreateEntity","selectNetwork","results","value","checkRequiredString","checkRequiredNumber","checkRequiredURL","did","portalUrl","PORTAL_URL","HelpCommand","registry","cmd","p","existsSync","path","simpleGit","fs","path","createProjectEnvFile","config","freshMx","mxLogin","MatrixHomeServerUrl","network","projectPath","envFile","path","envDir","fs","envContent","error","InitCommand","config","wallet","input","value","inputStr","projectPath","projectName","path","name","existsSync","overwrite","confirm","repo","customRepo","shouldOverwrite","git","simpleGit","cloneSpinner","rmSync","gitFolder","CreateEntityCommand","createProjectEnvFile","error","confirm","LogoutCommand","wallet","toHex","createRegistry","IxoSignX","SIGN_X_LOGIN_ERROR","SIGN_X_LOGIN_SUCCESS","SIGN_X_TRANSACT_ERROR","SIGN_X_TRANSACT_SUCCESS","qrcode","SignXEndpoints","SignXClient","wallet","chainNetwork","loginData","qrCodeData","title","qrCodeStr","resolve","reject","response","error","messages","memo","registry","result","SignXLoginCommand","wallet","config","network","selectNetwork","signXClient","SignXClient","loginData","loginResult","error","CLIError","message","code","suggestions","handleError","error","CLIError","suggestion","RuntimeConfig","_RuntimeConfig","key","value","cosmos","existsSync","readFileSync","writeFileSync","unlink","os","path","WALLET_PATH","path","os","Wallet","signXClient","existsSync","walletData","readFileSync","SignXClient","error","wallet","walletJson","writeFileSync","unlink","address","amount","sendTokensToUserMsg","cosmos","tx","CLIManager","CommandRegistry","RuntimeConfig","Wallet","InitCommand","CreateEntityCommand","LogoutCommand","HelpCommand","result","login","select","isCancel","cancel","process","SignXLoginCommand","log","commandName","command","s","spinner","intro","action","args","userArgs","error","handleError","outro","cli"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/index.ts","../src/commands/create-entity-command.ts","../src/utils/common.ts","../src/utils/entity.ts","../src/utils/account/simplifiedRegistration.ts","../src/utils/account/matrix.ts","../src/utils/account/secretStorageKeys.ts","../src/utils/account/utils.ts","../src/utils/account/feegrant.ts","../src/utils/matrix/upload-to-matrix.ts","../src/utils/createCIDFromBase64.ts","../src/commands/help.command.ts","../src/commands/init.command.ts","../src/utils/create-project-env-file.ts","../src/commands/logout.commands.ts","../src/utils/signx/signx.ts","../src/commands/signX.commands.ts","../src/utils/errors.ts","../src/utils/runtime-config.ts","../src/utils/wallet.ts"],"sourcesContent":["import { cancel, intro, isCancel, log, outro, select, spinner } from '@clack/prompts';\nimport process from 'node:process';\nimport { CommandRegistry } from './commands';\nimport { CreateEntityCommand } from './commands/create-entity-command';\nimport { HelpCommand } from './commands/help.command';\nimport { InitCommand } from './commands/init.command';\nimport { LogoutCommand } from './commands/logout.commands';\nimport { SignXLoginCommand } from './commands/signX.commands';\nimport { handleError } from './utils/errors';\nimport { RuntimeConfig } from './utils/runtime-config';\nimport { Wallet } from './utils/wallet';\n\nclass CLIManager {\n private registry: CommandRegistry;\n private config: RuntimeConfig;\n private wallet: Wallet;\n\n constructor() {\n this.registry = new CommandRegistry();\n this.config = RuntimeConfig.getInstance();\n this.wallet = new Wallet();\n }\n\n private registerCommands(): void {\n this.registry.register(new InitCommand(this.config, this.wallet));\n this.registry.register(new CreateEntityCommand(this.wallet, this.config));\n this.registry.register(new LogoutCommand(this.wallet));\n this.registry.register(new HelpCommand(this.registry));\n }\n\n private async showHelp(): Promise<void> {\n // add fake wallet to the config\n this.wallet.setWallet({\n address: '0x0000000000000000000000000000000000000000',\n algo: 'secp',\n did: 'did:ixo:entity:1a76366f16570483cea72b111b27fd78',\n network: 'devnet',\n name: 'My oracle',\n pubKey:\n '0x0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',\n ledgered: false,\n matrix: {\n accessToken: '',\n userId: '0x0000000000000000000000000000000000000000',\n address: '',\n roomId: '',\n },\n });\n this.registerCommands();\n const helpCommand = new HelpCommand(this.registry);\n const result = await helpCommand.execute();\n if (result.success && result.data) {\n console.log(result.data);\n }\n }\n\n private async handleAuthentication(): Promise<void> {\n if (!this.wallet.checkWalletExists()) {\n const login = await select({\n message: 'Login with SignX',\n options: [\n { value: 'login', label: 'Login' },\n { value: 'exit', label: 'Exit' },\n ],\n });\n\n if (isCancel(login)) {\n cancel('Operation cancelled.');\n process.exit(0);\n }\n\n switch (String(login)) {\n case 'login':\n const loginCommand = new SignXLoginCommand(this.wallet, this.config);\n const result = await loginCommand.execute();\n if (result.success) {\n log.success('Login successful');\n }\n break;\n case 'exit':\n cancel('Operation cancelled.');\n process.exit(0);\n default:\n throw new Error(`Unknown command: ${login}`);\n }\n }\n }\n\n private async executeCommand(commandName: string): Promise<void> {\n const command = this.registry.get(commandName);\n if (!command) {\n throw new Error(`Unknown command: ${commandName}`);\n }\n\n const s = spinner();\n s.start(`Executing ${command.name}...`);\n\n const result = await command.execute();\n s.stop(`${command.name} completed`);\n\n if (result.success) {\n log.success(`${command.name} completed successfully!`);\n if (result.data) {\n log.info(JSON.stringify(result.data, null, 2));\n }\n } else {\n log.error(`${command.name} failed: ${result.error}`);\n }\n }\n\n private async interactiveMode(): Promise<void> {\n intro('IXO CLI');\n log.warn('Keep your IXO Mobile App open while running the CLI; So u do not interrupt the signX session');\n\n await this.handleAuthentication();\n this.registerCommands();\n\n const action = await select({\n message: `Welcome ${this.wallet.name}, what would you like to do?`,\n options: [...this.registry.getCommandOptions()],\n initialValue: 'init',\n });\n\n if (isCancel(action)) {\n cancel('Operation cancelled.');\n process.exit(0);\n }\n\n await this.executeCommand(String(action));\n }\n\n private async argumentMode(args: string[]): Promise<void> {\n const command = args[0];\n\n if (!command) {\n await this.interactiveMode();\n return;\n }\n\n // Handle special flags\n if (command === '--init') {\n await this.handleAuthentication();\n this.registerCommands();\n await this.executeCommand('init');\n return;\n }\n\n // Handle help\n if (command === '--help' || command === '-h') {\n await this.showHelp();\n return;\n }\n\n // Handle direct command execution\n await this.handleAuthentication();\n this.registerCommands();\n await this.executeCommand(command);\n }\n\n async run(args: string[]): Promise<void> {\n try {\n // Remove the first two args (node path and script path)\n const userArgs = args.slice(2);\n\n if (userArgs.length === 0) {\n await this.interactiveMode();\n } else {\n await this.argumentMode(userArgs);\n }\n } catch (error) {\n handleError(error);\n }\n\n outro('Thanks for using IXO CLI!');\n process.exit(0);\n }\n}\n\n// Handle uncaught errors\nprocess.on('uncaughtException', handleError);\nprocess.on('unhandledRejection', handleError);\n\n// Start the CLI\nconst cli = new CLIManager();\ncli.run(process.argv);\n","import { CLIResult } from '../types';\n\nexport interface Command {\n name: string;\n description: string;\n execute: (...args: any[]) => Promise<CLIResult>;\n}\n\nexport class CommandRegistry {\n private commands: Map<string, Command>;\n\n constructor() {\n this.commands = new Map();\n }\n\n register(command: Command): void {\n this.commands.set(command.name, command);\n }\n\n get(name: string): Command | undefined {\n return this.commands.get(name);\n }\n\n getAll(): Command[] {\n return Array.from(this.commands.values());\n }\n\n getCommandOptions() {\n return this.getAll().map((cmd) => ({\n value: cmd.name,\n label: cmd.name,\n hint: cmd.description,\n }));\n }\n}\n","import * as p from '@clack/prompts';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { Command } from '.';\nimport { CLIResult } from '../types';\nimport { checkRequiredNumber, checkRequiredString, checkRequiredURL, PORTAL_URL, selectNetwork } from '../utils/common';\nimport { CreateEntity } from '../utils/entity';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { Wallet } from '../utils/wallet';\nexport class CreateEntityCommand implements Command {\n name = 'create-entity';\n description = 'Create an entity';\n private readonly createEntity: CreateEntity;\n\n constructor(private wallet: Wallet, private config: RuntimeConfig) {\n this.createEntity = new CreateEntity(this.wallet, this.config);\n }\n\n async execute(): Promise<CLIResult> {\n const network = this.config.getValue('network') as NETWORK;\n if (!network) {\n await selectNetwork(this.config);\n }\n const results = await p.group(\n {\n oracleName: () =>\n p.text({\n message: 'What is the name of the oracle?',\n initialValue: 'My oracle',\n validate(value) {\n return checkRequiredString(value, 'Oracle name is required');\n },\n }),\n oraclePrice: () =>\n p.text({\n message: 'What is the price of the oracle in IXO CREDITS?',\n initialValue: '100',\n validate(value) {\n return checkRequiredNumber(parseInt(value), 'Oracle price is required and must be a number');\n },\n }),\n page: () =>\n p.group({\n title: () =>\n p.text({\n message: 'What is the title of the oracle entity page?',\n initialValue: 'AI Agent Oracle',\n validate(value) {\n return checkRequiredString(value, 'Title is required');\n },\n }),\n content: () =>\n p.text({\n message: 'What is the content of the oracle entity page?',\n initialValue: '### Oracle built to help u with daily tasks',\n validate(value) {\n return checkRequiredString(value, 'Content is required');\n },\n }),\n }),\n profile: () =>\n p.group({\n orgName: () =>\n p.text({\n message: 'What is the name of the organization?',\n initialValue: 'IXO',\n validate(value) {\n return checkRequiredString(value, 'Organization name is required');\n },\n }),\n name: () =>\n p.text({\n message: 'What is the name of the profile?',\n initialValue: 'My oracle',\n validate(value) {\n return checkRequiredString(value, 'Profile name is required');\n },\n }),\n logo: ({ results }) =>\n p.text({\n message: 'What is the logo of the profile?',\n initialValue: `https://api.dicebear.com/8.x/bottts/svg?seed=${results?.name ?? 'IXO'}`,\n defaultValue: `https://api.dicebear.com/8.x/bottts/svg?seed=${results?.name ?? 'IXO'}`,\n validate(value) {\n if (!value) return `https://api.dicebear.com/8.x/bottts/svg?seed=${results?.name ?? 'IXO'}`;\n return checkRequiredURL(value, 'Logo is required or a valid URL');\n },\n }),\n coverImage: ({ results }) =>\n p.text({\n message: 'What is the cover image of the profile?',\n initialValue: results.logo as string,\n defaultValue: results.logo as string,\n validate(value) {\n if (!value) return results.logo as string;\n return checkRequiredURL(value, 'Cover image is required or a valid URL');\n },\n }),\n location: () =>\n p.text({\n message: 'What is the location of your domain?',\n initialValue: 'New York, NY',\n validate(value) {\n return checkRequiredString(value, 'Location is required');\n },\n }),\n description: () =>\n p.text({\n message: 'What is the description of the entity (profile)?',\n initialValue: 'We are a company that helps you with daily tasks',\n validate(value) {\n return checkRequiredString(value, 'Description is required');\n },\n }),\n }),\n parentProtocol: () =>\n p.select({\n message: 'What is the parent protocol of the entity?',\n options: [\n {\n value: 'did:ixo:entity:1a76366f16570483cea72b111b27fd78',\n label: 'IXO Oracle Protocol',\n hint: 'default protocol',\n },\n ],\n initialValue: 'did:ixo:entity:1a76366f16570483cea72b111b27fd78',\n }),\n },\n {\n // On Cancel callback that wraps the group\n // So if the user cancels one of the prompts in the group this function will be called\n onCancel: () => {\n p.cancel('Operation cancelled.');\n process.exit(0);\n },\n }\n );\n\n const did = await this.createEntity.execute({\n oracleConfig: {\n oracleName: results.oracleName,\n price: parseInt(results.oraclePrice),\n },\n page: results.page,\n profile: {\n orgName: results.profile.orgName,\n name: results.profile.name,\n logo: results.profile.logo as string,\n coverImage: results.profile.coverImage as string,\n location: results.profile.location,\n description: results.profile.description,\n },\n services: [\n {\n id: '{id}#api',\n serviceEndpoint: 'http://localhost:4000',\n type: 'oracleService',\n },\n {\n id: '{id}#ws',\n serviceEndpoint: 'http://localhost:4000',\n type: 'wsService',\n },\n ],\n parentProtocol: results.parentProtocol,\n });\n\n p.log.info(`API for the oracle is: http://localhost:4000 | You can change this after you deploy the oracle`);\n\n // add to portal\n const portalBaseUrl = PORTAL_URL[(this.config.getValue('network') as NETWORK) ?? 'devnet'];\n\n const portalUrl = `${portalBaseUrl}/oracle/${did}/overview`;\n\n p.log.info(`Oracle created successfully: ${did}`);\n p.log.info(`Oracle URL: ${portalUrl}`);\n\n return {\n success: true,\n data: `Entity created successfully: ${did}`,\n };\n }\n}\n","import { select } from '@clack/prompts';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { z } from 'zod';\nimport { RuntimeConfig } from './runtime-config';\n\nexport const selectNetwork = async (config: RuntimeConfig) => {\n const network = await select({\n message: 'Select network: (default: devnet)',\n options: [\n { value: 'mainnet', label: 'Mainnet' },\n { value: 'testnet', label: 'Testnet' },\n { value: 'devnet', label: 'Devnet' },\n ],\n initialValue: 'devnet',\n maxItems: 1,\n });\n\n config.addValue('network', network as NETWORK);\n\n return network as NETWORK;\n};\n\nexport const RELAYER_NODE_DID = {\n mainnet: 'did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d',\n testnet: 'did:ixo:entity:3d079ebc0b332aad3305bb4a51c72edb',\n devnet: 'did:ixo:entity:2f22535f8b179a51d77a0e302e68d35d',\n};\n\nexport const MatrixHomeServerUrl: Record<NETWORK, string> = {\n devnet: 'https://devmx.ixo.earth',\n testnet: 'https://testmx.ixo.earth',\n mainnet: 'https://mx.ixo.earth',\n};\n\nexport const MatrixRoomBotServerUrl: Record<NETWORK, string> = {\n devnet: 'https://rooms.bot.devmx.ixo.earth',\n testnet: 'https://rooms.bot.testmx.ixo.earth',\n mainnet: 'https://rooms.bot.mx.ixo.earth',\n};\n\nexport const MatrixBotHomeServerUrl: Record<NETWORK, string> = {\n devnet: 'https://state.bot.devmx.ixo.earth',\n testnet: 'https://state.bot.testmx.ixo.earth',\n mainnet: 'https://state.bot.mx.ixo.earth',\n};\nexport const PORTAL_URL = {\n devnet: 'https://ixo-portal.vercel.app',\n testnet: 'https://ixo-portal.vercel.app',\n mainnet: 'https://ixo-portal.vercel.app',\n};\n\nexport const CHAIN_RPC = {\n mainnet: 'https://impacthub.ixo.world/rpc/',\n testnet: 'https://testnet.ixo.earth/rpc/',\n devnet: 'https://devnet.ixo.earth/rpc/',\n};\n\nexport const checkRequiredString = (value: string, message = 'This field is required') => {\n const schema = z.string().min(1, message);\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n\nexport const checkRequiredURL = (value: string, message = 'This url is required or a valid URL') => {\n const schema = z.url(message);\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n\nexport const checkRequiredNumber = (value: number, message = 'This number is required') => {\n const schema = z.number().min(1, message);\n const result = schema.safeParse(value);\n if (!result.success) {\n return result.error.message;\n }\n return undefined;\n};\n","import { isCancel, log, spinner, text } from '@clack/prompts';\nimport { customMessages, ixo, utils } from '@ixo/impactxclient-sdk';\nimport { LinkedResource, Service } from '@ixo/impactxclient-sdk/types/codegen/ixo/iid/v1beta1/types';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { registerUserSimplified } from './account/simplifiedRegistration';\nimport { checkRequiredString, RELAYER_NODE_DID } from './common';\nimport { publicUpload } from './matrix/upload-to-matrix';\nimport { RuntimeConfig } from './runtime-config';\nimport { Wallet } from './wallet';\n\ninterface BlockNoteBlock {\n id: string;\n type: string;\n props: {\n textColor: string;\n backgroundColor: string;\n textAlignment: string;\n level?: number;\n };\n content: Array<{\n type: string;\n text: string;\n styles: Record<string, any>;\n }>;\n children?: any[];\n}\ninterface BlockNotePage {\n title: string;\n blocks: BlockNoteBlock[] | null;\n}\n\ninterface CreateEntityParams {\n profile: {\n orgName: string;\n name: string;\n logo: string;\n coverImage: string;\n location: string;\n description: string;\n };\n page: {\n title: string;\n content: string;\n };\n services: Service[];\n parentProtocol: string;\n oracleConfig: {\n oracleName: string;\n price: number;\n };\n}\n\nexport class CreateEntity {\n private readonly wallet: Wallet;\n constructor(wallet: Wallet, private config: RuntimeConfig) {\n if (!wallet.did || !wallet.pubKey || !wallet.address || !wallet.algo) {\n throw new Error('Wallet not found');\n }\n this.wallet = wallet;\n this.MsgCreateEntityParams.value.verification = [\n ...customMessages.iid.createIidVerificationMethods({\n did: wallet.did,\n pubkey: new Uint8Array(Buffer.from(wallet.pubKey)),\n address: wallet.address,\n controller: wallet.did,\n type: wallet.algo === 'ed25519' ? 'ed' : 'secp',\n }),\n ];\n\n this.MsgCreateEntityParams.value.context = [];\n this.MsgCreateEntityParams.value.controller = [wallet.did];\n this.MsgCreateEntityParams.value.ownerAddress = wallet.address;\n this.MsgCreateEntityParams.value.ownerDid = wallet.did;\n this.MsgCreateEntityParams.value.service.push(\n ixo.iid.v1beta1.Service.fromPartial({\n id: '{id}#matrix',\n type: 'Matrix',\n serviceEndpoint: 'devmx.ixo.earth',\n })\n );\n\n this.MsgCreateEntityParams.value.relayerNode =\n RELAYER_NODE_DID[(this.config.getValue('network') as NETWORK) ?? 'devnet'];\n }\n private MsgCreateEntityParams = {\n typeUrl: '/ixo.entity.v1beta1.MsgCreateEntity',\n value: ixo.entity.v1beta1.MsgCreateEntity.fromPartial({\n entityType: 'oracle',\n context: [],\n entityStatus: 0,\n verification: [],\n controller: [],\n ownerAddress: '',\n ownerDid: '',\n relayerNode: '',\n service: [],\n linkedResource: [],\n accordedRight: [],\n linkedEntity: [],\n linkedClaim: [],\n startDate: utils.proto.toTimestamp(new Date()),\n endDate: utils.proto.toTimestamp(new Date(Date.now() + 100 * 365 * 24 * 60 * 60 * 1000)),\n }),\n };\n\n private async createAuthZConfig({\n oracleAccountAddress,\n oracleName,\n entityDid,\n }: {\n oracleAccountAddress: string;\n oracleName: string;\n entityDid: string;\n }): Promise<LinkedResource> {\n const config = {\n '@context': [\n 'https://schema.org',\n {\n ixo: 'https://w3id.org/ixo/context/v1',\n oracle: {\n '@id': entityDid,\n '@type': '@id',\n },\n },\n ],\n '@type': 'Service',\n '@id': 'oracle:OracleAuthorization',\n name: 'OracleAuthorization',\n description: 'OracleAuthorization',\n serviceType: 'OracleClaimAuthorizationService',\n requiredPermissions: ['/ixo.claims.v1beta1.MsgCreateClaimAuthorization'],\n granteeAddress: oracleAccountAddress,\n granterAddress: '',\n oracleName: oracleName,\n };\n const response = await publicUpload({\n data: config,\n fileName: 'authz',\n config: this.config,\n wallet: this.wallet,\n });\n\n return ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: '{id}#orz',\n type: 'oracleAuthZConfig',\n proof: response.proof,\n right: '',\n encrypted: 'false',\n mediaType: 'application/json',\n description: 'Orale AuthZ Config',\n serviceEndpoint: response.serviceEndpoint,\n });\n }\n\n /**\n * Create Fees Config\n * @param entityDid\n * @param price\n *\n * The fees config is used to set the pricing for the oracle -- this config is fetched by the Frontend and any client to use the pricing for the oracle and grant max amount permissions\n */\n private async createFeesConfig({ entityDid, price }: { entityDid: string; price: number }): Promise<LinkedResource> {\n const config = {\n '@context': [\n 'https://schema.org',\n {\n ixo: 'https://w3id.org/ixo/context/v1',\n oracle: {\n '@id': entityDid,\n '@type': '@id',\n },\n },\n ],\n '@type': 'Service',\n '@id': 'oracle:ServiceFeeModel',\n name: 'Pricing',\n description: 'Pricing',\n serviceType: '',\n offers: {\n '@type': 'Offer',\n priceCurrency: 'uixo',\n priceSpecification: {\n '@type': 'PaymentChargeSpecification',\n priceCurrency: 'uixo',\n price: price,\n unitCode: 'MON',\n billingIncrement: 1,\n billingPeriod: 'P1M',\n priceType: 'Subscription',\n maxPrice: price,\n },\n eligibleQuantity: {\n '@type': 'QuantitativeValue',\n value: 1,\n unitCode: 'MON',\n },\n },\n };\n const response = await publicUpload({\n data: config,\n fileName: 'fees',\n config: this.config,\n wallet: this.wallet,\n });\n return ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: '{id}#fee',\n type: 'pricingList',\n proof: response.proof,\n right: '',\n encrypted: 'false',\n mediaType: 'application/json',\n description: 'Pricing List',\n serviceEndpoint: response.serviceEndpoint,\n });\n }\n\n /**\n * Create Oracle Config Files\n * @param oracleAccountAddress\n * @param oracleName\n * @param entityDid\n * @param price\n *\n * Using this after the entity is created to upload the config files to the entity using it's did\n * this will do entity update to add the config files to the entity\n */\n private async createOracleConfigFiles({\n oracleName,\n entityDid,\n price,\n oracleAccountAddress,\n }: CreateEntityParams['oracleConfig'] & { entityDid: string; oracleAccountAddress: string }) {\n const walletAddress = this.wallet.wallet?.address;\n\n if (!this.wallet.signXClient || !this.wallet.wallet || !walletAddress) {\n throw new Error('SignX client or wallet not found');\n }\n\n const resources = await Promise.all([\n this.createAuthZConfig({\n oracleName,\n entityDid,\n oracleAccountAddress,\n }),\n this.createFeesConfig({\n entityDid,\n price,\n }),\n ]);\n const linkedResourcesMsgs = resources.map((resource) => ({\n typeUrl: '/ixo.iid.v1beta1.MsgAddLinkedResource',\n value: ixo.iid.v1beta1.MsgAddLinkedResource.fromPartial({\n id: entityDid,\n linkedResource: ixo.iid.v1beta1.LinkedResource.fromPartial({\n id: resource.id,\n description: resource.description,\n type: resource.type,\n proof: resource.proof,\n mediaType: resource.mediaType,\n encrypted: resource.encrypted,\n serviceEndpoint: resource.serviceEndpoint,\n }),\n signer: walletAddress,\n }),\n }));\n\n // sign and send the msgs\n log.info('Sign to edit the entity and add the config files');\n const tx = await this.wallet.signXClient.transact(linkedResourcesMsgs, this.wallet.wallet);\n this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(tx));\n await this.wallet.signXClient.pollNextTransaction();\n const response = await this.wallet.signXClient.awaitTransaction();\n return response;\n }\n\n private async addPage({ content, title }: CreateEntityParams['page']) {\n const blockNotePage: BlockNotePage = {\n title,\n blocks: [\n {\n id: 'title-block',\n type: 'heading',\n props: { textColor: 'default', backgroundColor: 'default', textAlignment: 'left' },\n content: [{ type: 'text', text: title, styles: {} }],\n },\n {\n id: 'content-block',\n type: 'paragraph',\n props: {\n textColor: 'default',\n backgroundColor: 'default',\n textAlignment: 'left',\n },\n content: [{ type: 'text', text: content, styles: {} }],\n },\n ],\n };\n\n const response = await publicUpload({\n data: blockNotePage,\n fileName: 'page',\n config: this.config,\n wallet: this.wallet,\n });\n\n const pageResource = {\n id: '{id}#pag',\n type: 'Settings',\n description: 'Page',\n mediaType: 'application/json',\n serviceEndpoint: response.serviceEndpoint,\n proof: response.proof,\n encrypted: 'false',\n right: '',\n };\n this.MsgCreateEntityParams.value.linkedResource.push(ixo.iid.v1beta1.LinkedResource.fromPartial(pageResource));\n }\n\n private async addProfile({ orgName, name, logo, coverImage, location, description }: CreateEntityParams['profile']) {\n const profileData = {\n '@context': {\n ixo: 'https://w3id.org/ixo/ns/protocol/',\n '@id': '@type',\n type: '@type',\n '@protected': false,\n },\n id: 'ixo:entity#profile',\n type: 'profile',\n orgName,\n name,\n image: coverImage,\n logo,\n brand: orgName,\n location,\n description,\n };\n\n const response = await publicUpload({\n data: profileData,\n fileName: 'profile',\n config: this.config,\n wallet: this.wallet,\n });\n\n const profileResource = {\n id: '{id}#pro',\n type: 'Settings',\n description: 'Profile',\n mediaType: 'application/json',\n serviceEndpoint: response.serviceEndpoint,\n proof: response.proof,\n encrypted: 'false',\n right: '',\n };\n this.MsgCreateEntityParams.value.linkedResource.push(ixo.iid.v1beta1.LinkedResource.fromPartial(profileResource));\n }\n\n private async addServices(services: Service[]) {\n this.MsgCreateEntityParams.value.service.push(\n ...services.map((service) => ixo.iid.v1beta1.Service.fromPartial(service))\n );\n }\n\n private async setParentProtocol(parentProtocol: string) {\n this.MsgCreateEntityParams.value.context.push(\n ...customMessages.iid.createAgentIidContext([{ key: 'class', val: parentProtocol }])\n );\n }\n\n public returnExecutableMsg() {\n return this.MsgCreateEntityParams;\n }\n\n public async execute(params: CreateEntityParams): Promise<string> {\n log.info('Adding page');\n await this.addPage(params.page);\n log.info('Adding profile');\n await this.addProfile(params.profile);\n log.info('Adding services');\n await this.addServices(params.services);\n log.info('Adding parent protocol');\n await this.setParentProtocol(params.parentProtocol);\n\n const msg = this.returnExecutableMsg();\n if (!this.wallet.signXClient || !this.wallet.wallet) {\n throw new Error('SignX client not found');\n }\n log.info('Sign this transaction to create the entity');\n const tx = await this.wallet.signXClient.transact([msg], this.wallet.wallet);\n this.wallet.signXClient.displayTransactionQRCode(JSON.stringify(tx));\n await this.wallet.signXClient.pollNextTransaction();\n\n // Wait for transaction completion\n const response = await this.wallet.signXClient.awaitTransaction();\n log.success('Entity created -- wait to attach the required config files');\n\n log.info('Creating Oracle Wallet and Matrix Account');\n const pin = await text({\n message: 'Enter a PIN to secure your Matrix Vault:',\n initialValue: '',\n defaultValue: '',\n validate(value) {\n return checkRequiredString(value, 'PIN is required');\n },\n });\n if (isCancel(pin)) {\n log.error('User cancelled');\n process.exit(1);\n }\n const registerResult = await registerUserSimplified(\n {\n pin,\n oracleName: params.oracleConfig.oracleName,\n network: this.config.getValue('network') as NETWORK,\n oracleAvatarUrl: params.profile.logo,\n },\n async (address) => {\n await this.wallet.sendTokens(address, 250_000); // 250,000 uixo = 0.25 IXO;\n }\n );\n\n // upload resources\n const did = utils.common.getValueFromEvents(response as any, 'wasm', 'token_id');\n await this.createOracleConfigFiles({\n oracleName: params.oracleConfig.oracleName,\n price: params.oracleConfig.price,\n oracleAccountAddress: registerResult.address,\n entityDid: did,\n });\n log.success('Entity created -- config files attached');\n const s = spinner();\n s.start('Creating Entity Matrix Room...');\n s.stop('Room created -- room joined');\n log.warn('Please save the following information in a secure location as it is not stored:');\n log.info(`ORACLE ACCOUNT DETAILS`);\n log.info(`Oracle DID: ${registerResult.did}`);\n log.info(`Oracle Account Address: ${registerResult.address}`);\n log.info(`Oracle Account Mnemonic: ${registerResult.mnemonic}`);\n log.info(`Matrix User ID: ${registerResult.matrixUserId}`);\n log.info(`Matrix Password: ${registerResult.matrixPassword}`);\n this.config.addValue('registerUserResult', registerResult);\n this.config.addValue('entityDid', did);\n return did;\n }\n}\n","import { utils } from '@ixo/impactxclient-sdk';\nimport { createMatrixApiClient } from '@ixo/matrixclient-sdk';\n\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { MatrixHomeServerUrl, MatrixRoomBotServerUrl } from '../common';\nimport {\n checkIsUsernameAvailable,\n createMatrixClient,\n generatePassphraseFromMnemonic,\n generatePasswordFromMnemonic,\n generateUsernameFromAddress,\n generateUserRoomAliasFromAddress,\n hasCrossSigningAccountData,\n logoutMatrixClient,\n mxRegisterWithSecp,\n setupCrossSigning,\n} from './matrix';\nimport { checkIidDocumentExists, createIidDocument, delay, encrypt, getSecpClient } from './utils';\n\nexport interface SimplifiedRegistrationResult {\n address: string;\n did: string;\n mnemonic: string;\n matrixUserId: string;\n matrixRoomId: string;\n matrixMnemonic: string;\n matrixPassword: string;\n matrixAccessToken: string;\n matrixRecoveryPhrase: string;\n pin: string;\n matrixDeviceName: string;\n}\n\nconst DEVICE_NAME = 'Oracles CLI';\n/**\n * Simplified user registration flow without email verification or passkey authentication\n * Includes: wallet creation, DID creation, Matrix account with secp auth, Matrix room setup, encrypted mnemonic storage\n * @param pin - User PIN for encrypting Matrix mnemonic\n * @returns Registration result with wallet and Matrix account details\n */\nexport async function registerUserSimplified(\n {\n pin,\n oracleName,\n network,\n oracleAvatarUrl,\n }: {\n pin: string;\n oracleName: string;\n network: NETWORK;\n oracleAvatarUrl: string;\n },\n transferTokens: (address: string) => Promise<void>\n): Promise<SimplifiedRegistrationResult> {\n try {\n // =================================================================================================\n // 1. CREATE WALLET\n // =================================================================================================\n const mnemonic = utils.mnemonic.generateMnemonic();\n const wallet = await getSecpClient(mnemonic);\n const address = wallet.baseAccount.address;\n console.log('✅ Wallet created:', address);\n\n // transfer tokens\n await transferTokens(address);\n\n // =================================================================================================\n // 2. DID CREATION\n // =================================================================================================\n const did = utils.did.generateSecpDid(address);\n const didExists = await checkIidDocumentExists(did, network);\n console.log('✅ DID exists:', didExists);\n if (!didExists) {\n console.log('✅ DID does not exist, creating...');\n await createIidDocument(did, network, wallet);\n console.log('✅ DID created, waiting 500ms...');\n await delay(500);\n console.log('✅ Checking if DID exists...');\n const didExistsAfterCreation = await checkIidDocumentExists(did, network);\n if (!didExistsAfterCreation) {\n throw new Error('Failed to create DID document');\n }\n }\n console.log('✅ DID created:', did);\n\n // =================================================================================================\n // 3. MATRIX ACCOUNT CREATION\n // =================================================================================================\n const mxMnemonic = utils.mnemonic.generateMnemonic(12);\n const homeServerUrl = MatrixHomeServerUrl[network];\n const mxUsername = generateUsernameFromAddress(address);\n const mxPassword = generatePasswordFromMnemonic(mxMnemonic);\n const mxPassphrase = generatePassphraseFromMnemonic(mxMnemonic);\n\n // Check if username is available\n const isUsernameAvailable = await checkIsUsernameAvailable({\n homeServerUrl: homeServerUrl,\n username: mxUsername,\n });\n if (!isUsernameAvailable) {\n throw new Error('Matrix account already exists');\n }\n\n // Clear any residual matrix data\n // await logoutMatrixClient({ baseUrl: homeServerUrl, accessToken: '', userId: '', deviceId: '' });\n\n // Register using secp256k1 signature (not passkey)\n const account = await mxRegisterWithSecp(address, mxPassword, DEVICE_NAME, wallet, network);\n if (!account?.accessToken) {\n throw new Error('Failed to register matrix account');\n }\n console.log('✅ Matrix account created:', account.userId);\n\n // =================================================================================================\n // 4. MATRIX CLIENT SETUP\n // =================================================================================================\n const mxClient = await createMatrixClient({\n homeServerUrl,\n accessToken: account.accessToken,\n userId: account.userId,\n deviceId: account.deviceId,\n });\n\n try {\n await Promise.all([mxClient.setDisplayName(oracleName), mxClient.setAvatarUrl(oracleAvatarUrl)]);\n } catch (error) {\n console.error('Failed to set display name or avatar url:', error);\n }\n\n const matrixApiClient = createMatrixApiClient({\n homeServerUrl: homeServerUrl,\n accessToken: account.accessToken,\n });\n\n // Setup cross signing\n let hasCrossSigning = hasCrossSigningAccountData(mxClient);\n if (!hasCrossSigning) {\n hasCrossSigning = await setupCrossSigning(mxClient, {\n securityPhrase: mxPassphrase,\n password: mxPassword,\n forceReset: true,\n });\n if (!hasCrossSigning) {\n throw new Error('Failed to setup cross signing');\n }\n }\n console.log('✅ Matrix cross-signing setup completed');\n\n // =================================================================================================\n // 5. MATRIX ROOM CREATION/JOIN\n // =================================================================================================\n const mxRoomAlias = generateUserRoomAliasFromAddress(address, account.baseUrl);\n const queryIdResponse = await matrixApiClient.room.v1beta1.queryId(mxRoomAlias).catch(() => undefined);\n let roomId: string = queryIdResponse?.room_id ?? '';\n\n if (!roomId) {\n // Create room via bot\n const response = await fetch(`${MatrixRoomBotServerUrl[network]}/room/source`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n did: did,\n userMatrixId: account.userId,\n }),\n });\n if (!response.ok) {\n throw new Error('Failed to create matrix room');\n }\n const data = (await response.json()) as { roomId: string };\n roomId = data.roomId;\n if (!roomId) {\n throw new Error('Failed to create user matrix room');\n }\n }\n\n // Ensure room is joined\n let joinedMembers = await matrixApiClient.room.v1beta1.listJoinedMembers(roomId).catch(() => undefined);\n let joined = !!joinedMembers?.joined?.[account.userId];\n if (!joined) {\n const joinResponse = await matrixApiClient.room.v1beta1.join(roomId);\n if (!joinResponse.room_id) {\n throw new Error('Failed to join matrix room');\n }\n joinedMembers = await matrixApiClient.room.v1beta1.listJoinedMembers(roomId);\n joined = !!joinedMembers?.joined?.[account.userId];\n if (!joined) {\n throw new Error('Failed to join matrix room');\n }\n }\n console.log('✅ Matrix room created/joined:', roomId);\n\n // =================================================================================================\n // 6. ENCRYPT AND STORE MATRIX MNEMONIC\n // =================================================================================================\n const encryptedMnemonic = encrypt(mxMnemonic, pin);\n const storeEncryptedMnemonicResponse = await fetch(\n `${homeServerUrl}/_matrix/client/r0/rooms/${roomId}/state/ixo.room.state.secure/encrypted_mnemonic`,\n {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${account.accessToken as string}`,\n },\n body: JSON.stringify({\n encrypted_mnemonic: encryptedMnemonic,\n }),\n }\n );\n if (!storeEncryptedMnemonicResponse.ok) {\n throw new Error('Failed to store encrypted mnemonic in matrix room');\n }\n await storeEncryptedMnemonicResponse.json();\n console.log('✅ Encrypted Matrix mnemonic stored in room');\n\n // =================================================================================================\n // 7. LOGOUT MATRIX CLIENT\n // =================================================================================================\n await logoutMatrixClient({\n mxClient,\n baseUrl: homeServerUrl,\n accessToken: account.accessToken,\n userId: account.userId,\n deviceId: account.deviceId,\n });\n\n // =================================================================================================\n // 7. RETURN REGISTRATION RESULT\n // =================================================================================================\n return {\n address: address,\n did: did,\n mnemonic: mnemonic, // Wallet mnemonic - store securely!\n matrixUserId: account.userId,\n matrixRoomId: roomId,\n matrixMnemonic: mxMnemonic, // Matrix mnemonic - also store securely!\n matrixPassword: mxPassword,\n matrixAccessToken: account.accessToken,\n matrixRecoveryPhrase: mxMnemonic,\n pin: pin,\n matrixDeviceName: DEVICE_NAME,\n };\n } catch (error) {\n console.error('Simplified registration failed:', error);\n throw error;\n }\n}\n","import { sha256 } from '@cosmjs/crypto';\nimport { encrypt as eciesEncrypt } from 'eciesjs';\nimport { ClientEvent, createClient, MatrixClient } from 'matrix-js-sdk';\nimport { CryptoApi } from 'matrix-js-sdk/lib/crypto-api';\nimport md5 from 'md5';\n\n// import cons from '@constants/matrix';\n// import { isAuthenticated, secret } from '@utils/secrets';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { MatrixHomeServerUrl, MatrixRoomBotServerUrl } from '../common';\nimport { cacheSecretStorageKey, clearSecretStorageKeys, getSecretStorageKey } from './secretStorageKeys';\nimport { delay } from './utils';\n\nconst WELL_KNOWN_URI = '/.well-known/matrix/client';\n\n// =================================================================================================\n// AUTH\n// =================================================================================================\ninterface AuthResponse {\n accessToken: string;\n deviceId: string;\n userId: string;\n baseUrl: string;\n}\nexport const mxLogin = async (\n {\n homeServerUrl,\n username,\n password,\n deviceName,\n }: { homeServerUrl: string; username: string; password: string; deviceName: string },\n localMatrix = false\n) => {\n let mxHomeServerUrl = homeServerUrl;\n let mxUsername = username;\n const mxIdMatch = mxUsername.match(/^@(.+):(.+\\..+)$/);\n if (mxIdMatch) {\n mxUsername = mxIdMatch[1] as string;\n mxHomeServerUrl = mxIdMatch[2] as string;\n mxHomeServerUrl = localMatrix ? mxHomeServerUrl : await getBaseUrl(mxHomeServerUrl);\n }\n\n try {\n const client = createTemporaryClient(mxHomeServerUrl);\n const response = await client.login('m.login.password', {\n identifier: {\n type: 'm.id.user',\n user: normalizeUsername(mxUsername),\n },\n password,\n initial_device_display_name: deviceName,\n });\n const data: AuthResponse = {\n accessToken: response.access_token,\n deviceId: response.device_id,\n userId: response.user_id,\n baseUrl: localMatrix ? mxHomeServerUrl : response?.well_known?.['m.homeserver']?.base_url || client.baseUrl,\n };\n return data;\n } catch (error) {\n let msg = (error as any).message;\n if (msg === 'Unknown message') {\n msg = 'Please check your credentials';\n }\n console.error(`mxLogin::`, msg);\n throw new Error(msg);\n }\n};\n\n// =================================================================================================\n// NEW API-BASED REGISTRATION\n// =================================================================================================\n\ninterface PublicKeyResponse {\n publicKey: string;\n fingerprint: string;\n algorithm: string;\n usage: string;\n}\n\ninterface UserCreationChallenge {\n timestamp: string;\n address: string;\n service: string;\n type: string;\n}\n\ninterface UserCreationRequest {\n address: string;\n encryptedPassword: string;\n publicKeyFingerprint: string;\n authnResult?: any;\n secpResult?: {\n signature: string;\n challenge: string;\n };\n}\n\ninterface UserCreationResponse {\n success: boolean;\n matrixUserId: string;\n address: string;\n message: string;\n}\n\n/**\n * Fetch the public key for password encryption from the user creation API\n * @returns Public key information for encryption\n */\nexport async function getPublicKeyForEncryption(network: NETWORK): Promise<PublicKeyResponse> {\n const response = await fetch(`${MatrixRoomBotServerUrl[network]}/public-key`, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error('Failed to fetch public key for encryption');\n }\n\n const data = (await response.json()) as PublicKeyResponse;\n return data;\n}\n\n/**\n * Create a structured challenge for user creation\n * @param address The user's address (without did:ixo: prefix)\n * @returns The challenge object and its base64 representation\n */\nexport function createUserCreationChallenge(address: string): {\n challenge: UserCreationChallenge;\n challengeBase64: string;\n} {\n const challenge: UserCreationChallenge = {\n timestamp: new Date().toISOString(),\n address: address,\n service: 'matrix',\n type: 'create-account',\n };\n\n const challengeBase64 = Buffer.from(JSON.stringify(challenge)).toString('base64');\n\n return { challenge, challengeBase64 };\n}\n\n/**\n * Encrypt password using ECIES with the provided public key\n * @param password The password to encrypt\n * @param publicKey The public key in hex format\n * @returns The encrypted password in hex format\n */\nexport function encryptPasswordWithECIES(password: string, publicKey: string): string {\n const publicKeyBytes = new Uint8Array(Buffer.from(publicKey, 'hex'));\n const passwordBytes = new Uint8Array(Buffer.from(password, 'utf8'));\n const encryptedPassword = eciesEncrypt(publicKeyBytes, passwordBytes);\n return Array.from(encryptedPassword, (byte) => byte.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * Create user account using WebAuthn/Passkey authentication\n * @param address The user's address\n * @param password The matrix password\n * @param authnResult The WebAuthn assertion result\n * @returns The user creation response\n */\nexport async function createUserAccountWithPasskey(\n address: string,\n password: string,\n authnResult: any,\n network: NETWORK\n): Promise<UserCreationResponse> {\n const publicKeyInfo = await getPublicKeyForEncryption(network);\n const encryptedPassword = encryptPasswordWithECIES(password, publicKeyInfo.publicKey);\n\n const request: UserCreationRequest = {\n address,\n encryptedPassword,\n publicKeyFingerprint: publicKeyInfo.fingerprint,\n authnResult,\n };\n\n const response = await fetch(`${MatrixRoomBotServerUrl[network]}/user/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const errorData = (await response.json()) as { error: string };\n throw new Error(errorData.error || 'Failed to create user account');\n }\n\n return (await response.json()) as UserCreationResponse;\n}\n\n/**\n * Create user account using secp256k1 signature authentication\n * @param address The user's address\n * @param password The matrix password\n * @param signature The secp256k1 signature (base64)\n * @param challenge The challenge that was signed (base64)\n * @returns The user creation response\n */\nexport async function createUserAccountWithSecp(\n address: string,\n password: string,\n signature: string,\n challenge: string,\n network: NETWORK\n): Promise<UserCreationResponse> {\n const publicKeyInfo = await getPublicKeyForEncryption(network);\n const encryptedPassword = encryptPasswordWithECIES(password, publicKeyInfo.publicKey);\n\n const request: UserCreationRequest = {\n address,\n encryptedPassword,\n publicKeyFingerprint: publicKeyInfo.fingerprint,\n secpResult: {\n signature,\n challenge,\n },\n };\n\n const response = await fetch(`${MatrixRoomBotServerUrl[network]}/user/create`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n const errorData = (await response.json()) as { error: string };\n throw new Error(errorData.error || 'Failed to create user account');\n }\n\n return (await response.json()) as UserCreationResponse;\n}\n\n// =================================================================================================\n// UPDATED REGISTRATION FUNCTIONS\n// =================================================================================================\n\n/**\n * Register matrix account using the new API with WebAuthn/Passkey authentication\n * @param address The user's address\n * @param password The matrix password\n * @param authnResult The WebAuthn assertion result\n * @returns AuthResponse with access token and user details\n */\nexport async function mxRegisterWithPasskey(\n address: string,\n password: string,\n authnResult: any,\n deviceName: string,\n network: NETWORK\n): Promise<AuthResponse> {\n try {\n const userCreationResult = await createUserAccountWithPasskey(address, password, authnResult, network);\n\n if (!userCreationResult.success) {\n throw new Error('Failed to create matrix account via API');\n }\n\n // Now login to get the access token\n const homeServerUrl = MatrixHomeServerUrl[network];\n const username = generateUsernameFromAddress(address);\n\n const loginResult = await mxLogin({\n homeServerUrl,\n username,\n password,\n deviceName,\n });\n\n return loginResult;\n } catch (error) {\n console.error('mxRegisterWithPasskey error:', error);\n throw error;\n }\n}\n\n/**\n * Register matrix account using the new API with secp256k1 signature authentication\n * @param address The user's address\n * @param password The matrix password\n * @param wallet The secp wallet for signing\n * @returns AuthResponse with access token and user details\n */\nexport async function mxRegisterWithSecp(\n address: string,\n password: string,\n deviceName: string,\n wallet: { sign: (message: string) => Promise<Uint8Array> },\n network: NETWORK\n): Promise<AuthResponse> {\n try {\n // Create challenge and sign it\n const { challengeBase64 } = createUserCreationChallenge(address);\n const signatureBytes = await wallet.sign(challengeBase64);\n const signature = Buffer.from(signatureBytes).toString('base64');\n\n const userCreationResult = await createUserAccountWithSecp(address, password, signature, challengeBase64, network);\n\n if (!userCreationResult.success) {\n throw new Error('Failed to create matrix account via API');\n }\n\n // Now login to get the access token\n const homeServerUrl = MatrixHomeServerUrl[network];\n const username = generateUsernameFromAddress(address);\n\n const loginResult = await mxLogin({\n homeServerUrl,\n username,\n password,\n deviceName,\n });\n\n return loginResult;\n } catch (error) {\n console.error('mxRegisterWithSecp error:', error);\n throw error;\n }\n}\n\n// =================================================================================================\n// UPDATED LEGACY REGISTRATION (DEPRECATED)\n// =================================================================================================\n\n// Keep the old functions for backward compatibility but mark as deprecated\nasync function getRegisterFlow(homeServerUrl: string) {\n try {\n const client = createTemporaryClient(homeServerUrl);\n // @ts-ignore\n const [registerResponse] = await Promise.allSettled([client.register()]);\n const registerFlow = registerResponse.status === 'rejected' ? registerResponse?.reason?.data : undefined;\n console.log('registerFlow', registerFlow);\n if (registerFlow === undefined) {\n throw new Error('Failed to setup home server config.');\n }\n return registerFlow;\n } catch (error) {\n if ((error as any).data) {\n console.log('registerFlow', (error as any).data);\n return (error as any).data;\n }\n throw new Error('Failed to get matrix register flow.');\n }\n}\n\nexport async function loginOrRegisterMatrixAccount({\n homeServerUrl,\n username,\n password,\n wallet,\n accessToken,\n deviceName,\n network,\n}: {\n homeServerUrl: string;\n username: string;\n password: string;\n accessToken?: string;\n wallet?: { sign: (message: string) => Promise<Uint8Array>; baseAccount: { address: string } };\n deviceName: string;\n network: NETWORK;\n}) {\n const isAuthenticated = !!accessToken;\n let isUsernameAvailable = await checkIsUsernameAvailable({ homeServerUrl, username });\n let res: AuthResponse | undefined;\n if (isUsernameAvailable && wallet) {\n // Use new API-based registration with secp256k1 authentication\n res = await mxRegisterWithSecp(wallet.baseAccount.address, password, deviceName, wallet, network);\n if (!res?.accessToken) {\n throw new Error('Failed to register matrix account');\n }\n console.log('mxRegisterWithSecp', res);\n }\n if (!isAuthenticated) {\n res = await mxLogin({\n homeServerUrl,\n username,\n password,\n deviceName,\n });\n if (!res?.accessToken) {\n throw new Error('Failed to login to matrix account');\n }\n console.log('mxLogin', res);\n }\n return res;\n}\n\nexport async function checkIsUsernameAvailable({\n homeServerUrl,\n username,\n}: {\n homeServerUrl: string;\n username: string;\n}) {\n const client = createTemporaryClient(homeServerUrl);\n try {\n const isUsernameAvailable = await client.isUsernameAvailable(username);\n return !!isUsernameAvailable;\n } catch (error) {\n return false;\n }\n}\n\n// =================================================================================================\n// CLIENT\n// =================================================================================================\n/**\n * Creates a temporary matrix client, used for matrix login or registration to get access tokens\n * @param homeServerUrl - the home server url to instantiate the matrix client\n * @returns matrix client\n */\nexport function createTemporaryClient(homeServerUrl: string) {\n if (!homeServerUrl) {\n throw new Error('Home server URL is required to instantiate matrix client');\n }\n return createClient({\n baseUrl: homeServerUrl,\n });\n}\n\nexport async function createMatrixClient({\n homeServerUrl,\n accessToken,\n userId,\n deviceId,\n}: {\n homeServerUrl: string;\n accessToken: string;\n userId: string;\n deviceId: string;\n}) {\n console.log('createMatrixClient::', { homeServerUrl, accessToken, userId, deviceId });\n\n if (!homeServerUrl || !accessToken || !userId || !deviceId) {\n throw new Error('Login to Matrix account before trying to instantiate Matrix client.');\n }\n\n // const indexedDBStore = new IndexedDBStore({\n // indexedDB: global.indexedDB,\n // dbName: 'matrix-sync-store',\n // });\n // const legacyCryptoStore = new IndexedDBCryptoStore()\n\n const mxClient = createClient({\n baseUrl: homeServerUrl,\n accessToken,\n userId,\n // store: indexedDBStore,\n // cryptoStore: legacyCryptoStore,\n deviceId,\n timelineSupport: true,\n cryptoCallbacks: {\n getSecretStorageKey: getSecretStorageKey,\n cacheSecretStorageKey: cacheSecretStorageKey,\n },\n verificationMethods: ['m.sas.v1'],\n });\n // await indexedDBStore.startup();\n await mxClient.initRustCrypto({\n useIndexedDB: false,\n });\n // mxClient.setGlobalErrorOnUnknownDevices(false);\n mxClient.setMaxListeners(20);\n // const filter = new Filter(userId);\n // filter.setDefinition({\n // room: {\n // state: {\n // lazy_load_members: true,\n // types: [],\n // },\n // timeline: {\n // types: [],\n // },\n // },\n // // Disable unnecessary features\n // presence: {\n // types: [], // No presence updates needed\n // },\n // account_data: {\n // types: ['m.cross_signing.master'], // No account data needed\n // },\n // });\n await mxClient.startClient({\n lazyLoadMembers: true,\n // initialSyncLimit: 1,\n includeArchivedRooms: false,\n // pollTimeout: 2 * 60 * 1000, // poll every 2 minutes\n // filter: filter,\n });\n await new Promise<void>((resolve, reject) => {\n const sync = {\n NULL: () => {\n console.info('[NULL] state');\n },\n SYNCING: () => {\n void 0;\n },\n PREPARED: () => {\n console.info(`[PREPARED] state: user ${userId}`);\n resolve();\n },\n RECONNECTING: () => {\n console.info('[RECONNECTING] state');\n },\n CATCHUP: () => {\n console.info('[CATCHUP] state');\n },\n ERROR: () => {\n reject(new Error('[ERROR] state: starting matrix client'));\n },\n STOPPED: () => {\n console.info('[STOPPED] state');\n },\n };\n mxClient.on(ClientEvent.Sync, (state) => {\n sync[state]();\n });\n });\n return mxClient;\n}\n\nexport async function logoutMatrixClient({\n mxClient,\n baseUrl,\n accessToken,\n userId,\n deviceId,\n}: {\n mxClient?: MatrixClient;\n baseUrl: string;\n accessToken: string;\n userId: string;\n deviceId: string;\n}) {\n let client = mxClient;\n if (!client) {\n client = createClient({\n baseUrl: baseUrl,\n accessToken,\n userId,\n deviceId,\n });\n }\n if (client) {\n client.stopClient();\n await client.logout().catch(console.error);\n client.clearStores();\n }\n}\n\n// =================================================================================================\n// CROSS SIGNING\n// =================================================================================================\n/**\n * Check if the user has cross-signing account data.\n * @param {MatrixClient} mxClient - The matrix client to check.\n * @returns {boolean} True if the user has cross-signing account data, otherwise false.\n */\nexport function hasCrossSigningAccountData(mxClient: MatrixClient): boolean {\n const masterKeyData = mxClient.getAccountData('m.cross_signing.master');\n console.log('hasCrossSigningAccountData::masterKeyData', masterKeyData);\n return !!masterKeyData;\n}\n\n/**\n * Setup cross signing and secret storage for the current user\n * @param {MatrixClient} mxClient - The matrix client to setup cross signing for\n * @param {string} securityPhrase - the security phrase to use for secret storage\n * @param {string} password - the password for the matrix account\n * @param {boolean} forceReset - if to force reset the cross signing keys (NB, only do if you know what you are doing!!!)\n * @param {boolean} skipBootstrapSS - if to skip bootstrapping secret storage\n * @returns {boolean} True if the cross signing was setup successfully, otherwise false.\n */\nexport async function setupCrossSigning(\n mxClient: MatrixClient,\n {\n securityPhrase,\n password,\n forceReset = false,\n skipBootstrapSecureStorage = false,\n }: { securityPhrase: string; password: string; forceReset?: boolean; skipBootstrapSecureStorage?: boolean }\n): Promise<boolean> {\n if (forceReset) {\n clearSecretStorageKeys();\n }\n\n const mxCrypto = mxClient.getCrypto() as CryptoApi;\n if (!mxCrypto) {\n throw new Error('Failed to setup matrix cross signing - failed to get matrix crypto api');\n }\n if (!skipBootstrapSecureStorage) {\n const recoveryKey = await mxCrypto.createRecoveryKeyFromPassphrase(securityPhrase);\n clearSecretStorageKeys();\n await mxCrypto.bootstrapSecretStorage({\n createSecretStorageKey: async () => recoveryKey!,\n setupNewSecretStorage: forceReset,\n });\n }\n const userId = mxClient.getUserId()!;\n await mxCrypto.bootstrapCrossSigning({\n authUploadDeviceSigningKeys: async function (makeRequest) {\n await makeRequest(getAuthId({ userId, password }));\n },\n setupNewCrossSigning: forceReset,\n });\n await mxCrypto.resetKeyBackup();\n\n await delay(300);\n\n return !!mxClient.getAccountData('m.cross_signing.master');\n}\n\n// =================================================================================================\n// GENERAL\n// =================================================================================================\n/**\n * Generates a username from an address, used for matrix login, generated an account did\n * @param {string} address - the address to generate the username from\n * @returns {string} username\n */\nexport function generateUsernameFromAddress(address: string): string {\n if (!address) {\n throw new Error('Address is required to generate matrix username');\n }\n return 'did-ixo-' + address;\n}\n\n/**\n * Generates a password from a mnemonic, used for matrix login, generated using the first 24 bytes of the base64 encoded md5 hash of the mnemonic\n * @param {string} mnemonic - the mnemonic to generate the password from\n * @returns {string} password\n */\nexport function generatePasswordFromMnemonic(mnemonic: string): string {\n const base64 = Buffer.from(md5(mnemonic.replace(/ /g, ''))).toString('base64');\n return base64.slice(0, 24);\n}\n\n/**\n * Generates a recovery phrase from a mnemonic, used for matrix recovery, generated using the first 32 bytes of the base64 encoded sha256 hash of the mnemonic\n * @param {string} mnemonic - the mnemonic to generate the recovery phrase from\n * @returns {string} recoveryPhrase\n */\nexport function generateRecoveryPhraseFromMnemonic(mnemonic: string): string {\n const hash = sha256(new TextEncoder().encode(mnemonic.replace(/ /g, '')));\n const base64 = Buffer.from(hash).toString('base64');\n return base64.slice(0, 32);\n}\n\n/**\n * Extracts the home server URL from a user ID.\n * @param {string} userId - The user ID to extract the homeserver URL from.\n * @returns {string} The homeserver URL.\n */\nexport function extractHomeServerUrlFromUserId(userId: string): string {\n const parts = userId.split(':');\n if (parts.length < 2) {\n throw new Error('Invalid userId');\n }\n return parts.slice(1).join(':');\n}\n\n/**\n * Generates a recovery phrase from a mnemonic, used for matrix recovery, generated using the first 32 bytes of the base64 encoded sha256 hash of the mnemonic\n * @param {string} mnemonic - the mnemonic to generate the recovery phrase from\n * @returns {string} passphrase\n */\nexport function generatePassphraseFromMnemonic(mnemonic: string): string {\n const hash = sha256(new TextEncoder().encode(mnemonic.replace(/ /g, '')));\n const base64 = Buffer.from(hash).toString('base64');\n return base64.slice(0, 32);\n}\n\n/**\n * Cleans a home server URL by removing protocol and trailing slashes\n * @param {string} homeServer - the homeserver URL to clean\n * @returns {string} cleaned homeserver URL\n */\nexport function cleanMatrixHomeServerUrl(homeServer: string): string {\n return homeServer.replace(/^(https?:\\/\\/)/, '').replace(/\\/$/, '');\n}\n\n/**\n * Generates a room name from an account address, used for matrix user room where user can manage their own data\n * @param {string} address - the address of the user\n * @param {string} postpend - the postpend of the room name (for testing)\n * @returns {string} roomName\n */\nexport function generateUserRoomNameFromAddress(address: string, postpend = ''): string {\n return 'did-ixo-' + address + postpend;\n}\n\n/**\n * Generates a room alias from an account address, used for matrix user room where user can manage their own data\n * @param {string} address - the address of the user\n * @param {string} postpend - the postpend of the room alias (for testing)\n * @returns {string} roomAlias\n */\nexport function generateUserRoomAliasFromAddress(address: string, homeServerUrl: string): string {\n return '#' + generateUserRoomNameFromAddress(address) + ':' + cleanMatrixHomeServerUrl(homeServerUrl);\n}\n\n/**\n * Get the base URL for a given servername.\n * @param servername The servername to get the base URL for.\n * @returns The base URL for the servername.\n */\nexport async function getBaseUrl(servername: string): Promise<string> {\n let protocol = 'https://';\n if (/^https?:\\/\\//.test(servername)) {\n protocol = '';\n }\n const serverDiscoveryUrl = `${protocol}${servername}${WELL_KNOWN_URI}`;\n try {\n const response = await fetch(serverDiscoveryUrl, { method: 'GET' });\n const result = await response.json();\n const baseUrl = (result as { 'm.homeserver': { base_url: string } })['m.homeserver']?.base_url;\n if (baseUrl === undefined) {\n throw new Error();\n }\n return baseUrl;\n } catch (e) {\n return `${protocol}${servername}`;\n }\n}\n\n/**\n * Normalize a username by removing leading '@' and trimming whitespace.\n * @param {string} rawUsername - The raw username to normalize.\n * @returns {string} The normalized username.\n */\nexport function normalizeUsername(rawUsername: string): string {\n const noLeadingAt = rawUsername.indexOf('@') === 0 ? rawUsername.substring(1) : rawUsername;\n return noLeadingAt.trim();\n}\n\n/**\n * Generates the authentication identifier for matrix login\n * @param {string} password - the password for the matrix account\n * @returns {object} authId - the authentication identifier\n */\nexport function getAuthId({ userId, password }: { userId: string; password: string }): {\n type: string;\n password: string;\n identifier: { type: string; user: string };\n} {\n return {\n type: 'm.login.password',\n password,\n identifier: {\n type: 'm.id.user',\n user: userId,\n },\n };\n}\n","const secretStorageKeys = new Map();\n\nexport function storePrivateKey(keyId: string, privateKey: Uint8Array) {\n if (privateKey instanceof Uint8Array === false) {\n throw new Error('Unable to store, privateKey is invalid.');\n }\n\n secretStorageKeys.set(keyId, privateKey);\n}\n\nexport function hasPrivateKey(keyId: string) {\n return secretStorageKeys.get(keyId) instanceof Uint8Array;\n}\n\nexport function getPrivateKey(keyId: string) {\n return secretStorageKeys.get(keyId);\n}\n\nexport function deletePrivateKey(keyId: string) {\n secretStorageKeys.delete(keyId);\n}\n\nexport function clearSecretStorageKeys() {\n secretStorageKeys.clear();\n}\n\nexport async function getSecretStorageKey({ keys }: { keys: any }): Promise<[string, Uint8Array] | null> {\n const keyIds = Object.keys(keys);\n const keyId = keyIds.find(hasPrivateKey);\n console.info('[] getSecretStorageKey', keys, keyIds, keyId);\n\n if (!keyId) {\n return null;\n }\n\n const privateKey = getPrivateKey(keyId);\n\n return [keyId, privateKey];\n}\n\nexport function cacheSecretStorageKey(keyId: string, keyInfo: any, privateKey: Uint8Array) {\n secretStorageKeys.set(keyId, privateKey);\n}\n","import { Bip39, EnglishMnemonic, Secp256k1, sha256, Slip10, Slip10Curve, stringToPath } from '@cosmjs/crypto';\nimport { AccountData, DirectSecp256k1HdWallet, OfflineSigner } from '@cosmjs/proto-signing';\nimport { createQueryClient, createSigningClient, customMessages, ixo, utils } from '@ixo/impactxclient-sdk';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { createCipheriv, randomBytes } from 'crypto';\nimport { CHAIN_RPC } from '../common';\nimport { decodeGrants, isAllowanceExpired, isAllowanceLimitReached } from './feegrant';\n/**\n * Checks if an iid document (did) exists\n * @param did - The did to check for\n * @returns True if the iid document exists, false otherwise\n */\nexport async function checkIidDocumentExists(did: string, network: NETWORK) {\n if (!network) {\n throw new Error('Network parameter is required but was undefined');\n }\n\n console.log(`🔍 Checking IID document for DID: ${did} on network: ${network}`);\n\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}. Valid networks are: ${Object.keys(CHAIN_RPC).join(', ')}`);\n }\n\n console.log(`🔗 Using RPC URL: ${url}`);\n\n try {\n const queryClient = await createQueryClient(url);\n const iidDocumentResponse = await queryClient.ixo.iid.v1beta1.iidDocument({ id: did });\n if (!iidDocumentResponse?.iidDocument?.id) {\n return false;\n }\n return true;\n } catch (error) {\n if ((error as Error).message?.includes('did document not found') || (error as Error).message?.includes('(22)')) {\n return false;\n }\n console.error('Error checking IID document:', error);\n throw error;\n }\n}\n\n/**\n * Creates an iid document (did)\n * Must be signed by base account mnemonic (not passkey signer)\n * @param did - The did to create iid document for\n * @param offlineSigner - The offline signer to use to create iid document\n */\nexport async function createIidDocument(did: string, network: NETWORK, offlineSigner: OfflineSigner) {\n try {\n const accounts = await offlineSigner.getAccounts();\n const { address, pubkey } = (accounts[0] ?? {}) as AccountData;\n const allowances = await queryAddressAllowances(address, network);\n const feegrantGranter = allowances?.length\n ? decodeGrants(allowances)?.find(\n (allowance) =>\n !!allowance &&\n !isAllowanceExpired(allowance.expiration as number) &&\n !isAllowanceLimitReached(allowance.limit)\n )?.granter\n : undefined;\n const trx = {\n typeUrl: '/ixo.iid.v1beta1.MsgCreateIidDocument',\n value: ixo.iid.v1beta1.MsgCreateIidDocument.fromPartial({\n id: did,\n verifications: customMessages.iid.createIidVerificationMethods({\n did: did,\n pubkey: pubkey,\n address: address,\n controller: did,\n type: 'secp',\n }),\n signer: address,\n controllers: [did],\n }),\n };\n // if (!feegrantGranter) {\n // throw new Error('No feegrant granter found');\n // }\n await signAndBroadcastWithMnemonic({\n offlineSigner: offlineSigner,\n messages: [trx],\n feegrantGranter: feegrantGranter as string,\n network,\n });\n } catch (error) {\n console.error(error);\n throw error;\n }\n}\n\nexport async function queryAddressAllowances(address: string, network: NETWORK) {\n try {\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}`);\n }\n const queryClient = await createQueryClient(url);\n const allowancesResponse = await queryClient.cosmos.feegrant.v1beta1.allowances({\n grantee: address,\n });\n return allowancesResponse?.allowances ?? [];\n } catch (error) {\n console.error('queryAddressAllowances::', (error as Error).message);\n return undefined;\n }\n}\n\n/**\n * Signs and broadcasts a transaction with a mnemonic\n * @param offlineSigner - The offline signer\n * @param messages - The messages to sign and broadcast\n * @param memo - The memo for the transaction\n * @param feegrantGranter - The granter for the transaction\n * @returns The deliver tx response\n */\nexport const signAndBroadcastWithMnemonic = async ({\n offlineSigner,\n messages,\n memo = 'Signing with Mnemonic Demo',\n feegrantGranter,\n network,\n}: {\n offlineSigner: OfflineSigner;\n messages: any[];\n memo?: string;\n feegrantGranter: string;\n network: NETWORK;\n}) => {\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}`);\n }\n const signingClient = await createSigningClient(url, offlineSigner);\n const accounts = await offlineSigner.getAccounts();\n const { address } = (accounts[0] ?? {}) as AccountData;\n\n const simGas = await signingClient.simulate(address, messages, memo);\n const gasUsed = simGas > 50000 ? simGas : (messages ?? []).length * 500000;\n const gas = gasUsed * 1.7;\n const gasOptions = calculateTrxGasOptions(gas);\n const fee = {\n amount: [\n {\n denom: 'uixo',\n amount: String(Math.round(gasOptions.average)),\n },\n ],\n gas: String(Math.round(gas)),\n granter: feegrantGranter,\n };\n const result = await signingClient.signAndBroadcast(address, messages, fee, memo, undefined);\n const isDeliverTxFailure = !!result.code;\n if (isDeliverTxFailure) {\n throw new Error(\n `Error when broadcasting tx ${result.transactionHash} at height ${result.height}. Code: ${result.code}; Raw log: ${result.rawLog}`\n );\n }\n};\n\nconst calculateTrxGasOptions = (gasUsed: number) => {\n const gasPriceStep = {\n low: 0.02,\n average: 0.035,\n high: 0.045,\n };\n const gas = gasUsed < 0.01 ? 0.01 : gasUsed;\n const gasOptions = {\n low: gas * gasPriceStep.low,\n average: gas * gasPriceStep.average,\n high: gas * gasPriceStep.high,\n };\n\n return gasOptions;\n};\n\nexport const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport function encrypt(text: string, password: string) {\n const iv = randomBytes(16);\n\n const cipher = createCipheriv('aes-256-cbc', Buffer.from(password.padEnd(32)), iv);\n let encrypted = cipher.update(text);\n encrypted = Buffer.concat([encrypted, cipher.final()]);\n return iv.toString('hex') + ':' + encrypted.toString('hex');\n}\n\nexport type SecpClient = Awaited<ReturnType<typeof getSecpClient>>;\nexport const getSecpClient = async (mnemonic: string) => {\n const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {\n prefix: 'ixo',\n });\n const account = (await wallet.getAccounts())[0];\n\n // Debug: Derive and verify keys manually for comparison\n const seed = await Bip39.mnemonicToSeed(new EnglishMnemonic(mnemonic));\n const hdPath = stringToPath(\"m/44'/118'/0'/0/0\");\n const slip10Result = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath);\n const privkey = slip10Result.privkey;\n // Derive the compressed public key from the private key\n const keypair = await Secp256k1.makeKeypair(privkey);\n const compressedPubkey = Secp256k1.compressPubkey(keypair.pubkey);\n // Log keys and addresses for comparison\n // console.log({\n // walletPubkey: account!.pubkey ? Buffer.from(account!.pubkey).toString('hex') : 'not available',\n // derivedPubkey: Buffer.from(compressedPubkey).toString('hex'),\n // });\n\n const secpClient = {\n mnemonic,\n did: utils.did.generateSecpDid(account!.address),\n baseAccount: account!,\n\n async getAccounts() {\n return (await wallet.getAccounts()) as AccountData[];\n },\n\n async signDirect(signerAddress: any, signDoc: any) {\n return await wallet.signDirect(signerAddress, signDoc);\n },\n\n /**\n * Sign a message with the secp256k1 private key derived from the mnemonic\n * @param message - The message to sign (usually a challenge string - base64 encoded)\n * @returns The signature as a Uint8Array\n */\n async sign(message: string): Promise<Uint8Array> {\n // Use the wallet's signDirect method to ensure consistent signing\n try {\n // Derive keypair from mnemonic directly\n const seed = await Bip39.mnemonicToSeed(new EnglishMnemonic(mnemonic));\n\n // NOTE: need to do checking here if it produces matched address to signed in one, maybe user is using a different derivation path\n // Use the standard Cosmos HD path (m/44'/118'/0'/0/0)\n const hdPath = stringToPath(\"m/44'/118'/0'/0/0\");\n\n // Derive the private key using SLIP-10\n const { privkey } = Slip10.derivePath(Slip10Curve.Secp256k1, seed, hdPath);\n\n // For the challenge (base64 encoded string), decode to get the original bytes\n const challengeBytes = new Uint8Array(Buffer.from(message, 'base64'));\n\n // Hash the challenge bytes using SHA-256\n const messageHash = sha256(challengeBytes);\n\n // Sign the hash with the derived private key\n const signature = await Secp256k1.createSignature(messageHash, privkey);\n\n // Get the fixed-length signature, which is r (32 bytes) | s (32 bytes) | recovery param (1 byte)\n const fixedLengthSignature = signature.toFixedLength();\n\n // Remove the recovery parameter byte (last byte) to get only r and s\n // This gives us exactly 64 bytes which is what the verification expects\n return fixedLengthSignature.slice(0, 64);\n } catch (error) {\n console.error('Error during signature creation:', error);\n throw error;\n }\n },\n };\n\n return secpClient;\n};\n","import { Coin, DecodeObject } from '@cosmjs/proto-signing';\nimport { createQueryClient, createRegistry, utils } from '@ixo/impactxclient-sdk';\nimport { Grant } from '@ixo/impactxclient-sdk/types/codegen/cosmos/feegrant/v1beta1/feegrant';\nimport { Timestamp } from '@ixo/impactxclient-sdk/types/codegen/google/protobuf/timestamp';\n\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { CHAIN_RPC } from '../common';\n\n/**\n * Converts a timestamp object to a timestamp\n * @param timestamp - The timestamp object to convert\n * @returns The timestamp\n */\nexport function convertTimestampObjectToTimestamp(timestamp: Timestamp): number | undefined {\n try {\n const date = utils.proto.fromTimestamp(timestamp);\n\n return date.getTime();\n } catch (error) {\n return undefined;\n }\n}\n\nexport enum FeegrantTypes {\n BASIC_ALLOWANCE = 'BasicAllowance',\n PERIODIC_ALLOWANCE = 'PeriodicAllowance',\n}\n\nexport const FEEGRANT_TYPES: Record<FeegrantTypes, string> = {\n BasicAllowance: '/cosmos.feegrant.v1beta1.BasicAllowance',\n PeriodicAllowance: '/cosmos.feegrant.v1beta1.PeriodicAllowance',\n};\n\n/**\n * Queries the address allowances from the IXO blockchain\n * @param address - The address to query allowances for\n * @returns The allowances for the address\n */\nexport async function queryAddressAllowances(address: string, network: NETWORK) {\n try {\n const url = CHAIN_RPC[network];\n if (!url) {\n throw new Error(`Invalid network: ${network}`);\n }\n const queryClient = await createQueryClient(url);\n const allowancesResponse = await queryClient.cosmos.feegrant.v1beta1.allowances({\n grantee: address,\n });\n return allowancesResponse?.allowances ?? [];\n } catch (error) {\n console.error('queryAddressAllowances::', (error as Error).message);\n return undefined;\n }\n}\n\n/**\n * Checks if the address has a valid feegrant (not expired yet and limit not reached yet)\n * @param address - The address to check feegrant for\n * @returns True if the address has a valid feegrant, false otherwise\n */\nexport async function checkAddressFeegrant(address: string, network: NETWORK) {\n try {\n const allowancesResponse = await queryAddressAllowances(address, network);\n console.log('allowancesResponse', allowancesResponse);\n if (!allowancesResponse?.length) {\n return false;\n }\n const allowances = decodeGrants(allowancesResponse);\n return allowances.some(\n (allowance) =>\n !!allowance && !isAllowanceExpired(allowance.expiration as number) && !isAllowanceLimitReached(allowance.limit)\n );\n } catch (error) {\n console.error('checkAddressFeegrant::', (error as Error).message);\n throw error;\n }\n}\n\n/**\n * Decodes the grant values from the the user's list of allowances\n * @param grants - The grants to decode\n * @returns The decoded grants\n */\nexport const decodeGrants = (grants: Grant[]) => {\n const registry = createRegistry();\n\n return (grants ?? []).map((grant) => {\n const allowance = grant.allowance as DecodeObject;\n const decodedAllowance = registry.decode(allowance);\n // decodedAllowance.\n switch (allowance.typeUrl) {\n case FEEGRANT_TYPES.BasicAllowance:\n return {\n granter: grant.granter,\n grantee: grant.grantee,\n type: FEEGRANT_TYPES.BasicAllowance,\n expiration: decodedAllowance.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.expiration)\n : null,\n limit: decodedAllowance.spendLimit?.length\n ? decodedAllowance.spendLimit.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : null,\n msgs: [],\n };\n case FEEGRANT_TYPES.PeriodicAllowance:\n return {\n granter: grant.granter,\n grantee: grant.grantee,\n type: FEEGRANT_TYPES.PeriodicAllowance,\n expiration: decodedAllowance.basic?.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.basic.expiration)\n : null,\n limit: decodedAllowance?.periodCanSpend\n ? decodedAllowance?.periodCanSpend?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : decodedAllowance?.basic?.spendLimit?.length\n ? decodedAllowance?.basic?.spendLimit?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : null,\n msgs: [],\n };\n default:\n return {\n type: allowance.typeUrl,\n granter: grant.granter,\n grantee: grant.grantee,\n expiration: decodedAllowance.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.expiration)\n : decodedAllowance.basic?.expiration\n ? convertTimestampObjectToTimestamp(decodedAllowance.basic.expiration)\n : null,\n limit: decodedAllowance.spendLimit?.length\n ? decodedAllowance.spendLimit.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : decodedAllowance?.periodCanSpend\n ? decodedAllowance?.periodCanSpend?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : decodedAllowance?.basic?.spendLimit?.length\n ? decodedAllowance?.basic?.spendLimit?.find((limit: Coin) => limit.denom === 'uixo')?.amount\n : null,\n msgs: decodedAllowance.allowedMessages,\n };\n }\n });\n};\n\n/**\n * Checks if the allowance has expired\n * @param expiration - The expiration of the allowance\n * @returns True if the allowance has expired, false otherwise\n */\nexport const isAllowanceExpired = (expiration: number | Timestamp) => {\n if (expiration === null || expiration === undefined) {\n return false;\n }\n const expirationTimestamp =\n typeof expiration === 'object' ? convertTimestampObjectToTimestamp(expiration) : expiration;\n if (expirationTimestamp === undefined || expirationTimestamp === null) {\n // failed to decode or convert - assume expired\n return true;\n }\n return expirationTimestamp < Date.now();\n};\n\n/**\n * Checks if the allowance limit has been reached\n * @param limit - The limit of the allowance\n * @returns True if the allowance limit has been reached, false otherwise\n */\nexport const isAllowanceLimitReached = (limit: number | string | Coin) => {\n if (limit === null || limit === undefined) {\n return false;\n }\n const limitAmount =\n typeof limit === 'object' ? Number(limit?.amount ?? 0) : typeof limit === 'string' ? Number(limit ?? 0) : limit;\n return limitAmount <= 0.0005;\n};\n","import { createMatrixApiClient, utils as mxUtils } from '@ixo/matrixclient-sdk';\nimport { UploadContentType } from '@ixo/matrixclient-sdk/types/api/media/v1beta1';\nimport { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { MatrixHomeServerUrl } from '../common';\nimport { createCIDFromBase64, jsonToBase64 } from '../createCIDFromBase64';\nimport { RuntimeConfig } from '../runtime-config';\nimport { Wallet } from '../wallet';\n\nexport const publicUpload = async ({\n data,\n fileName,\n config,\n wallet,\n}: {\n data: object;\n fileName: string;\n config: RuntimeConfig;\n wallet: Wallet;\n}) => {\n const matrixAPIClient = createMatrixApiClient({\n homeServerUrl: MatrixHomeServerUrl[(config.getValue('network') as NETWORK) ?? 'devnet'],\n accessToken: wallet?.matrix?.accessToken ?? '',\n });\n\n // Create a simple Buffer instead of using File - this works reliably with node-fetch\n const fileContent = JSON.stringify(data);\n const fileBuffer = Buffer.from(fileContent, 'utf8');\n const fullFileName = fileName + '.json';\n const contentType = 'application/ld+json';\n\n // Pass the buffer directly - node-fetch can handle this reliably in all environments\n const response = await matrixAPIClient.media.v1beta1.upload(\n fullFileName,\n contentType as UploadContentType,\n fileBuffer\n );\n const httpUrl = mxUtils.mxc.mxcUrlToHttp(\n MatrixHomeServerUrl[(config.getValue('network') as NETWORK) ?? 'devnet'], // homeServerUrl\n response.content_uri // the mxc url\n );\n\n if (!httpUrl) {\n throw new Error('Failed to upload file to Matrix');\n }\n\n const jsonString = JSON.stringify(data);\n const base64String = jsonToBase64(jsonString);\n const cid = await createCIDFromBase64(base64String);\n\n return {\n encrypted: 'false',\n cid,\n proof: cid,\n serviceEndpoint: httpUrl,\n mxc: response.content_uri,\n };\n};\n","import { CID } from 'multiformats';\nimport { base64 } from 'multiformats/bases/base64';\nimport * as mfsha2 from 'multiformats/hashes/sha2';\n\nexport async function createCIDFromBase64(base64String: string): Promise<string> {\n // Add 'm' prefix if not present\n const multibaseString = base64String.startsWith('m') ? base64String : 'm' + base64String;\n\n // Decode base64 to bytes\n const bytes = base64.decode(multibaseString);\n\n // Create SHA-256 hash of the bytes\n const hash = await mfsha2.sha256.digest(bytes);\n\n // Create CID (using SHA-256 and RAW codec)\n const cid = CID.create(1, 0x55, hash);\n\n return cid.toString();\n}\n\nexport function jsonToBase64(jsonString: string): string {\n const uint8Array = new TextEncoder().encode(jsonString);\n return btoa(String.fromCharCode(...Array.from(uint8Array)));\n}\n","import { CLIResult } from '../types';\nimport { Command, CommandRegistry } from './index';\n\nexport class HelpCommand implements Command {\n name = 'help';\n description = 'Show help information and available commands';\n\n constructor(private registry: CommandRegistry) {}\n\n async execute(): Promise<CLIResult> {\n const commands = this.registry.getAll();\n\n const helpText = `\nIXO Oracles CLI - Help\n\nUSAGE:\n oracles-cli [command] [options]\n\nCOMMANDS:\n${commands.map((cmd) => ` ${cmd.name.padEnd(15)} ${cmd.description}`).join('\\n')}\n\nEXAMPLES:\n oracles-cli --init Initialize a new IXO Oracle project\n oracles-cli Launch interactive menu\n oracles-cli help Show this help message\n\nOPTIONS:\n --init Initialize a new project (shortcut)\n --help, -h Show help information\n\nFor more information, visit: https://github.com/ixoworld/ixo-oracles-cli\n`;\n\n return {\n success: true,\n data: helpText,\n };\n }\n}\n","import * as p from '@clack/prompts';\nimport { existsSync } from 'fs';\nimport path from 'path';\nimport simpleGit from 'simple-git';\nimport { Command } from '.';\nimport { CLIResult } from '../types';\nimport { createProjectEnvFile } from '../utils/create-project-env-file';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { Wallet } from '../utils/wallet';\nimport { CreateEntityCommand } from './create-entity-command';\n\nexport class InitCommand implements Command {\n name = 'init';\n description = 'Initialize Project';\n\n constructor(private readonly config: RuntimeConfig, private readonly wallet: Wallet) {}\n\n private async getProjectInput(): Promise<{ projectPath: string; projectName: string }> {\n // Get the input from user (could be path, name, or both)\n const input = await p.text({\n message: 'What is your project named?',\n placeholder: 'my-ixo-project',\n validate(value) {\n if (!value) {\n return 'Project name is required';\n }\n return undefined;\n },\n });\n\n if (p.isCancel(input)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n // Parse the input to determine if it's a path, name, or both\n const inputStr = String(input);\n let projectPath: string;\n let projectName: string;\n\n // Check if input contains path separators (is a path)\n if (inputStr.includes('/') || inputStr.includes('\\\\')) {\n // Input is a path\n projectPath = inputStr;\n projectName = path.basename(inputStr);\n } else {\n // Input is just a name, create in current directory\n projectName = inputStr;\n projectPath = path.join(process.cwd(), projectName);\n }\n\n // Ensure the project name is valid\n if (!this.isValidProjectName(projectName)) {\n p.note('Invalid project name. Using a valid name instead.', 'Warning');\n projectName = this.sanitizeProjectName(projectName);\n projectPath = path.join(path.dirname(projectPath), projectName);\n }\n\n return { projectPath, projectName };\n }\n\n private isValidProjectName(name: string): boolean {\n // Check if name is valid (no special characters, starts with letter, etc.)\n const validNameRegex = /^[a-zA-Z][a-zA-Z0-9-_]*$/;\n return validNameRegex.test(name) && name.length > 0 && name.length <= 50;\n }\n\n private sanitizeProjectName(name: string): string {\n // Convert invalid characters to valid ones\n return name\n .replace(/[^a-zA-Z0-9-_]/g, '-')\n .replace(/^-+|-+$/g, '') // Remove leading/trailing dashes\n .toLowerCase()\n .substring(0, 50);\n }\n\n private async confirmProjectCreation(projectPath: string, projectName: string): Promise<boolean> {\n const isDirExists = existsSync(projectPath);\n\n if (isDirExists) {\n const overwrite = await p.confirm({\n message: `Directory \"${projectPath}\" already exists. Do you want to overwrite it?`,\n initialValue: false,\n });\n\n if (p.isCancel(overwrite)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n return overwrite;\n }\n\n // Show confirmation for new project\n const confirm = await p.confirm({\n message: `Create IXO project \"${projectName}\" in \"${projectPath}\"?`,\n initialValue: true,\n });\n\n if (p.isCancel(confirm)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n return confirm;\n }\n\n private async selectRepo() {\n const repo = await p.select({\n message: 'Select a template to clone',\n options: [\n {\n value: 'git@github.com:ixoworld/ixo-oracles-boilerplate.git',\n label: 'IXO Oracles (Default)',\n },\n {\n label: 'Custom template',\n value: 'custom',\n },\n ],\n });\n\n if (p.isCancel(repo)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n if (repo === 'custom') {\n const customRepo = await p.text({\n message: 'Enter the custom template URL',\n });\n\n if (p.isCancel(customRepo)) {\n p.cancel('Operation cancelled.');\n process.exit(0);\n }\n\n return customRepo;\n }\n\n return repo;\n }\n\n private async cloneRepo(repo: string, projectPath: string, shouldOverwrite: boolean = false) {\n const git = simpleGit();\n const cloneSpinner = p.spinner();\n\n try {\n cloneSpinner.start('Cloning repository...');\n\n // If overwriting, remove the existing directory first\n if (shouldOverwrite && existsSync(projectPath)) {\n const { rmSync } = await import('fs');\n rmSync(projectPath, { recursive: true, force: true });\n }\n\n // Create directory if it doesn't exist\n\n await git.clone(repo, projectPath);\n\n // Clean repo and create new git\n const gitFolder = path.join(projectPath, '.git');\n if (existsSync(gitFolder)) {\n const { rmSync } = await import('fs');\n rmSync(gitFolder, { recursive: true, force: true });\n }\n await simpleGit(projectPath).init();\n\n cloneSpinner.stop('Repository cloned successfully');\n\n p.log.info('Creating Oracle Entity and Matrix Account');\n const command = new CreateEntityCommand(this.wallet, this.config);\n const result = await command.execute();\n if (result.success) {\n p.log.info('Oracle Entity and Matrix Account created successfully');\n } else {\n p.log.error('Failed to create Oracle Entity and Matrix Account');\n }\n\n await createProjectEnvFile(this.config);\n // Show success message with next steps\n p.log.success(\n `\\n✅ IXO project created successfully!\\n\\n` +\n `📁 Location: ${projectPath}\\n` +\n `🚀 Next steps:\\n` +\n ` cd ${path.basename(projectPath)}\\n` +\n ` pnpm install\\n` +\n ` pnpm build \\n` +\n ` cd apps/app\\n` +\n ` pnpm start:dev`\n );\n } catch (error) {\n cloneSpinner.stop('Failed to clone repository');\n throw error;\n }\n }\n\n async execute(): Promise<CLIResult> {\n try {\n // Get project input (path and/or name)\n const { projectPath, projectName } = await this.getProjectInput();\n\n // Confirm project creation\n const shouldProceed = await this.confirmProjectCreation(projectPath, projectName);\n\n if (!shouldProceed) {\n return { success: false, data: 'Project creation cancelled' };\n }\n\n // Store in config\n this.config.addValue('projectPath', projectPath);\n this.config.addValue('projectName', projectName);\n\n // Select repository template\n const repo = await this.selectRepo();\n this.config.addValue('repo', repo);\n\n // Check if we need to overwrite\n const shouldOverwrite = existsSync(projectPath);\n\n // Clone the repository\n await this.cloneRepo(repo, projectPath, shouldOverwrite);\n\n return {\n success: true,\n data: `Project \"${projectName}\" created successfully in \"${projectPath}\"`,\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? error.message : 'Unknown error occurred',\n };\n }\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { mxLogin } from './account/matrix';\nimport { MatrixHomeServerUrl } from './common';\nimport { RuntimeConfig } from './runtime-config';\nexport const createProjectEnvFile = async (config: RuntimeConfig) => {\n const freshMx = await mxLogin({\n homeServerUrl: MatrixHomeServerUrl[config.getOrThrow('network')],\n username: config.getOrThrow('registerUserResult').matrixUserId,\n password: config.getOrThrow('registerUserResult').matrixPassword,\n deviceName: config.getOrThrow('registerUserResult').matrixDeviceName,\n });\n const network = config.getOrThrow('network');\n const projectPath = config.getOrThrow('projectPath');\n const envFile = path.join(projectPath, 'apps', 'app', '.env');\n\n console.log('Creating .env file at:', envFile);\n console.log('Project path:', projectPath);\n\n // Ensure the directory exists\n const envDir = path.dirname(envFile);\n if (!fs.existsSync(envDir)) {\n console.log('Creating directory:', envDir);\n fs.mkdirSync(envDir, { recursive: true });\n }\n const envContent = `\nPORT=4000 \nORACLE_NAME=${config.getValue('projectName')}\n\n# Matrix\nMATRIX_BASE_URL=${MatrixHomeServerUrl[network]}\nMATRIX_ORACLE_ADMIN_ACCESS_TOKEN=${freshMx.accessToken}\nMATRIX_ORACLE_ADMIN_PASSWORD=${config.getOrThrow('registerUserResult').matrixPassword}\nMATRIX_ORACLE_ADMIN_USER_ID=${config.getOrThrow('registerUserResult').matrixUserId}\nMATRIX_RECOVERY_PHRASE=${config.getOrThrow('registerUserResult').matrixRecoveryPhrase}\n\n# OPENAI\nOPENAI_API_KEY=\n\n# Langfuse\nLANGFUSE_PUBLIC_KEY=\nLANGFUSE_SECRET_KEY=\nLANGFUSE_HOST=https://cloud.langfuse.com\n\nOPEN_ROUTER_API_KEY=\"sk-\"\n\n\n### NOT REQUIRED FOR THE APP BUT SAVE THEM IN SAFE PLACE\n# ORACLE ACCOUNT DETAILS\nORACLE_ADDRESS=${config.getOrThrow('registerUserResult').address}\nORACLE_DID=${config.getOrThrow('registerUserResult').did}\nORACLE_MNEMONIC=${config.getOrThrow('registerUserResult').mnemonic}\nMATRIX_VAULT_PIN=${config.getOrThrow('registerUserResult').pin}\nENTITY_DID=${config.getOrThrow('entityDid')}\n`;\n try {\n fs.writeFileSync(envFile, envContent);\n console.log('✅ .env file created successfully at:', envFile);\n } catch (error) {\n console.error('❌ Failed to create .env file:', error);\n throw error;\n }\n};\n","import { confirm } from '@clack/prompts';\nimport { CLIResult } from '../types';\nimport { Wallet } from '../utils/wallet';\nimport { Command } from './index';\n\nexport class LogoutCommand implements Command {\n name = 'logout';\n description = 'Logout command';\n\n constructor(private wallet: Wallet) {}\n\n async execute(): Promise<CLIResult> {\n const shouldClear = await confirm({\n message: 'Are you sure you want to logout?',\n initialValue: false,\n });\n if (shouldClear) {\n await this.wallet.clearWallet();\n return {\n success: true,\n data: 'Logged out successfully',\n };\n }\n return {\n success: false,\n error: 'Logout cancelled',\n };\n }\n}\n","'use server';\nimport { toHex } from '@cosmjs/encoding';\nimport { EncodeObject } from '@cosmjs/proto-signing';\nimport { createRegistry } from '@ixo/impactxclient-sdk';\nimport {\n SignX as IxoSignX,\n SIGN_X_LOGIN_ERROR,\n SIGN_X_LOGIN_SUCCESS,\n SIGN_X_TRANSACT_ERROR,\n SIGN_X_TRANSACT_SUCCESS,\n} from '@ixo/signx-sdk';\nimport { LOGIN_DATA } from '@ixo/signx-sdk/types/types/transact';\nimport qrcode from 'qrcode-terminal';\nimport { WalletProps } from './types';\n\nconst SignXEndpoints = {\n devnet: 'https://signx.devnet.ixo.earth',\n testnet: 'https://signx.testnet.ixo.earth',\n mainnet: 'https://signx.ixo.earth',\n};\n\nexport class SignXClient {\n private readonly signXClient: IxoSignX;\n private _loginData?: LOGIN_DATA;\n public get loginData() {\n return this._loginData;\n }\n\n static loadFromWallet(wallet: WalletProps) {\n return new IxoSignX({\n endpoint: SignXEndpoints[wallet.network],\n sitename: 'IXO Oracles CLI',\n network: wallet.network,\n });\n }\n\n constructor(chainNetwork: keyof typeof SignXEndpoints) {\n this.signXClient = new IxoSignX({\n endpoint: SignXEndpoints[chainNetwork],\n sitename: 'IXO Oracles CLI',\n network: chainNetwork,\n });\n }\n\n async login() {\n const loginData = await this.signXClient.login({ pollingInterval: 2000, matrix: true });\n this._loginData = loginData;\n return loginData;\n }\n\n private displayStyledQRCode(qrCodeData: string | LOGIN_DATA, title: string) {\n const qrCodeStr = typeof qrCodeData === 'string' ? qrCodeData : JSON.stringify(qrCodeData);\n\n // Display title with emoji\n console.log('\\n' + ' '.repeat(5) + '🔐 ' + title);\n console.log(' '.repeat(5) + '📱 Scan with IXO app');\n console.log(' '.repeat(5) + '━'.repeat(30));\n\n // Generate very compact QR code\n qrcode.generate(qrCodeStr, {\n small: true,\n });\n console.log(' '.repeat(5) + '⏳ Waiting...\\n');\n }\n\n public displayQRCode(qrCodeData: string | LOGIN_DATA) {\n this.displayStyledQRCode(qrCodeData, 'Login with SignX');\n }\n\n async awaitLogin() {\n return new Promise<WalletProps>((resolve, reject) => {\n try {\n this.signXClient.on(SIGN_X_LOGIN_SUCCESS, async (response: { data: WalletProps }) => {\n resolve(response.data); // Resolve the promise with the login success data\n });\n\n this.signXClient.on(SIGN_X_LOGIN_ERROR, (error) => {\n console.log('Login error:', error);\n reject(error); // Reject the promise with the login error\n });\n\n // Use loginRequest data to show QR code to user for scanning by mobile app\n } catch (error) {\n console.error('Error in connecting:', error);\n reject(error); // Reject the promise with any other errors\n }\n });\n }\n\n async transact(messages: readonly EncodeObject[], wallet: WalletProps, memo?: string) {\n const registry = createRegistry();\n\n return this.signXClient.transact({\n address: wallet.address,\n did: wallet.did,\n pubkey: wallet.pubKey,\n timestamp: new Date().toISOString(),\n transactions: [\n {\n sequence: 1,\n txBodyHex: toHex(registry.encodeTxBody({ messages: messages, memo: memo || '' })),\n },\n ],\n });\n }\n\n async awaitTransaction() {\n return new Promise((resolve, reject) => {\n try {\n this.signXClient.on(SIGN_X_TRANSACT_SUCCESS, (result) => {\n resolve(result.data); // Resolve the promise with the login success data\n });\n\n this.signXClient.on(SIGN_X_TRANSACT_ERROR, (error) => {\n reject(error); // Reject the promise with the login error\n });\n // Use loginRequest data to show QR code to user for scanning by mobile app\n } catch (error) {\n console.error('Error in connecting:', error);\n reject(error); // Reject the promise with any other errors\n }\n });\n }\n\n async pollNextTransaction() {\n return this.signXClient.pollNextTransaction();\n }\n\n displayTransactionQRCode(qrCodeData: string) {\n this.displayStyledQRCode(qrCodeData, 'SIGNX TRANSACTION');\n }\n}\n","import { CLIResult } from '../types';\nimport { selectNetwork } from '../utils/common';\nimport { RuntimeConfig } from '../utils/runtime-config';\nimport { SignXClient } from '../utils/signx/signx';\nimport { Wallet } from '../utils/wallet';\nimport { Command } from './index';\n\nexport class SignXLoginCommand implements Command {\n name = 'signx-login';\n description = 'Login with SignX wallet';\n\n constructor(private wallet: Wallet, private config: RuntimeConfig) {}\n\n async execute(): Promise<CLIResult> {\n try {\n // Select network and create SignX client\n const network = await selectNetwork(this.config);\n const signXClient = new SignXClient(network);\n\n // Start login process\n const loginData = await signXClient.login();\n\n // Display QR code for user to scan\n signXClient.displayQRCode(loginData);\n\n // Wait for login completion\n const loginResult = await signXClient.awaitLogin();\n this.wallet.setWallet(loginResult);\n this.wallet.setSignXClient(signXClient);\n return {\n success: true,\n data: {\n message: 'Successfully logged in with SignX!',\n wallet: {\n address: loginResult.address,\n did: loginResult.did,\n name: loginResult.name,\n },\n },\n };\n } catch (error) {\n return {\n success: false,\n error: error instanceof Error ? `SignX login failed: ${error.message}` : 'Unknown error',\n };\n }\n }\n}\n","export class CLIError extends Error {\n constructor(message: string, public code: string = 'CLI_ERROR', public suggestions?: string[]) {\n super(message);\n this.name = 'CLIError';\n }\n}\n\nexport class ConfigError extends CLIError {\n constructor(message: string, suggestions?: string[]) {\n super(message, 'CONFIG_ERROR', suggestions);\n this.name = 'ConfigError';\n }\n}\n\nexport class NetworkError extends CLIError {\n constructor(message: string, suggestions?: string[]) {\n super(message, 'NETWORK_ERROR', suggestions);\n this.name = 'NetworkError';\n }\n}\n\nexport class ValidationError extends CLIError {\n constructor(message: string, suggestions?: string[]) {\n super(message, 'VALIDATION_ERROR', suggestions);\n this.name = 'ValidationError';\n }\n}\n\nexport function handleError(error: unknown): never {\n if (error instanceof CLIError) {\n console.error(`\\n❌ ${error.name}: ${error.message}`);\n if (error.suggestions?.length) {\n console.error('\\nSuggestions:');\n error.suggestions.forEach((suggestion) => console.error(` • ${suggestion}`));\n }\n process.exit(1);\n }\n\n if (error instanceof Error) {\n console.error(`\\n❌ Unexpected Error: ${error.message}`);\n if (error.stack) {\n console.error('\\nStack trace:');\n console.error(error.stack);\n }\n process.exit(1);\n }\n\n console.error('\\n❌ Unknown error occurred');\n process.exit(1);\n}\n","import { NETWORK } from '@ixo/signx-sdk/types/types/transact';\nimport { SimplifiedRegistrationResult } from './account/simplifiedRegistration';\n\ninterface Config {\n authZFile: string;\n feesFile: string;\n projectPath: string;\n projectName: string;\n entityDid: string;\n network: NETWORK;\n repo: string;\n registerUserResult: SimplifiedRegistrationResult & {\n matrixDeviceName: string;\n };\n}\n\nexport class RuntimeConfig {\n private config: Partial<Config> = {};\n private static instance: RuntimeConfig;\n private constructor() {}\n\n public static getInstance(): RuntimeConfig {\n if (!RuntimeConfig.instance) {\n RuntimeConfig.instance = new RuntimeConfig();\n }\n return RuntimeConfig.instance;\n }\n\n public addValue<K extends keyof Config>(key: K, value: Config[K]) {\n this.config[key] = value;\n }\n\n public getValue(key: keyof Config) {\n return this.config[key];\n }\n\n public getOrThrow<K extends keyof Config>(key: K): Config[K] {\n const value = this.getValue(key);\n if (!value) {\n throw new Error(`Value ${key} is not set`);\n }\n return value as Config[K];\n }\n\n public getConfig() {\n return this.config;\n }\n\n public deleteValue(key: keyof Config) {\n delete this.config[key];\n }\n}\n","import { cosmos } from '@ixo/impactxclient-sdk';\nimport { existsSync, readFileSync, writeFileSync } from 'fs';\nimport { unlink } from 'fs/promises';\nimport os from 'os';\nimport path from 'path';\nimport { SignXClient } from './signx/signx';\nimport { WalletProps } from './signx/types';\n\n// Use hidden .wallet.json file in user's home directory\nconst WALLET_PATH = path.join(os.homedir(), '.wallet.json');\n\n// for dev make it here\n// const WALLET_PATH = path.join(__dirname, '.wallet.json');\n\nexport class Wallet {\n public wallet: WalletProps | undefined;\n public signXClient?: SignXClient;\n\n constructor() {\n this.loadWallet();\n }\n\n public setSignXClient(signXClient: SignXClient) {\n this.signXClient = signXClient;\n }\n\n private loadWallet() {\n if (existsSync(WALLET_PATH)) {\n try {\n const walletData = readFileSync(WALLET_PATH, 'utf8');\n this.wallet = JSON.parse(walletData) as WalletProps;\n // set signx client\n this.setSignXClient(new SignXClient(this.wallet.network ?? 'devnet'));\n console.log('Wallet loaded successfully');\n } catch (error) {\n console.warn('Failed to load wallet file:', error);\n this.wallet = undefined;\n }\n } else {\n console.log('No wallet file found');\n }\n }\n\n setWallet(wallet: WalletProps) {\n try {\n this.wallet = wallet;\n const walletJson = JSON.stringify(wallet, null, 2);\n writeFileSync(WALLET_PATH, walletJson, 'utf8');\n console.log('Wallet saved successfully to:', WALLET_PATH);\n } catch (error) {\n console.error('Failed to save wallet:', error);\n throw new Error('Failed to save wallet file');\n }\n }\n\n public checkWalletExists() {\n return existsSync(WALLET_PATH) && this.wallet !== undefined;\n }\n\n public async clearWallet() {\n this.wallet = undefined;\n try {\n if (existsSync(WALLET_PATH)) {\n await unlink(WALLET_PATH);\n console.log('Wallet file deleted successfully');\n }\n } catch (error) {\n console.error('Failed to delete wallet file:', error);\n }\n }\n\n get did() {\n return this.wallet?.did;\n }\n\n get address() {\n return this.wallet?.address;\n }\n\n get name() {\n return this.wallet?.name;\n }\n\n get pubKey() {\n return this.wallet?.pubKey;\n }\n\n get algo() {\n return this.wallet?.algo;\n }\n\n get matrix() {\n return this.wallet?.matrix;\n }\n\n public reloadWallet() {\n this.loadWallet();\n }\n\n async sendTokens(address: string, amount: number) {\n if (!this.address || !this.signXClient || !this.wallet) {\n throw new Error('Wallet not loaded');\n }\n const sendTokensToUserMsg = {\n typeUrl: '/cosmos.bank.v1beta1.MsgSend',\n value: cosmos.bank.v1beta1.MsgSend.fromPartial({\n fromAddress: this.address,\n toAddress: address,\n amount: [\n cosmos.base.v1beta1.Coin.fromPartial({\n amount: amount.toString(),\n denom: 'uixo',\n }),\n ],\n }),\n };\n const tx = await this.signXClient?.transact([sendTokensToUserMsg], this.wallet);\n this.signXClient?.displayTransactionQRCode(JSON.stringify(tx));\n await this.signXClient?.pollNextTransaction();\n const response = await this.signXClient?.awaitTransaction();\n return response;\n }\n}\n"],"mappings":"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","names":["cancel","intro","isCancel","log","outro","select","spinner","process","CommandRegistry","command","name","cmd","select","z","selectNetwork","config","network","RELAYER_NODE_DID","MatrixHomeServerUrl","MatrixRoomBotServerUrl","PORTAL_URL","CHAIN_RPC","checkRequiredString","value","message","result","z","checkRequiredURL","checkRequiredNumber","isCancel","log","spinner","text","customMessages","ixo","utils","utils","createMatrixApiClient","sha256","eciesEncrypt","ClientEvent","createClient","md5","secretStorageKeys","hasPrivateKey","keyId","secretStorageKeys","getPrivateKey","clearSecretStorageKeys","secretStorageKeys","getSecretStorageKey","keys","keyIds","keyId","hasPrivateKey","privateKey","getPrivateKey","cacheSecretStorageKey","keyInfo","Bip39","EnglishMnemonic","Secp256k1","sha256","Slip10","Slip10Curve","stringToPath","DirectSecp256k1HdWallet","createQueryClient","createSigningClient","customMessages","ixo","utils","createCipheriv","randomBytes","createQueryClient","createRegistry","utils","convertTimestampObjectToTimestamp","timestamp","utils","FEEGRANT_TYPES","decodeGrants","grants","registry","createRegistry","grant","allowance","decodedAllowance","FEEGRANT_TYPES","convertTimestampObjectToTimestamp","limit","isAllowanceExpired","expiration","expirationTimestamp","isAllowanceLimitReached","checkIidDocumentExists","did","network","url","CHAIN_RPC","createQueryClient","error","createIidDocument","offlineSigner","accounts","address","pubkey","allowances","queryAddressAllowances","feegrantGranter","decodeGrants","allowance","isAllowanceExpired","isAllowanceLimitReached","trx","ixo","customMessages","signAndBroadcastWithMnemonic","messages","memo","signingClient","createSigningClient","simGas","gas","gasOptions","calculateTrxGasOptions","fee","result","gasUsed","gasPriceStep","delay","ms","resolve","encrypt","text","password","iv","randomBytes","cipher","createCipheriv","encrypted","getSecpClient","mnemonic","wallet","DirectSecp256k1HdWallet","account","seed","Bip39","EnglishMnemonic","hdPath","stringToPath","privkey","Slip10","Slip10Curve","keypair","Secp256k1","compressedPubkey","utils","signerAddress","signDoc","message","challengeBytes","messageHash","sha256","WELL_KNOWN_URI","mxLogin","homeServerUrl","username","password","deviceName","localMatrix","mxHomeServerUrl","mxUsername","mxIdMatch","getBaseUrl","client","createTemporaryClient","response","normalizeUsername","error","msg","getPublicKeyForEncryption","network","MatrixRoomBotServerUrl","createUserCreationChallenge","address","challenge","challengeBase64","encryptPasswordWithECIES","publicKey","publicKeyBytes","passwordBytes","encryptedPassword","eciesEncrypt","byte","createUserAccountWithSecp","address","password","signature","challenge","network","publicKeyInfo","getPublicKeyForEncryption","encryptedPassword","encryptPasswordWithECIES","request","response","MatrixRoomBotServerUrl","errorData","mxRegisterWithSecp","address","password","deviceName","wallet","network","challengeBase64","createUserCreationChallenge","signatureBytes","signature","createUserAccountWithSecp","homeServerUrl","MatrixHomeServerUrl","username","generateUsernameFromAddress","mxLogin","error","checkIsUsernameAvailable","homeServerUrl","username","client","createTemporaryClient","createClient","createMatrixClient","accessToken","userId","deviceId","mxClient","getSecretStorageKey","cacheSecretStorageKey","resolve","reject","sync","ClientEvent","state","logoutMatrixClient","baseUrl","hasCrossSigningAccountData","masterKeyData","setupCrossSigning","securityPhrase","password","forceReset","skipBootstrapSecureStorage","clearSecretStorageKeys","mxCrypto","recoveryKey","makeRequest","getAuthId","delay","generateUsernameFromAddress","address","generatePasswordFromMnemonic","mnemonic","md5","generatePassphraseFromMnemonic","mnemonic","hash","sha256","cleanMatrixHomeServerUrl","homeServer","generateUserRoomNameFromAddress","address","postpend","generateUserRoomAliasFromAddress","homeServerUrl","getBaseUrl","servername","protocol","serverDiscoveryUrl","WELL_KNOWN_URI","baseUrl","normalizeUsername","rawUsername","getAuthId","userId","password","DEVICE_NAME","registerUserSimplified","pin","oracleName","network","oracleAvatarUrl","transferTokens","mnemonic","utils","wallet","getSecpClient","address","did","didExists","checkIidDocumentExists","createIidDocument","delay","mxMnemonic","homeServerUrl","MatrixHomeServerUrl","mxUsername","generateUsernameFromAddress","mxPassword","generatePasswordFromMnemonic","mxPassphrase","generatePassphraseFromMnemonic","checkIsUsernameAvailable","account","mxRegisterWithSecp","mxClient","createMatrixClient","error","matrixApiClient","createMatrixApiClient","hasCrossSigning","hasCrossSigningAccountData","setupCrossSigning","mxRoomAlias","generateUserRoomAliasFromAddress","roomId","response","MatrixRoomBotServerUrl","joinedMembers","joined","encryptedMnemonic","encrypt","storeEncryptedMnemonicResponse","logoutMatrixClient","createMatrixApiClient","mxUtils","CID","base64","mfsha2","createCIDFromBase64","base64String","multibaseString","bytes","hash","jsonToBase64","jsonString","uint8Array","publicUpload","data","fileName","config","wallet","matrixAPIClient","createMatrixApiClient","MatrixHomeServerUrl","fileContent","fileBuffer","fullFileName","response","httpUrl","mxUtils","jsonString","base64String","jsonToBase64","cid","createCIDFromBase64","CreateEntity","wallet","config","customMessages","ixo","RELAYER_NODE_DID","utils","oracleAccountAddress","oracleName","entityDid","response","publicUpload","price","walletAddress","linkedResourcesMsgs","resource","log","tx","content","title","pageResource","orgName","name","logo","coverImage","location","description","profileResource","services","service","parentProtocol","params","msg","pin","text","value","checkRequiredString","isCancel","registerResult","registerUserSimplified","address","did","s","spinner","CreateEntityCommand","wallet","config","CreateEntity","selectNetwork","results","value","checkRequiredString","checkRequiredNumber","checkRequiredURL","did","portalUrl","PORTAL_URL","HelpCommand","registry","cmd","p","existsSync","path","simpleGit","fs","path","createProjectEnvFile","config","freshMx","mxLogin","MatrixHomeServerUrl","network","projectPath","envFile","path","envDir","fs","envContent","error","InitCommand","config","wallet","input","value","inputStr","projectPath","projectName","path","name","existsSync","overwrite","confirm","repo","customRepo","shouldOverwrite","git","simpleGit","cloneSpinner","rmSync","gitFolder","CreateEntityCommand","createProjectEnvFile","error","confirm","LogoutCommand","wallet","toHex","createRegistry","IxoSignX","SIGN_X_LOGIN_ERROR","SIGN_X_LOGIN_SUCCESS","SIGN_X_TRANSACT_ERROR","SIGN_X_TRANSACT_SUCCESS","qrcode","SignXEndpoints","SignXClient","wallet","chainNetwork","loginData","qrCodeData","title","qrCodeStr","resolve","reject","response","error","messages","memo","registry","result","SignXLoginCommand","wallet","config","network","selectNetwork","signXClient","SignXClient","loginData","loginResult","error","CLIError","message","code","suggestions","handleError","error","CLIError","suggestion","RuntimeConfig","_RuntimeConfig","key","value","cosmos","existsSync","readFileSync","writeFileSync","unlink","os","path","WALLET_PATH","path","os","Wallet","signXClient","existsSync","walletData","readFileSync","SignXClient","error","wallet","walletJson","writeFileSync","unlink","address","amount","sendTokensToUserMsg","cosmos","tx","CLIManager","CommandRegistry","RuntimeConfig","Wallet","InitCommand","CreateEntityCommand","LogoutCommand","HelpCommand","result","login","select","isCancel","cancel","process","SignXLoginCommand","log","commandName","command","s","spinner","intro","action","args","userArgs","error","handleError","outro","cli"]}
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "ixo-oracles-cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "CLI tool for creating and managing IXO Oracle projects",
5
5
  "main": "dist/cli.js",
6
6
  "type": "module",
7
7
  "bin": {
8
8
  "oracles-cli": "./dist/cli.js"
9
9
  },
10
+ "preferGlobal": true,
10
11
  "keywords": [
11
12
  "cli",
12
13
  "ixo",
@@ -27,7 +28,8 @@
27
28
  },
28
29
  "homepage": "https://github.com/ixoworld/ixo-oracles-cli#readme",
29
30
  "engines": {
30
- "node": ">=22.0.0"
31
+ "node": ">=22.0.0",
32
+ "pnpm": ">=10.0.0"
31
33
  },
32
34
  "files": [
33
35
  "dist",