wative 1.1.20 → 1.2.0

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.
@@ -19,6 +19,7 @@ export declare class SSHConfigManager {
19
19
  * 加载服务配置
20
20
  */
21
21
  loadServiceConfig(serviceName: string): SSHServiceConfig;
22
+ serviceIsExist(serviceName: string): boolean;
22
23
  /**
23
24
  * 获取所有服务配置列表
24
25
  */
@@ -50,6 +51,5 @@ export declare class SSHConfigManager {
50
51
  private getServiceConfigPath;
51
52
  private saveServiceConfig;
52
53
  private parseConfigData;
53
- private removeServiceKeys;
54
54
  }
55
55
  //# sourceMappingURL=config_manager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config_manager.d.ts","sourceRoot":"","sources":["../../src/ssh/config_manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C,qBAAa,gBAAgB;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAS;gBAEjB,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;IAerD;;OAEG;IACI,eAAe,IAAI,MAAM;IAIhC;;OAEG;IACI,YAAY,IAAI,MAAM;IAI7B;;OAEG;IACU,mBAAmB,CAC5B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EAAE,EAC1B,UAAU,GAAE,MAAyB,EACrC,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IA+C5B;;OAEG;IACI,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB;IAW/D;;OAEG;IACI,kBAAkB,IAAI,MAAM,EAAE;IAiBrC;;OAEG;IACI,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAWrD;;OAEG;IACI,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAMzF;;OAEG;IACU,yBAAyB,CAClC,WAAW,EAAE,MAAM,EAAE,EACrB,SAAS,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAC5C,OAAO,CAAC;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAyB7C;;OAEG;IAGH,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,WAAW;YAiBL,sBAAsB;YAwBtB,qBAAqB;IAmBnC,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,iBAAiB;CAc5B"}
1
+ {"version":3,"file":"config_manager.d.ts","sourceRoot":"","sources":["../../src/ssh/config_manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG3C,qBAAa,gBAAgB;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,YAAY,CAAS;gBAEjB,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;IAerD;;OAEG;IACI,eAAe,IAAI,MAAM;IAIhC;;OAEG;IACI,YAAY,IAAI,MAAM;IAI7B;;OAEG;IACU,mBAAmB,CAC5B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EAAE,EAC1B,UAAU,GAAE,MAAyB,EACrC,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IA+C5B;;OAEG;IACI,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB;IAWxD,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAKnD;;OAEG;IACI,kBAAkB,IAAI,MAAM,EAAE;IAiBrC;;OAEG;IACI,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAQrD;;OAEG;IACI,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,IAAI;IAMzF;;OAEG;IACU,yBAAyB,CAClC,WAAW,EAAE,MAAM,EAAE,EACrB,SAAS,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAC5C,OAAO,CAAC;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;IAyB7C;;OAEG;IAGH,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,WAAW;YAiBL,sBAAsB;YAwBtB,qBAAqB;IAmBnC,OAAO,CAAC,wBAAwB;IAIhC,OAAO,CAAC,oBAAoB;IAI5B,OAAO,CAAC,iBAAiB;IAazB,OAAO,CAAC,eAAe;CA2B1B"}
@@ -1 +1 @@
1
- {"version":3,"file":"service_manager.d.ts","sourceRoot":"","sources":["../../src/ssh/service_manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAmB,MAAM,SAAS,CAAC;AAQ5D,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,eAAe,CAA2C;IAClE,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,MAAM,CAAS;gBAEX,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;IAOrD;;OAEG;IACH,OAAO,CAAC,YAAY;IAMpB;;;;;OAKG;YACW,WAAW;IAqBzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACU,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA2D3G;;OAEG;IACU,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0G5D;;OAEG;IACU,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7G;;OAEG;IACI,kBAAkB,IAAI,MAAM,EAAE;IAIrC;;OAEG;IACI,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB;IAI9D;;OAEG;IACI,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW;IA0CjF;;OAEG;IACU,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7C;;OAEG;IACU,aAAa,CACtB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EAAE,EAC1B,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IAU5B;;OAEG;IACU,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9D;;OAEG;IACI,YAAY,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE;IAoB9F;;OAEG;IACI,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAS7E;;OAEG;IACU,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IA6CjG;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqC5B;;OAEG;IACU,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAgDvG;;OAEG;IACH,OAAO,CAAC,WAAW;IAgCnB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgD1B;;OAEG;IACH,OAAO,CAAC,cAAc;CAoBzB"}
1
+ {"version":3,"file":"service_manager.d.ts","sourceRoot":"","sources":["../../src/ssh/service_manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAmB,MAAM,SAAS,CAAC;AAQ5D,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,eAAe,CAA2C;IAClE,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,MAAM,CAAS;gBAEX,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;IAOrD;;OAEG;IACH,OAAO,CAAC,YAAY;IAMpB;;;;;OAKG;YACW,WAAW;IAqBzB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,YAAY;IAKpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;OAEG;IACH,OAAO,CAAC,aAAa;IAOrB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACU,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA2D3G;;OAEG;IACU,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0G5D;;OAEG;IACU,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAU7G;;OAEG;IACI,kBAAkB,IAAI,MAAM,EAAE;IAIrC;;OAEG;IACI,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB;IAI9D;;OAEG;IACI,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW;IA0CjF;;OAEG;IACU,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ7C;;OAEG;IACU,aAAa,CACtB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,gBAAgB,EAAE,MAAM,EAAE,EAC1B,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,gBAAgB,CAAC;IAU5B;;OAEG;IACU,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9D;;OAEG;IACI,YAAY,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE;IAoB9F;;OAEG;IACI,sBAAsB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI;IAS7E;;OAEG;IACU,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QAAE,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IA6CjG;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAqC5B;;OAEG;IACU,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,EAAE,MAAM,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAgDvG;;OAEG;IACH,OAAO,CAAC,WAAW;IAgCnB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgD1B;;OAEG;IACH,OAAO,CAAC,cAAc;CAoBzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"wative.d.ts","sourceRoot":"","sources":["../src/wative.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AA0mB9B,OAAO,EAAE,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"wative.d.ts","sourceRoot":"","sources":["../src/wative.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,QAAA,MAAM,OAAO,SAAgB,CAAC;AA8mB9B,OAAO,EAAE,OAAO,EAAE,CAAC"}
package/lib/wative.esm.js CHANGED
@@ -1 +1 @@
1
- import*as e from"path";import t from"path";import{Command as r}from"commander";import{execSync as s,spawn as o}from"child_process";import*as n from"fs";import i,{readFileSync as a}from"fs";import*as c from"ini";import*as l from"crypto";import{timingSafeEqual as u}from"crypto";import{utils as p,Server as d}from"ssh2";import"figlet";import h from"inquirer";import g from"web3";import f from"@solana/web3.js";import"@solana/spl-token";import"@metaplex-foundation/js";import"bignumber.js";import*as m from"log4js";import{ethers as y}from"ethers";import v from"tweetnacl";import w from"bs58";import b from"bip39";import S from"@coral-xyz/anchor";import k from"crypto-js";import x from"ethereumjs-wallet";import _ from"micro-ed25519-hdkey";import*as P from"net";class I{constructor(t,r){this.configDir=t||e.join(require("os").homedir(),".wative/ssh"),this.keystorePath=r||e.join(require("os").homedir(),".wative"),n.existsSync(this.configDir)||n.mkdirSync(this.configDir,{recursive:!0});const s=e.join(this.configDir,"conf.d");n.existsSync(s)||n.mkdirSync(s,{recursive:!0})}getKeystorePath(){return this.keystorePath}getConfigDir(){return this.configDir}async createServiceConfig(e,t,r,s="default_client",o){if(!this.isValidServiceName(e))throw new Error("Invalid service name. Use only alphanumeric characters, hyphens, and underscores.");if(this.isPortInUse(t))throw new Error(`Port ${t} is already in use by another service.`);const n=await this.generateServiceKeyPair(e),i=await this.generateClientKeyPair(e,s),a={name:e,description:o||`Wative SSH Service - ${e}`,ssh:{listen:"127.0.0.1",port:t,log:{size:10485760,backups:3}},keystore:{path:this.keystorePath,allowed_keystores:r},clients:[{name:s,public_key_path:i.publicKey,allowed_keystores:r}],server_keys:{private_key_path:n.privateKey,passphrase:n.passphrase}};return this.saveServiceConfig(e,a),a}loadServiceConfig(e){const t=this.getServiceConfigPath(e);if(!n.existsSync(t))throw new Error(`Service configuration '${e}' not found.`);const r=c.parse(n.readFileSync(t,"utf-8"));return this.parseConfigData(r)}listServiceConfigs(){const t=e.join(this.configDir,"conf.d");if(!n.existsSync(t))return[];return n.readdirSync(t).filter(r=>{const s=e.join(t,r);return n.statSync(s).isDirectory()&&n.existsSync(e.join(s,"config.ini"))})}removeServiceConfig(e){const t=this.getServiceConfigPath(e);n.existsSync(t)&&n.unlinkSync(t),this.removeServiceKeys(e)}updateServiceConfig(e,t){const r={...this.loadServiceConfig(e),...t};this.saveServiceConfig(e,r)}async validateKeystorePasswords(e,t){const r={},{WativeCore:s}=require("wative-core");for(const o of e)try{const e=t[o];if(!e){r[o]=!1;continue}const n=new s(this.keystorePath,[o],[e]);r[o]=n.account.isLogin(o)}catch(e){r[o]=!1}return r}isValidServiceName(e){return/^[a-zA-Z0-9_-]+$/.test(e)&&e.length>0&&e.length<=50}isPortInUse(e){const t=this.listServiceConfigs();for(const r of t)try{if(this.loadServiceConfig(r).ssh.port===e)return!0}catch(e){}return!1}async generateServiceKeyPair(t){const r=this.generateSecurePassphrase(),o=e.join(this.configDir,"conf.d",t);n.existsSync(o)||n.mkdirSync(o,{recursive:!0});const i=e.join(o,"server_private_key"),a=e.join(o,"server_public_key.pub");return n.existsSync(i)||(console.log(`Generating SSH server key pair for service '${t}'...`),s(`ssh-keygen -t rsa -b 4096 -f ${i} -N '${r}' -C 'wative_${t}_server'`,{stdio:"inherit"})),{privateKey:i,publicKey:a,passphrase:r}}async generateClientKeyPair(t,r){const s=e.join(this.configDir,"conf.d",t);n.existsSync(s)||n.mkdirSync(s,{recursive:!0});return{privateKey:"",publicKey:e.join(s,`${r}.pub`),passphrase:""}}generateSecurePassphrase(){return l.randomBytes(32).toString("hex")}getServiceConfigPath(t){return e.join(this.configDir,"conf.d",t,"config.ini")}saveServiceConfig(t,r){const s=this.getServiceConfigPath(t),o=e.dirname(s);n.existsSync(o)||n.mkdirSync(o,{recursive:!0});const i=c.stringify(r);n.writeFileSync(s,i)}parseConfigData(e){return{name:e.name,description:e.description,ssh:{listen:e.ssh.listen,port:parseInt(e.ssh.port),log:{size:parseInt(e.ssh.log.size),backups:parseInt(e.ssh.log.backups)}},keystore:{path:e.keystore.path,allowed_keystores:Array.isArray(e.keystore.allowed_keystores)?e.keystore.allowed_keystores:e.keystore.allowed_keystores.split(",")},clients:Array.isArray(e.clients)?e.clients:[e.clients],server_keys:{private_key_path:e.server_keys.private_key_path,passphrase:e.server_keys.passphrase}}}removeServiceKeys(t){const r=[`id_rsa_${t}_server`,`id_rsa_${t}_server.pub`,`id_rsa_${t}_*`];for(const t of r){const r=e.join(this.configDir,t);n.existsSync(r)&&n.unlinkSync(r)}}}require("chalk"),require("chalk"),require("chalk"),process.env.HOME||process.env.USERPROFILE;const E=async e=>{const t=[{name:"password",type:"password",mask:"#",message:`${e}:`}];let{password:r}=await h.prompt(t);return r};require("bn.js"),require("ethereumjs-util"),require("bignumber.js"),require("chalk"),require("wative-core"),require("chalk"),require("dotenv").config(),require("cli-progress"),require("wative-core");const{WativeCore:j}=require("wative-core"),{Connection:A,PublicKey:$,VersionedTransaction:C,VersionedMessage:T}=require("@solana/web3.js"),K=require("bs58"),{Keypair:M,TransactionMessage:O,ComputeBudgetInstruction:D,TransactionInstruction:L,ComputeBudgetProgram:q}=require("@solana/web3.js"),{Wallet:H}=require("@coral-xyz/anchor");m.configure({appenders:{file:{type:"file",filename:process.env.HOME+"/.wative/logs/wative.log",maxLogSize:10485760,backups:3,compress:!0,keepFileExt:!0,layout:{type:"pattern",pattern:"%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %c - %m"},encoding:"utf-8"},console:{type:"console"}},categories:{default:{appenders:["file","console"],level:"info"}}});const z=m.getLogger("file");z.level="info";class N{constructor(e,t,r,s,o,i,c,l){if(this._allowedAppIds=[],this._allowedPubKeys=[],this._allowedKeystoreIds=[],this._sessionIdAppIdMap={},(e=>{if(e=e.trim(),!n.existsSync(e))throw new Error("File not exists")})(e),0===r.length||0===s.length||0===o.length||r.length!==s.length||r.length!==o.length)throw new Error("WativeWielderServer:: constructor: Invaild AllowedApp");for(let e=0;e<o.length;e++)for(let t=0;t<o[e].length;t++){const r=o[e][t];if(!c.includes(r))throw new Error("WativeWielderServer:: constructor: Invaild AllowedKeystoreIds")}for(let e of r)this._allowedAppIds.push(Buffer.from(e));for(let e of s){let t=p.parseKey(a(e));this._allowedPubKeys.push(t)}this.wativeCore=new j(i,c,l),this._idRsaPrivatePath=e,this._idRsaPassphrase=t,this._allowedKeystoreIds=o,this._keystoreDirectoryPath=i}listen(e,t){new d({hostKeys:[{key:a(this._idRsaPrivatePath),passphrase:this._idRsaPassphrase}]},e=>{e.on("authentication",t=>{let r=!0;if(this&&(this.checkValue(Buffer.from(t.username),"appId")||(r=!1)),"publickey"!==t.method||!r)return t.reject();{let e=this.getBytesIndex(Buffer.from(t.username),this._allowedAppIds),r=this._allowedPubKeys[e];if(t.key.algo!==r.type||!this.checkValue(t.key.data,"publicKey")||t.signature&&!0!==r.verify(t.blob,t.signature,t.hashAlgo))return t.reject()}if(r){const r=e._protocol._kex.sessionID.toString("hex");this._sessionIdAppIdMap[r]=Buffer.from(t.username),t.accept()}else t.reject()}).on("ready",()=>{e.on("session",(t,r)=>{t().once("exec",async(t,r,s)=>{const o=e._protocol._kex.sessionID.toString("hex"),n=await this.web3Request(o,s.command),i=t();i&&(JSON.stringify(n)?(i.write(JSON.stringify(n)),i.exit(0),i.end()):(i.write("ssh2 connect error"),i.exit(0),i.end()))})})}).on("close",()=>{z.info("Client disconnected")}).on("error",e=>{z.error("err: ",e.message)})}).listen(t,e,function(){z.info("Listening on port "+t)})}async web3Request(e,t){try{const r=this._sessionIdAppIdMap[e],s=this.getBytesIndex(r,this._allowedAppIds);if(s<0)return{status:!1,msg:"app not found"};let o=JSON.parse(t);z.info("sign message: ",t);let n=o.method,i=o.keystoreId||o.params.keystoreId,a=o.chainId||o.params.chainId;if(!this._allowedKeystoreIds[s].includes(i))return{status:!1,msg:"keystore not allowed"};let c;if("get_root_account"===n)c=this.getRootAccount(i,a);else if("get_sub_account"===n){let e=o.params;c=this.getSubAccount(i,e.chainId,null==e?void 0:e.startIndex,null==e?void 0:e.endIndex)}else if("sign"===n){let e=o.params;try{c=await this.wativeCore.account.signTransaction(e.txParams.from,e.txParams,e.rpcUrl)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}}else if("sign_and_send"===n){let e=o.params;try{c={transactionHash:await this.wativeCore.account.signAndSendTx(e.txParams,e.rpcUrl)}}catch(e){return{status:!1,msg:e.msg}}}else if("solana_sign"===n)try{let e=o.params;c=await this.signSolanaTransaction(e.txParams.from,e.txParams.data,e.txParams.lookup_tables,e.rpcUrl,e.priority_fee)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}else if("solana_send"===n)try{let e=o.params;c=await this.sendSignedSolanaTransaction(e.txParams.from,e.txParams.signature,e.txParams.data,e.rpcUrl)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}else if("sign_message"===n)try{let e=o.params;z.debug("sign message: ",e),c=await this.signMessage(e.account,e.message)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}else{if("sign_typed_data"!==n)return{status:!1,msg:"message method not find"};try{let e=o.params;z.debug("sign message: ",e),c=await this.signTypedData(e.account,e.domain,e.types_name,e.types,e.message)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}}return{status:!0,data:c}}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}}checkValue(e,t){if("appId"!==t&&"publicKey"!==t)return!1;let r=this._allowedAppIds.length;for(let s=0;s<r;s++){let r;r="appId"===t?this._allowedAppIds[s]:this._allowedPubKeys[s].getPublicSSH();const o=e.length!==r.length;o&&(r=e);const n=u(e,r);if(!o&&n)return!0}}getBytesIndex(e,t){let r=t.length;for(let s=0;s<r;s++)if(e.length===t[s].length&&u(e,t[s]))return s;return-1}getRootAccount(t,r){const s=e.resolve(this._keystoreDirectoryPath,`accounts/${t}.json`);let o,n=a(s);return n=JSON.parse(n.toString()),o="SOLANA"===this.getChainType(r)?n.data[0].ciphertexts.solana.address:n.data[0].ciphertexts.evm.address,[{id:0,address:o,children:n.data.length,type:"M"}]}getChainType(e){return"901"===e||"902"===e||"903"===e?"SOLANA":"EVM"}getSubAccount(t,r,s,o){const n=e.resolve(this._keystoreDirectoryPath,`accounts/${t}.json`);let i=a(n);i=JSON.parse(i.toString());let c=i.data.length-1;o&&o<c&&(c=o);let l=0;if(s&&s>0&&(l=s),l>c)return[];let u=this.getChainType(r),p=[];for(let e=l;e<=c;e++)p.push(i.data[e].ciphertexts[u.toLocaleLowerCase()].address);return p}async signMessage(e,t){let r=await this.wativeCore.account.signMessage(e,t);return console.log(r),r}async signTypedData(e,t,r,s,o){let n=JSON.parse(t),i=JSON.parse(s),a=JSON.parse(o);console.log(n),console.log(i),console.log(a);let c=this.wativeCore.account.showPrivateKey(e),l=new y.Wallet(c),u=await l.signTypedData(n,{[r]:i},a);return console.log(u),{status:!0,output:u}}async signSolanaTransaction(e,t,r,s,o){let n=new A(s),i=[];if(r)for(let e of r){let t=(await n.getAddressLookupTable(new $(e))).value;i.push(t),await R(1e3)}let a=T.deserialize(Uint8Array.from(Buffer.from(t,"hex"))),c=O.decompile(a);c.instructions.push(q.setComputeUnitLimit({units:2e6})),c.instructions.push(q.setComputeUnitPrice({microLamports:1e3})),a=c.compileToV0Message(i),a.recentBlockhash=(await n.getLatestBlockhash()).blockhash,await R(3e3);let l=new C(a),u=this.wativeCore.account.showPrivateKey(e);const p=M.fromSecretKey(new Uint8Array(K.decode(u))),d=new H(p);let h=await n.simulateTransaction(l);if(!h||!h.value||0===h.value.unitsConsumed||h.value.err)return{status:!1,output:h.value.err};let g=c.instructions.length,f=Math.trunc(1.2*h.value.unitsConsumed);if(c.instructions[g-2]=q.setComputeUnitLimit({units:f}),!o||"null"==o)try{o=await this.getPrioritizationFee(s)}catch(e){o=2e5}o<1e4&&(o=1e4),o>5e5&&(o=5e5),c.instructions[g-1]=q.setComputeUnitPrice({microLamports:o}),a=c.compileToV0Message(i),await R(1e3),a.recentBlockhash=(await n.getLatestBlockhash()).blockhash,l=new C(a),l.feePayer=d.publicKey,await R(3e3);let m=await this.wativeCore.account.signTransaction(e,l,s),y=new C(m.output.message,m.output.signatures).message.serialize();return y=Buffer.from(y).toString("hex"),{status:!0,output:{transactionHash:K.encode(m.output.signatures[0]),message:y,compute_units:h.value.unitsConsumed.toString()}}}async sendSignedSolanaTransaction(e,t,r,s){let o=[K.decode(t)],n=T.deserialize(Uint8Array.from(Buffer.from(r,"hex"))),i=new C(n,o);return await this.wativeCore.account.sendSignedTransaction(e,i,s)}async getPrioritizationFee(e){let t=new $("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4");const r=new A(e,"confirmed");let s=await r.getSignaturesForAddress(t,{limit:5});await R(2e3);let o=[];for(let e=0;e<s.length;e++)o.push(s[e].signature);let n=await r.getParsedTransactions(o,{maxSupportedTransactionVersion:0}),i=0;for(let e=0;e<n.length;e++){let t=n[e].transaction.message.instructions;for(let e=0;e<t.length;e++)if("ComputeBudget111111111111111111111111111111"===t[e].programId.toBase58()){let r=t[e].data;try{let e=new L({keys:[],programId:new $("ComputeBudget111111111111111111111111111111"),data:Buffer.from(K.decode(r))}),{microLamports:t}=D.decodeSetComputeUnitPrice(e);i+=Number(t);continue}catch(e){}}}return Math.ceil(i/5)}}const R=e=>new Promise(t=>setTimeout(t,e));"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var F={exports:{}},B={name:"wative-core",version:"1.0.21",description:"An agile keystore management toolkit",main:"lib/index.umd.js",module:"lib/index.esm.js",types:"lib/index.d.ts",scripts:{test:"jest",compile:"tsc",build:"rollup --config"},repository:{type:"git",url:""},bugs:{url:"https://github.com"},homepage:"https://github.com",keywords:["keystore","wallet"],author:"",license:"ISC",files:["src/","lib/"],dependencies:{"@babel/plugin-transform-modules-commonjs":"7.24.1","@rollup/plugin-commonjs":"21.0.1","@solana/web3.js":"1.91.8","@types/bs58":"4.0.4","crypto-js":"4.2.0","ethereumjs-wallet":"1.0.2",jest:"27.5.1","micro-ed25519-hdkey":"0.1.2",rollup:"2.79.1","rollup-plugin-terser":"7.0.2","rollup-plugin-typescript2":"0.31.2",tslib:"2.6.2",typescript:"4.9.5",web3:"1.7.3","web3-core":"4.3.2","@coral-xyz/anchor":"0.30.1","@types/crypto-js":"4.2.2","nodejs-threadpool":"1.0.1",tweetnacl:"1.0.3","rpc-websockets":"7.10.0"}};!function(e,t,r,s,o,n,i,a,c,l,u,p){function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function h(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}}),t.default=e,Object.freeze(t)}var g=h(t),f=h(r),m=d(s),y=h(o),v=h(n),w=h(i),b=h(l),S=function(){return S=Object.assign||function(e){for(var t,r=1,s=arguments.length;r<s;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},S.apply(this,arguments)};function k(e,t,r,s){return new(r||(r=Promise))(function(o,n){function i(e){try{c(s.next(e))}catch(e){n(e)}}function a(e){try{c(s.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,a)}c((s=s.apply(e,t||[])).next())})}function x(e,t){var r,s,o,n={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=a(0),i.throw=a(1),i.return=a(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(a){return function(c){return function(a){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,a[0]&&(n=0)),n;)try{if(r=1,s&&(o=2&a[0]?s.return:a[0]?s.throw||((o=s.return)&&o.call(s),0):s.next)&&!(o=o.call(s,a[1])).done)return o;switch(s=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return n.label++,{value:a[1],done:!1};case 5:n.label++,s=a[1],a=[0];continue;case 7:a=n.ops.pop(),n.trys.pop();continue;default:if(!((o=(o=n.trys).length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){n=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){n.label=a[1];break}if(6===a[0]&&n.label<o[1]){n.label=o[1],o=a;break}if(o&&n.label<o[2]){n.label=o[2],n.ops.push(a);break}o[2]&&n.ops.pop(),n.trys.pop();continue}a=t.call(e,n)}catch(e){a=[6,e],s=0}finally{r=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}"function"==typeof SuppressedError&&SuppressedError;var _=function(e,t){return k(void 0,void 0,void 0,function(){var r,s,o;return x(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.apply(void 0,t)];case 1:return s=n.sent(),r={status:!0,output:s},[3,3];case 2:return o=n.sent(),r={status:!1,output:o.toString()},[3,3];case 3:return[2,r]}})})},P=function(){function e(e){this.web3=new m.default(e)}return e.prototype.getEvmGasPrice=function(){return k(this,void 0,void 0,function(){return x(this,function(e){switch(e.label){case 0:return[4,_(this.web3.eth.getGasPrice,[])];case 1:return[2,e.sent()]}})})},e.prototype.getEvmGasLimit=function(e,t){return k(this,void 0,void 0,function(){return x(this,function(r){switch(r.label){case 0:return[4,_(this.web3.eth.estimateGas,[e,t])];case 1:return[2,r.sent()]}})})},e}(),I=function(e){return e=e.trim(),g.existsSync(e)},E=function(e,t){var r=t.length;if(0===r)return!0;for(var s=0;s<r;s++){var o=f.join(e,"accounts/".concat(t[s],".json"));if(!I(o))return!1}return!0},j=function(e){return(e=(e=(e=e.trim()).toLocaleLowerCase()).replace(/\s+/g,"-").trim()).replace(/\-+/g,"-").trim()},A=function(e,t){var r=[],s=f.join(e,"network.json");if(!I(s))throw new Error("network.json not found");for(var o=function(e){for(var t=[],r=0;r<e.length;r++)t.push(j(e[r]));return t}($(s).accounts),n=0;n<t.length;n++)o.includes(t[n])&&r.push(t[n]);return r},$=function(e){var t=g.readFileSync(e).toString();return JSON.parse(t)},C=function(e,t){var r=JSON.stringify(e);g.writeFileSync(t,r)},T=function(e,t){return b.AES.encrypt(e,t).toString()},K=function(e,t){return b.AES.decrypt(e,t).toString(b.enc.Utf8)},M=["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","library","license","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","type","typical","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"],O=new m.default(m.default.givenProvider),D=function(){function e(e,t,r,s){if(this.account_passwords={},this.account_ciphertexts={},this.disable_address=!1,this.account_signatures="",this.setting_path=e,this.account_labels=t,0!==t.length){if(r){if(t.length!==r.length)throw new Error("account_labels should have same length for account_passwords");for(var o=0;o<t.length;o++){if(!this.checkPassword(t[o],r[o].trim()))throw new Error("account_passwords is not correct");this.account_passwords[t[o]]=r[o].trim()}}s&&(this.disable_address=s),this.reload()}}return e.prototype.isLogin=function(e){return e in this.account_passwords},e.prototype.reloadAccount=function(){this.reload()},e.prototype.getAccountLabel=function(e){var t=null;for(var r in this.account_ciphertexts)r.toLocaleLowerCase().includes(e.toLocaleLowerCase())&&(t=r);return null===t?null:{account_address:t,account_label:this.account_ciphertexts[t].account_label}},e.prototype.login=function(e,t){return this.checkPassword(e,t)?(this.account_passwords[e]=t,this.account_labels.push(e),this.reload(),{status:!0,output:"Login success"}):{status:!1,output:"Password is not correct"}},e.prototype.getAccounts=function(e){var t=this.getAccountSignature();t!==this.account_signatures&&(this.account_signatures=t,this.reload());for(var r=Object.keys(this.account_ciphertexts),s=[],o=0;o<r.length;o++)this.getAccountChainType(r[o])===e&&s.push(r[o]);return s},e.prototype.checkAccountLabelIsExist=function(e){return E(this.setting_path,[e])},e.prototype.checkAccountIsExist=function(e){return(e=this.getAccountChecksumAddress(e))in this.account_ciphertexts||(this.reload(),e in this.account_ciphertexts)},e.prototype.checkPassword=function(e,t){var r=f.join(this.setting_path,"accounts/".concat(e,".json"));if(!I(r))return!1;var s,o=$(r);s="PK"===o.account_type?S({salt:t},o.data[0].ciphertexts):{slat:t,data:o.pp_ciphertexts};var n=b.SHA256(JSON.stringify(s)).toString();return o.signature===n},e.prototype.showPrivateKey=function(e){if(!this.checkAccountIsExist(e))throw new Error("Account is not exist");e=this.getAccountChecksumAddress(e);var t=this.account_ciphertexts[e],r=this.account_passwords[t.account_label];return K(t.data,r)},e.prototype.getAccountChainType=function(e){return e.startsWith("0x")&&42===e.length?"evm":/^[A-HJ-NP-Za-km-z1-9]*$/.test(e)?"solana":"unknown"},e.prototype.generatePKAccount=function(e,t,r,s,o){if(o&&this.checkAccountLabelIsExist(e))throw new Error("Account labels already exist");if(!o&&!this.account_passwords[e])throw new Error("Password is not correct");o||(r=this.account_passwords[e]);var n,i=T(t,r);try{n=this.getAccountAddressByPrivateKey(t,s)}catch(e){return{status:!1,output:e.message}}var a={address:n,data:i},c=S({salt:r},a),l={signature:b.SHA256(JSON.stringify(c)).toString(),account_type:"PK",tag:"",ciphertexts:a};return o||(this.account_passwords[e]=r,this.account_labels.push(e)),{status:!0,output:l}},e.prototype.generatePPAccount=function(e,t,r){if(this.checkAccountLabelIsExist(e))return{status:!1,output:"Account labels already exist"};var s=T(t,r),o={slat:r,data:s},n=b.SHA256(JSON.stringify(o)).toString(),i=this.getSubAccount("evm",t,0);if(!1===i.status)return{status:!1,output:i.output};var a=this.getSubAccount("solana",t,0);if(!1===a.status)return{status:!1,output:a.output};var c={signature:n,account_type:"PP",pp_ciphertexts:s,tag:"",data:[{ciphertexts:{evm:{address:i.output.address,data:T(i.output.pk,r)},solana:{address:a.output.address,data:T(a.output.pk,r)}}}]};return this.account_passwords[e]=r,this.account_labels.push(e),{status:!0,output:c}},e.prototype.generateSubAccount=function(e,t){if(!this.checkAccountLabelIsExist(e))return{status:!1,output:"Account labels not exist"};var r=f.join(this.setting_path,"accounts/".concat(e,".json")),s=$(r).pp_ciphertexts,o=K(s,this.account_passwords[e]),n=this.getSubAccount("evm",o,t);if(!1===n.status)return{status:!1,output:n.output};var i=this.getSubAccount("solana",o,t);return!1===i.status?{status:!1,output:i.output}:{status:!0,output:{evm:{address:n.output.address,data:T(n.output.pk,this.account_passwords[e])},solana:{address:i.output.address,data:T(i.output.pk,this.account_passwords[e])}}}},e.prototype.resetPassword=function(e,t){if(!this.checkAccountLabelIsExist(e))return{status:!1,output:"Account labels not exist"};if(!this.checkPassword(e,this.account_passwords[e]))return{status:!1,output:"account passwords is not correct"};var r=f.join(this.setting_path,"accounts/".concat(e,".json")),s=$(r);if("PK"===s.account_type){for(var o=s.data,n=0;n<o.length;n++){var i=o[n].ciphertexts.data,a=K(i,this.account_passwords[e]);o[n].ciphertexts.data=T(a,t)}var c=S({salt:t},s.data[0].ciphertexts);return s.signature=b.SHA256(JSON.stringify(c)).toString(),C(s,r),delete this.account_passwords[e],{status:!0,output:"Password reset successfully"}}var l=K(s.pp_ciphertexts,this.account_passwords[e]);s.pp_ciphertexts=T(l,t);var u={slat:t,data:s.pp_ciphertexts};s.signature=b.SHA256(JSON.stringify(u)).toString();var p=s.data;for(n=0;n<p.length;n++){var d=K(p[n].ciphertexts.evm.data,this.account_passwords[e]);p[n].ciphertexts.evm.data=T(d,t);var h=K(p[n].ciphertexts.solana.data,this.account_passwords[e]);p[n].ciphertexts.solana.data=T(h,t)}return C(s,r),delete this.account_passwords[e],{status:!0,output:"Password reset successfully"}},e.prototype.signTransaction=function(e,t,r){return e=this.getAccountChecksumAddress(e),this.checkAccountIsExist(e)?"unknown"===this.getAccountChainType(e)?{status:!1,output:"Chain type unknown"}:"evm"===this.getAccountChainType(e)?this.signEvmTransaction(t,r):this.signSolanaTransaction(e,r,t):{status:!1,output:"Account is not exist"}},e.prototype.sendSignedTransaction=function(e,t,r){return e=this.getAccountChecksumAddress(e),this.checkAccountIsExist(e)?"unknown"===this.getAccountChainType(e)?{status:!1,output:"Chain type unknown"}:"evm"===this.getAccountChainType(e)?this.sendEvmTransaction(t,r):this.sendSolanaTransaction(t,r):{status:!1,output:"Account is not exist"}},e.prototype.signMessage=function(e,t){return e=this.getAccountChecksumAddress(e),this.checkAccountIsExist(e)?"unknown"===this.getAccountChainType(e)?{status:!1,output:"Chain type unknown"}:"evm"===this.getAccountChainType(e)?{status:!0,output:this.signEvmMessage(t,e)}:{status:!0,output:this.signSolanaMessage(t,e)}:{status:!1,output:"Account is not exist"}},e.prototype.simulateTransaction=function(e,t,r){return k(this,void 0,void 0,function(){var s,o,n;return x(this,function(i){switch(i.label){case 0:return s=new a.Connection(t),o=this.showPrivateKey(e),n=a.Keypair.fromSecretKey(v.decode(o)),[4,_(s.simulateTransaction.bind(s),[r,[n]])];case 1:return[2,i.sent()]}})})},e.prototype.signEvmTransaction=function(e,t){return k(this,void 0,void 0,function(){var r,s,o,n;return x(this,function(i){switch(i.label){case 0:return this.account_passwords?(r=e.from,e.gas?[3,2]:[4,new P(t).getEvmGasLimit(e,t)]):[2,{status:!1,output:"Please set password first"}];case 1:if(!(s=i.sent()).status)return[2,s];e.gas=s.output,i.label=2;case 2:return e.gasPrice?[3,4]:[4,new P(t).getEvmGasPrice()];case 3:if(!(s=i.sent()).status)return[2,s];e.gasPrice=s.output,i.label=4;case 4:return o=this.showPrivateKey(r),n=new m.default(t),[4,_(n.eth.accounts.signTransaction.bind(n.eth.accounts),[e,o])];case 5:return[2,i.sent()]}})})},e.prototype.sendEvmTransaction=function(e,t){return k(this,void 0,void 0,function(){var r;return x(this,function(s){switch(s.label){case 0:return r=new m.default(t),[4,_(r.eth.sendSignedTransaction.bind(r.eth),[e])];case 1:return[2,s.sent()]}})})},e.prototype.signSolanaTransaction=function(e,t,r){return k(this,void 0,void 0,function(){var s,o,n,i,l;return x(this,function(u){switch(u.label){case 0:return s=this.showPrivateKey(e),o=a.Keypair.fromSecretKey(v.decode(s)),n=new c.Wallet(o),"recentBlockhash"in r&&r.recentBlockhash?[3,2]:(i=new a.Connection(t),[4,_(i.getLatestBlockhash.bind(i),[])]);case 1:if(!(l=u.sent()).status)return[2,{status:!1,output:"Failed to get latest blockhash"}];r.recentBlockhash=l.output.blockhash,u.label=2;case 2:return r.feePayer=n.publicKey,[4,_(n.signTransaction.bind(n),[r])];case 3:return[2,u.sent()]}})})},e.prototype.sendSolanaTransaction=function(e,t){return k(this,void 0,void 0,function(){var r;return x(this,function(s){switch(s.label){case 0:return r=new a.Connection(t),[4,_(r.sendRawTransaction.bind(r),[e.serialize()])];case 1:return[2,s.sent()]}})})},e.prototype.signEvmMessage=function(e,t){var r=this.showPrivateKey(t);return O.eth.accounts.sign(e,r).signature},e.prototype.signSolanaMessage=function(e,t){var r=this.showPrivateKey(t),s=y.sign.detached(new Uint8Array(e.match(/.{1,2}/g).map(function(e){return parseInt(e,16)})),v.decode(r));return v.encode(s)},e.prototype.checkIsDisableAddress=function(e,t){if(!e||!this.disable_address)return!1;for(var r=e.length,s=0;s<r;s++){var o=e[s].from,n=e[s].to;if(t>=o&&t<=n)return!0}return!1},e.prototype.reload=function(){if(this.account_labels=A(this.setting_path,this.account_labels),!E(this.setting_path,this.account_labels))throw new Error("Account labels not exist");for(var e={},t=this.account_labels.length,r=0;r<t;r++){var s=f.join(this.setting_path,"accounts/".concat(this.account_labels[r],".json"));if(g.existsSync(s)){var o=JSON.parse(g.readFileSync(s,"utf8"));if("PK"!==o.account_type){var n=o.data.length,i=o.disabled_slots;for(l=0;l<n;l++)this.checkIsDisableAddress(i,l)||(e[o.data[l].ciphertexts.evm.address]={account_label:this.account_labels[r],data:o.data[l].ciphertexts.evm.data},e[o.data[l].ciphertexts.solana.address]={account_label:this.account_labels[r],data:o.data[l].ciphertexts.solana.data})}else{var a=o.data;if(!a)continue;for(var c=a.length,l=0;l<c;l++)e[a[l].ciphertexts.address]={account_label:this.account_labels[r],data:a[l].ciphertexts.data}}}}this.account_ciphertexts=e},e.prototype.getAccountChecksumAddress=function(e){return"evm"===this.getAccountChainType(e)&&(e=O.utils.toChecksumAddress(e)),e},e.prototype.getAccountAddressByPrivateKey=function(e,t){return"evm"===this.getNetworkTypeByChainId(t)?O.eth.accounts.privateKeyToAccount(e).address:a.Keypair.fromSecretKey(v.decode(e)).publicKey.toBase58()},e.prototype.getNetworkTypeByChainId=function(e){return"901"===e||"902"===e||"903"===e?"solana":"evm"},e.prototype.getSubAccount=function(e,t,r){if(!function(e){var t=e.split(/\s+/g),r=t.length;if(12!==r&&24!==r)return!1;for(var s=0;s<r;s++)if(!M.includes(t[s]))return!1;return!0}(t))return{status:!1,output:"Please set correct mnemonic"};if("solana"===e){var s=w.mnemonicToSeedSync(t),o=p.HDKey.fromMasterSeed(s),n=a.Keypair.fromSeed(o.derive("m/44'/501'/".concat(r,"'/0'")).privateKey);return{status:!0,output:{address:n.publicKey.toBase58(),pk:v.encode(n.secretKey)}}}if("evm"===e){s=w.mnemonicToSeedSync(t);var i=(o=u.hdkey.fromMasterSeed(s)).derivePath("m/44'/60'/0'/0").deriveChild(r).getWallet();return{status:!0,output:{address:O.utils.toChecksumAddress(i.getAddressString()),pk:i.getPrivateKeyString()}}}return{status:!1,output:"Unknown chain type"}},e.prototype.getAccountSignature=function(){for(var e=this.account_labels.length,t=[],r=0;r<e;r++){var s=f.join(this.setting_path,"accounts/".concat(this.account_labels[r],".json")),o=g.readFileSync(s,"utf8");t.push(o)}return b.MD5(JSON.stringify(t)).toString()},e}(),L=B,q=function(){function e(e,t,r,s){this.account=new D(e,t,r,s)}return e.version=L.version,e}();e.WativeCore=q,Object.defineProperty(e,"__esModule",{value:!0})}(F.exports,i,t,g,v,w,b,f,S,k,x,_);class W{constructor(t,r){this.runningServices=new Map,this.configManager=new I(t,r),this.pidDir=e.join(this.configManager.getKeystorePath(),"ssh","pids"),this.ensurePidDir(),this.setupLogger()}ensurePidDir(){n.existsSync(this.pidDir)||n.mkdirSync(this.pidDir,{recursive:!0})}async isPortInUse(e,t="127.0.0.1"){return new Promise(r=>{const s=P.createServer();s.listen(e,t,()=>{s.once("close",()=>{r(!1)}),s.close()}),s.on("error",e=>{"EADDRINUSE"===e.code?r(!0):r(!1)})})}getPidFilePath(t){return e.join(this.pidDir,`${t}.pid`)}writePidFile(e,t){const r=this.getPidFilePath(e);n.writeFileSync(r,t.toString())}readPidFile(e){const t=this.getPidFilePath(e);if(!n.existsSync(t))return null;try{const e=n.readFileSync(t,"utf8").trim();return parseInt(e,10)}catch(e){return null}}removePidFile(e){const t=this.getPidFilePath(e);n.existsSync(t)&&n.unlinkSync(t)}isProcessRunning(e){try{return process.kill(e,0),!0}catch(e){return!1}}async startService(e,t){if(this.runningServices.has(e))throw new Error(`Service '${e}' is already running.`);const r=this.configManager.loadServiceConfig(e);if(await this.isPortInUse(r.ssh.port,r.ssh.listen)){const t=`Port ${r.ssh.port} on ${r.ssh.listen} is already in use. Cannot start SSH service '${e}'.`;throw this.logger.error(t),console.error(`Error: ${t}`),new Error(t)}this.logger.info(`Port ${r.ssh.port} on ${r.ssh.listen} is available for service '${e}'`);const s=t||await this.promptForPasswords(r.keystore.allowed_keystores),o=await this.configManager.validateKeystorePasswords(r.keystore.allowed_keystores,s),n=Object.entries(o).filter(([e,t])=>!t).map(([e,t])=>e);if(n.length>0)throw new Error(`Invalid passwords for keystores: ${n.join(", ")}`);const i=this.createServerInstance(r,s);i.listen(r.ssh.listen,r.ssh.port),this.writePidFile(e,process.pid),this.logger.info(`SSH service '${e}' started on ${r.ssh.listen}:${r.ssh.port}`),console.log(`SSH service '${e}' is now running in the background on ${r.ssh.listen}:${r.ssh.port}`);const a={config:r,passwords:s,server:i};this.runningServices.set(e,a),this.setupServiceLogger(e)}async stopService(t){const r=this.runningServices.get(t),s=this.readPidFile(t),o=e.join(this.pidDir,`${t}-daemon.pid`),i=e.join(this.pidDir,`${t}-watcher.pid`);let a=null,c=null;if(n.existsSync(o)){const e=n.readFileSync(o,"utf8").trim();e&&(a=parseInt(e))}if(n.existsSync(i)){const e=n.readFileSync(i,"utf8").trim();e&&(c=parseInt(e))}if(r)r.server&&r.server.close&&r.server.close(),this.runningServices.delete(t);else if(c&&this.isProcessRunning(c))try{process.kill(c,"SIGTERM"),setTimeout(()=>{this.isProcessRunning(c)&&process.kill(c,"SIGKILL");try{n.existsSync(i)&&n.unlinkSync(i),n.existsSync(o)&&n.unlinkSync(o)}catch(e){}},5e3)}catch(e){if(a&&this.isProcessRunning(a))try{process.kill(a,"SIGTERM"),setTimeout(()=>{this.isProcessRunning(a)&&process.kill(a,"SIGKILL")},5e3)}catch(e){}try{n.existsSync(i)&&n.unlinkSync(i),n.existsSync(o)&&n.unlinkSync(o)}catch(e){}}else if(a&&this.isProcessRunning(a))try{process.kill(a,"SIGTERM"),setTimeout(()=>{this.isProcessRunning(a)&&process.kill(a,"SIGKILL")},5e3),n.existsSync(o)&&n.unlinkSync(o)}catch(e){}else{if(!s||!this.isProcessRunning(s))throw new Error(`Service '${t}' is not running.`);try{process.kill(s,"SIGTERM"),setTimeout(()=>{this.isProcessRunning(s)&&process.kill(s,"SIGKILL")},5e3)}catch(e){}}this.removePidFile(t),this.logger.info(`SSH service '${t}' stopped.`)}async restartService(e,t){this.runningServices.has(e)&&await this.stopService(e),await this.startService(e,t)}getRunningServices(){return Array.from(this.runningServices.keys())}getServiceConfig(e){return this.configManager.loadServiceConfig(e)}getServiceStatus(t){if(this.runningServices.has(t))return"running";try{this.configManager.loadServiceConfig(t);const r=e.join(this.pidDir,`${t}-daemon.pid`);if(n.existsSync(r)){const e=n.readFileSync(r,"utf8").trim();if(e){const t=parseInt(e);if(this.isProcessRunning(t))return"running";n.unlinkSync(r)}}const s=this.readPidFile(t);return s&&this.isProcessRunning(s)?"running":(s&&this.removePidFile(t),"stopped")}catch(e){return"not_found"}}async stopAllServices(){const e=Array.from(this.runningServices.keys());for(const t of e)await this.stopService(t)}async createService(e,t,r,s,o){return this.configManager.createServiceConfig(e,t,r,s,o)}async removeService(e){this.runningServices.has(e)&&await this.stopService(e),this.configManager.removeServiceConfig(e),this.logger.info(`Service '${e}' removed.`)}listServices(){return this.configManager.listServiceConfigs().map(e=>{const t=this.getServiceStatus(e);let r,s;try{const t=this.configManager.loadServiceConfig(e);r=t.ssh.port,s=t.description}catch(e){}return{name:e,status:t,port:r,description:s}})}updateServiceKeystores(e,t){this.configManager.updateServiceConfig(e,{keystore:{path:this.configManager.loadServiceConfig(e).keystore.path,allowed_keystores:t}})}async promptForPasswords(e){const t={};for(const r of e){let e,s=!1,o=0;const n=3;for(;!s&&o<n;){e=await E(`Enter password for keystore [${r}]`);try{const i=this.configManager.getKeystorePath();if(s=new F.exports.WativeCore(i,[r]).account.checkPassword(r,e),s){t[r]=e;break}if(o++,!(o<n))throw new Error(`Failed to authenticate keystore [${r}] after ${n} attempts.`);console.log(`Invalid password for ${r}`)}catch(e){if(o++,!(o<n))throw new Error(`Failed to authenticate keystore [${r}] after ${n} attempts: ${e.message}`);console.log("Error validating password for keystore")}}}return t}createServerInstance(e,t){const r=e.clients;if(0===r.length)throw new Error("No clients configured for service");if(r.length>1)throw new Error("Only one client is supported for this service");const s=JSON.parse(r[0]),o=[s.name],n=[s.public_key_path],i=[s.allowed_keystores],a=e.keystore.allowed_keystores;if(0===a.length)throw new Error("No keystores configured for service");let c=[];for(const e of a)c.push(t[e]);return new N(e.server_keys.private_key_path,e.server_keys.passphrase,o,n,i,e.keystore.path,a,c)}async showLogs(t,r=50,s=!1){const i=process.env.HOME+"/.wative/logs";let a;if(a=t?e.join(i,`${t}.log`):e.join(i,"service_manager.log"),!n.existsSync(a))throw new Error(`Log file not found: ${a}`);const c=o("tail",s?["-f",`-n${r}`,a]:[`-n${r}`,a],{stdio:["ignore","inherit","inherit"]});return s?(process.on("SIGINT",()=>{c.kill("SIGTERM"),process.exit(0)}),new Promise((e,t)=>{c.on("close",r=>{0===r?e():t(new Error(`tail process exited with code ${r}`))})})):new Promise((e,t)=>{c.on("close",r=>{0===r?e():t(new Error(`tail process exited with code ${r}`))})})}setupLogger(){const t=process.env.HOME+"/.wative/logs";n.existsSync(t)||n.mkdirSync(t,{recursive:!0}),m.configure({appenders:{file:{type:"file",filename:e.join(t,"service_manager.log"),maxLogSize:10485760,backups:3,compress:!0,keepFileExt:!0,layout:{type:"pattern",pattern:"%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %c - %m"},encoding:"utf-8"},console:{type:"console"}},categories:{default:{appenders:["file","console"],level:"info"}}}),this.logger=m.getLogger("service_manager"),this.logger.level="info"}setupServiceLogger(t){const r=process.env.HOME+"/.wative/logs";n.existsSync(r)||n.mkdirSync(r,{recursive:!0});const s=e.join(r,`${t}.log`);this.cleanupOldLogs(r),m.configure({appenders:{file:{type:"file",filename:e.join(r,"service_manager.log"),maxLogSize:10485760,backups:3,compress:!0,keepFileExt:!0,layout:{type:"pattern",pattern:"%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %c - %m"},encoding:"utf-8"},console:{type:"console"},[`${t}_file`]:{type:"file",filename:s,maxLogSize:10485760,backups:3,compress:!0,keepFileExt:!0,layout:{type:"pattern",pattern:"%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %c - %m"},encoding:"utf-8"}},categories:{default:{appenders:["file","console"],level:"info"},[t]:{appenders:[`${t}_file`],level:"info"}}})}cleanupOldLogs(t){try{const r=n.readdirSync(t),s=new Date;s.setDate(s.getDate()-3),r.forEach(r=>{const o=e.join(t,r);n.statSync(o).mtime<s&&r.endsWith(".log")&&(n.unlinkSync(o),this.logger.info(`Deleted old log file: ${r}`))})}catch(e){this.logger.warn(`Failed to cleanup old logs: ${e}`)}}}const U=new r,G=require("../package.json");let J;U.version(G.version).description("Wative CLI Tool"),U.command("version").description("Show the version of wative").action(()=>{console.log(`Wative CLI Tool v${G.version}`)});const V=()=>{if(!J){const t=e.join(process.env.HOME||"",".wative","ssh");J=new W(t)}return J},Z=U.command("ssh").description("Manage SSH services");Z.command("start").description("Start SSH service").option("-c, --config <name>","Specify service configuration name").option("-d, --daemon","Run service in daemon mode").action(async t=>{const r=V();try{t.config||(console.error("Error: Configuration name is required. Use -c or --config to specify a service configuration."),process.exit(1));const s=t.config,i=r.getServiceConfig(s),a=require("net"),c=async(e,t="127.0.0.1")=>new Promise(r=>{const s=a.createServer();s.listen(e,t,()=>{s.once("close",()=>{r(!1)}),s.close()}),s.on("error",e=>{"EADDRINUSE"===e.code?r(!0):r(!1)})});if(await c(i.ssh.port,i.ssh.listen)){const e=`Port ${i.ssh.port} on ${i.ssh.listen} is already in use. Cannot start SSH service '${s}'.`;console.error(`Error: ${e}`),process.exit(1)}if(console.log(`Port ${i.ssh.port} on ${i.ssh.listen} is available for service '${s}'`),t.daemon){console.log(`Starting SSH service '${s}' in daemon mode...`);const t=await r.promptForPasswords(i.keystore.allowed_keystores),a=require("crypto"),c=a.randomBytes(32),l=a.randomBytes(16),u=a.createCipheriv("aes-256-cbc",c,l);let p=u.update(JSON.stringify(t),"utf8","hex");p+=u.final("hex");const d=l.toString("hex")+":"+c.toString("hex")+":"+p;return void((t,r)=>{const s=e.join(process.env.HOME||"",".wative","logs"),i=e.join(process.env.HOME||"",".wative","ssh","pids");n.existsSync(s)||n.mkdirSync(s,{recursive:!0}),n.existsSync(i)||n.mkdirSync(i,{recursive:!0});const a=e.join(s,`${t}-daemon.log`),c=e.join(i,`${t}-daemon.pid`),l=e.join(i,`${t}-watcher.pid`),u=o("node",[e.resolve(__dirname,"daemon-watcher.js"),t,a,c,l,e.resolve(__dirname,"..")],{detached:!0,stdio:"ignore",env:{...process.env,WATIVE_ENCRYPTED_PASSWORDS:r}});n.writeFileSync(l,u.pid.toString()),u.unref(),console.log(`SSH service '${t}' daemon watcher started with PID: ${u.pid}`),console.log(`Daemon log file: ${a}`),console.log(`Watcher PID file: ${l}`)})(s,d)}if(process.env.WATIVE_DAEMON_PASSWORDS&&process.env.WATIVE_WORKER_MODE){const e=require("crypto"),t=process.env.WATIVE_DAEMON_PASSWORDS;delete process.env.WATIVE_DAEMON_PASSWORDS,delete process.env.WATIVE_WORKER_MODE;try{const r=t.split(":"),o=Buffer.from(r[0],"hex"),n=Buffer.from(r[1],"hex"),i=r[2],a=e.createDecipheriv("aes-256-cbc",n,o);let c=a.update(i,"hex","utf8");c+=a.final("utf8");const l=JSON.parse(c);console.log(`[${(new Date).toISOString()}] Worker process starting SSH service '${s}'...`);const u=V();await u.startService(s,l);for(const e in l)l[e]=null,delete l[e];console.log(`[${(new Date).toISOString()}] SSH service '${s}' started successfully`);const p=async e=>{console.log(`[${(new Date).toISOString()}] Worker received ${e}, stopping service...`);try{await u.stopService(s),console.log(`[${(new Date).toISOString()}] Service stopped successfully`)}catch(e){console.error(`[${(new Date).toISOString()}] Error stopping service:`,e)}process.exit(0)};process.on("SIGTERM",()=>p("SIGTERM")),process.on("SIGINT",()=>p("SIGINT"));const d=setInterval(async()=>{try{const e=await u.getServiceStatus(s);"running"!==e&&(console.log(`[${(new Date).toISOString()}] Service status changed to: ${e}`),"stopped"===e&&(console.log(`[${(new Date).toISOString()}] Service stopped unexpectedly, exiting worker...`),clearInterval(d),process.exit(1)))}catch(e){console.error(`[${(new Date).toISOString()}] Error checking service status:`,e)}},3e4),h=setInterval(()=>{},6e4),g=()=>{clearInterval(d),clearInterval(h)};process.on("exit",g)}catch(e){console.error(`[${(new Date).toISOString()}] Worker process error:`,e),process.exit(1)}return}{await r.startService(s),console.log(`SSH service '${s}' started successfully`),process.on("SIGINT",async()=>{console.log("\nReceived SIGINT, stopping services..."),await r.stopAllServices(),process.exit(0)}),process.on("SIGTERM",async()=>{console.log("\nReceived SIGTERM, stopping services..."),await r.stopAllServices(),process.exit(0)});const e=setInterval(()=>{"running"!==r.getServiceStatus(s)&&(console.log(`Service ${s} is no longer running, exiting...`),clearInterval(e),process.exit(1))},5e3);process.stdin.resume()}}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Z.command("stop").description("Stop SSH service").option("-c, --config <name>","Specify service configuration name").action(async e=>{const t=V();try{e.config||(console.error("Error: Configuration name is required. Use -c or --config to specify a service configuration."),process.exit(1)),await t.stopService(e.config),console.log(`SSH service '${e.config}' stopped successfully`)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Z.command("restart").description("Restart SSH service").option("-c, --config <name>","Specify service configuration name").action(async e=>{const t=V();try{e.config||(console.error("Error: Configuration name is required. Use -c or --config to specify a service configuration."),process.exit(1)),await t.restartService(e.config),console.log(`SSH service '${e.config}' restarted successfully`)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Z.command("create").description("Create new SSH service configuration interactively").action(async()=>{const e=require("readline"),t=require("fs"),r=require("path"),s=e.createInterface({input:process.stdin,output:process.stdout}),o=e=>new Promise(t=>{s.question(e,t)});try{console.log("SSH create command started...");const e=r.join(process.env.HOME||"",".wative/ssh"),s=(await o(`SSH storage located in (default: ${e}): `)).trim()||e,n=r.join(process.env.HOME||"",".wative"),i=(await o(`Keystore storage located in (default: ${n}): `)).trim()||n,a=new I(s,i);let c,l,u,p;for(;;)if(c=await o("Enter service name: "),c.trim())try{a.loadServiceConfig(c),console.log("Service name already exists, please enter a different name")}catch(e){break}else console.log("Service name cannot be empty");for(;;){const e=await o("Enter port number: ");if(l=parseInt(e),isNaN(l)||l<1024||l>65535){console.log("Port number must be between 1024-65535");continue}const t=a.listServiceConfigs();let r=!1;for(const e of t)try{if(a.loadServiceConfig(e).ssh.port===l){r=!0;break}}catch(e){}if(!r)break;console.log(`Port ${l} is already in use by another service, please enter a different port`)}for(;;){const e=await o("Enter allowed keystore list (comma separated): ");if(!e.trim()){console.log("Keystore list cannot be empty");continue}if(u=e.split(",").map(e=>e.trim()).filter(e=>e),0===u.length){console.log("At least one valid keystore is required");continue}const s=r.join(i,"accounts");let n=!0;for(const e of u){const o=r.join(s,`${e}.json`);if(!t.existsSync(o)){console.log(`Keystore '${e}' does not exist`),n=!1;break}}if(n){console.log("All keystores verified to exist");break}console.log("Please re-enter valid keystore list")}for(;p=await o("Enter remote client name: "),!p.trim();)console.log("Client name cannot be empty");const d=r.join(s,"conf.d",c);t.existsSync(d)||t.mkdirSync(d,{recursive:!0});const h=r.join(d,`${p}.pub`);for(console.log("\nPlease place the remote client's public key file at the following path:"),console.log(`${h}`),console.log("\nPress Enter to continue after placing the file...");;){if(await o(""),t.existsSync(h)){console.log("Client public key file found");break}console.log("Client public key file not found, please confirm the file is correctly placed and press Enter again")}const g=await o("Enter service description (optional): ");console.log("\nCreating SSH service configuration...");const f=await a.createServiceConfig(c,l,u,p,g||void 0);console.log("\nNote: Passwords will be requested when starting the service."),console.log(`\nSSH service configuration '${c}' created successfully!`),console.log(`Port: ${l}`),console.log(`Allowed keystores: ${u.join(", ")}`),console.log(`Client name: ${p}`),console.log(`Server private key: ${f.server_keys.private_key_path}`),console.log(`Client public key: ${h}`)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}finally{s.close()}}),Z.command("remove").description("Remove SSH service configuration").option("-c, --config <name>","Service configuration name").action(async e=>{const t=V();try{e.config||(console.error("Error: Configuration name is required for remove command"),process.exit(1)),await t.removeService(e.config),console.log(`SSH service configuration '${e.config}' removed successfully`)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Z.command("list").description("List all SSH service configurations").action(async()=>{const e=new I,t=new W,r=e.listServiceConfigs();if(0!==r.length){console.log("SSH Service Configurations:");for(const s of r)try{const r=e.loadServiceConfig(s),o=t.getServiceStatus(s);console.log(` - ${s}: ${r.description||"No description"} (${o})`)}catch(e){const r=t.getServiceStatus(s);console.log(` - ${s}: Configuration error (${r})`)}}else console.log("No SSH service configurations found.")}),Z.command("status").description("Show SSH service status").option("-c, --config <name>","Service configuration name").action(async e=>{const t=V();try{if(e.config){const r=t.getServiceStatus(e.config);console.log(`SSH service '${e.config}' status: ${r}`)}else{const e=t.listServices();if(0===e.length)return void console.log("No SSH service configurations found");console.log("SSH Service Status:"),e.forEach(e=>{const r=t.getServiceStatus(e.name);console.log(` - ${e.name}: ${r}`)})}}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Z.command("log").description("Show SSH service logs").option("-c, --config <name>","Service configuration name").option("-n, --lines <number>","Number of lines to show (default: 50)","50").option("-f, --follow","Follow log output").action(async e=>{const t=V();try{const r=parseInt(e.lines)||50;await t.showLogs(e.config,r,e.follow)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),U.command("cmd").description("Start wallet-cli shell").action(async()=>{try{s("wallet-cli",{stdio:"inherit"})}catch(e){}}),(require.main===module||process.argv[1]&&(process.argv[1].includes("bin/wative.js")||process.argv[1].includes("wative")||process.argv[1].includes("ssh")))&&U.parse(process.argv);export{U as program};
1
+ import*as e from"path";import t from"path";import{Command as r}from"commander";import{execSync as s,spawn as o}from"child_process";import*as n from"fs";import i,{readFileSync as a}from"fs";import*as c from"ini";import*as l from"crypto";import{timingSafeEqual as u}from"crypto";import{utils as p,Server as d}from"ssh2";import"figlet";import h from"inquirer";import g from"web3";import f from"@solana/web3.js";import"@solana/spl-token";import"@metaplex-foundation/js";import"bignumber.js";import*as m from"log4js";import{ethers as y}from"ethers";import v from"tweetnacl";import w from"bs58";import b from"bip39";import S from"@coral-xyz/anchor";import k from"crypto-js";import x from"ethereumjs-wallet";import _ from"micro-ed25519-hdkey";import*as P from"net";class I{constructor(t,r){this.configDir=t||e.join(require("os").homedir(),".wative/ssh"),this.keystorePath=r||e.join(require("os").homedir(),".wative"),n.existsSync(this.configDir)||n.mkdirSync(this.configDir,{recursive:!0});const s=e.join(this.configDir,"conf.d");n.existsSync(s)||n.mkdirSync(s,{recursive:!0})}getKeystorePath(){return this.keystorePath}getConfigDir(){return this.configDir}async createServiceConfig(e,t,r,s="default_client",o){if(!this.isValidServiceName(e))throw new Error("Invalid service name. Use only alphanumeric characters, hyphens, and underscores.");if(this.isPortInUse(t))throw new Error(`Port ${t} is already in use by another service.`);const n=await this.generateServiceKeyPair(e),i=await this.generateClientKeyPair(e,s),a={name:e,description:o||`Wative SSH Service - ${e}`,ssh:{listen:"127.0.0.1",port:t,log:{size:10485760,backups:3}},keystore:{path:this.keystorePath,allowed_keystores:r},clients:[{name:s,public_key_path:i.publicKey,allowed_keystores:r}],server_keys:{private_key_path:n.privateKey,passphrase:n.passphrase}};return this.saveServiceConfig(e,a),a}loadServiceConfig(e){const t=this.getServiceConfigPath(e);if(!n.existsSync(t))throw new Error(`Service configuration '${e}' not found.`);const r=c.parse(n.readFileSync(t,"utf-8"));return this.parseConfigData(r)}serviceIsExist(t){const r=this.getServiceConfigPath(t);return n.existsSync(e.dirname(r))}listServiceConfigs(){const t=e.join(this.configDir,"conf.d");if(!n.existsSync(t))return[];return n.readdirSync(t).filter(r=>{const s=e.join(t,r);return n.statSync(s).isDirectory()&&n.existsSync(e.join(s,"config.ini"))})}removeServiceConfig(t){const r=this.getServiceConfigPath(t),s=e.dirname(r);n.existsSync(s)&&n.rmSync(s,{recursive:!0})}updateServiceConfig(e,t){const r={...this.loadServiceConfig(e),...t};this.saveServiceConfig(e,r)}async validateKeystorePasswords(e,t){const r={},{WativeCore:s}=require("wative-core");for(const o of e)try{const e=t[o];if(!e){r[o]=!1;continue}const n=new s(this.keystorePath,[o],[e]);r[o]=n.account.isLogin(o)}catch(e){r[o]=!1}return r}isValidServiceName(e){return/^[a-zA-Z0-9_-]+$/.test(e)&&e.length>0&&e.length<=50}isPortInUse(e){const t=this.listServiceConfigs();for(const r of t)try{if(this.loadServiceConfig(r).ssh.port===e)return!0}catch(e){}return!1}async generateServiceKeyPair(t){const r=this.generateSecurePassphrase(),o=e.join(this.configDir,"conf.d",t);n.existsSync(o)||n.mkdirSync(o,{recursive:!0});const i=e.join(o,"server_private_key"),a=e.join(o,"server_public_key.pub");return n.existsSync(i)||(console.log(`Generating SSH server key pair for service '${t}'...`),s(`ssh-keygen -t rsa -b 4096 -f ${i} -N '${r}' -C 'wative_${t}_server'`,{stdio:"inherit"})),{privateKey:i,publicKey:a,passphrase:r}}async generateClientKeyPair(t,r){const s=e.join(this.configDir,"conf.d",t);n.existsSync(s)||n.mkdirSync(s,{recursive:!0});return{privateKey:"",publicKey:e.join(s,`${r}.pub`),passphrase:""}}generateSecurePassphrase(){return l.randomBytes(32).toString("hex")}getServiceConfigPath(t){return e.join(this.configDir,"conf.d",t,"config.ini")}saveServiceConfig(t,r){const s=this.getServiceConfigPath(t),o=e.dirname(s);n.existsSync(o)||n.mkdirSync(o,{recursive:!0});const i=c.stringify(r);n.writeFileSync(s,i)}parseConfigData(e){return{name:e.name,description:e.description,ssh:{listen:e.ssh.listen,port:parseInt(e.ssh.port),log:{size:parseInt(e.ssh.log.size),backups:parseInt(e.ssh.log.backups)}},keystore:{path:e.keystore.path,allowed_keystores:Array.isArray(e.keystore.allowed_keystores)?e.keystore.allowed_keystores:e.keystore.allowed_keystores.split(",")},clients:Array.isArray(e.clients)?e.clients:[e.clients],server_keys:{private_key_path:e.server_keys.private_key_path,passphrase:e.server_keys.passphrase}}}}require("chalk"),require("chalk"),require("chalk"),process.env.HOME||process.env.USERPROFILE;const E=e=>e=(e=(e=(e=e.trim()).toLocaleLowerCase()).replace(/\s+/g,"-").trim()).replace(/\-+/g,"-").trim(),A=async e=>{const t=[{name:"password",type:"password",mask:"#",message:`${e}:`}];let{password:r}=await h.prompt(t);return r};require("bn.js"),require("ethereumjs-util"),require("bignumber.js"),require("chalk"),require("wative-core"),require("chalk"),require("dotenv").config(),require("cli-progress"),require("wative-core");const{WativeCore:j}=require("wative-core"),{Connection:C,PublicKey:$,VersionedTransaction:T,VersionedMessage:K}=require("@solana/web3.js"),M=require("bs58"),{Keypair:O,TransactionMessage:D,ComputeBudgetInstruction:L,TransactionInstruction:q,ComputeBudgetProgram:H}=require("@solana/web3.js"),{Wallet:N}=require("@coral-xyz/anchor");m.configure({appenders:{file:{type:"file",filename:process.env.HOME+"/.wative/logs/wative.log",maxLogSize:10485760,backups:3,compress:!0,keepFileExt:!0,layout:{type:"pattern",pattern:"%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %c - %m"},encoding:"utf-8"},console:{type:"console"}},categories:{default:{appenders:["file","console"],level:"info"}}});const z=m.getLogger("file");z.level="info";class R{constructor(e,t,r,s,o,i,c,l){if(this._allowedAppIds=[],this._allowedPubKeys=[],this._allowedKeystoreIds=[],this._sessionIdAppIdMap={},(e=>{if(e=e.trim(),!n.existsSync(e))throw new Error("File not exists")})(e),0===r.length||0===s.length||0===o.length||r.length!==s.length||r.length!==o.length)throw new Error("WativeWielderServer:: constructor: Invaild AllowedApp");for(let e=0;e<o.length;e++)for(let t=0;t<o[e].length;t++){const r=o[e][t];if(!c.includes(r))throw new Error("WativeWielderServer:: constructor: Invaild AllowedKeystoreIds")}for(let e of r)this._allowedAppIds.push(Buffer.from(e));for(let e of s){let t=p.parseKey(a(e));this._allowedPubKeys.push(t)}this.wativeCore=new j(i,c,l),this._idRsaPrivatePath=e,this._idRsaPassphrase=t,this._allowedKeystoreIds=o,this._keystoreDirectoryPath=i}listen(e,t){new d({hostKeys:[{key:a(this._idRsaPrivatePath),passphrase:this._idRsaPassphrase}]},e=>{e.on("authentication",t=>{let r=!0;if(this&&(this.checkValue(Buffer.from(t.username),"appId")||(r=!1)),"publickey"!==t.method||!r)return t.reject();{let e=this.getBytesIndex(Buffer.from(t.username),this._allowedAppIds),r=this._allowedPubKeys[e];if(t.key.algo!==r.type||!this.checkValue(t.key.data,"publicKey")||t.signature&&!0!==r.verify(t.blob,t.signature,t.hashAlgo))return t.reject()}if(r){const r=e._protocol._kex.sessionID.toString("hex");this._sessionIdAppIdMap[r]=Buffer.from(t.username),t.accept()}else t.reject()}).on("ready",()=>{e.on("session",(t,r)=>{t().once("exec",async(t,r,s)=>{const o=e._protocol._kex.sessionID.toString("hex"),n=await this.web3Request(o,s.command),i=t();i&&(JSON.stringify(n)?(i.write(JSON.stringify(n)),i.exit(0),i.end()):(i.write("ssh2 connect error"),i.exit(0),i.end()))})})}).on("close",()=>{z.info("Client disconnected")}).on("error",e=>{z.error("err: ",e.message)})}).listen(t,e,function(){z.info("Listening on port "+t)})}async web3Request(e,t){try{const r=this._sessionIdAppIdMap[e],s=this.getBytesIndex(r,this._allowedAppIds);if(s<0)return{status:!1,msg:"app not found"};let o=JSON.parse(t);z.info("sign message: ",t);let n=o.method,i=o.keystoreId||o.params.keystoreId,a=o.chainId||o.params.chainId;if(!this._allowedKeystoreIds[s].includes(i))return{status:!1,msg:"keystore not allowed"};let c;if("get_root_account"===n)c=this.getRootAccount(i,a);else if("get_sub_account"===n){let e=o.params;c=this.getSubAccount(i,e.chainId,null==e?void 0:e.startIndex,null==e?void 0:e.endIndex)}else if("sign"===n){let e=o.params;try{c=await this.wativeCore.account.signTransaction(e.txParams.from,e.txParams,e.rpcUrl)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}}else if("sign_and_send"===n){let e=o.params;try{c={transactionHash:await this.wativeCore.account.signAndSendTx(e.txParams,e.rpcUrl)}}catch(e){return{status:!1,msg:e.msg}}}else if("solana_sign"===n)try{let e=o.params;c=await this.signSolanaTransaction(e.txParams.from,e.txParams.data,e.txParams.lookup_tables,e.rpcUrl,e.priority_fee)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}else if("solana_send"===n)try{let e=o.params;c=await this.sendSignedSolanaTransaction(e.txParams.from,e.txParams.signature,e.txParams.data,e.rpcUrl)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}else if("sign_message"===n)try{let e=o.params;z.debug("sign message: ",e),c=await this.signMessage(e.account,e.message)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}else{if("sign_typed_data"!==n)return{status:!1,msg:"message method not find"};try{let e=o.params;z.debug("sign message: ",e),c=await this.signTypedData(e.account,e.domain,e.types_name,e.types,e.message)}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}}return{status:!0,data:c}}catch(e){return z.error("sign error: ",e.message),{status:!1,msg:e.msg}}}checkValue(e,t){if("appId"!==t&&"publicKey"!==t)return!1;let r=this._allowedAppIds.length;for(let s=0;s<r;s++){let r;r="appId"===t?this._allowedAppIds[s]:this._allowedPubKeys[s].getPublicSSH();const o=e.length!==r.length;o&&(r=e);const n=u(e,r);if(!o&&n)return!0}}getBytesIndex(e,t){let r=t.length;for(let s=0;s<r;s++)if(e.length===t[s].length&&u(e,t[s]))return s;return-1}getRootAccount(t,r){const s=e.resolve(this._keystoreDirectoryPath,`accounts/${t}.json`);let o,n=a(s);return n=JSON.parse(n.toString()),o="SOLANA"===this.getChainType(r)?n.data[0].ciphertexts.solana.address:n.data[0].ciphertexts.evm.address,[{id:0,address:o,children:n.data.length,type:"M"}]}getChainType(e){return"901"===e||"902"===e||"903"===e?"SOLANA":"EVM"}getSubAccount(t,r,s,o){const n=e.resolve(this._keystoreDirectoryPath,`accounts/${t}.json`);let i=a(n);i=JSON.parse(i.toString());let c=i.data.length-1;o&&o<c&&(c=o);let l=0;if(s&&s>0&&(l=s),l>c)return[];let u=this.getChainType(r),p=[];for(let e=l;e<=c;e++)p.push(i.data[e].ciphertexts[u.toLocaleLowerCase()].address);return p}async signMessage(e,t){let r=await this.wativeCore.account.signMessage(e,t);return console.log(r),r}async signTypedData(e,t,r,s,o){let n=JSON.parse(t),i=JSON.parse(s),a=JSON.parse(o);console.log(n),console.log(i),console.log(a);let c=this.wativeCore.account.showPrivateKey(e),l=new y.Wallet(c),u=await l.signTypedData(n,{[r]:i},a);return console.log(u),{status:!0,output:u}}async signSolanaTransaction(e,t,r,s,o){let n=new C(s),i=[];if(r)for(let e of r){let t=(await n.getAddressLookupTable(new $(e))).value;i.push(t),await F(1e3)}let a=K.deserialize(Uint8Array.from(Buffer.from(t,"hex"))),c=D.decompile(a);c.instructions.push(H.setComputeUnitLimit({units:2e6})),c.instructions.push(H.setComputeUnitPrice({microLamports:1e3})),a=c.compileToV0Message(i),a.recentBlockhash=(await n.getLatestBlockhash()).blockhash,await F(3e3);let l=new T(a),u=this.wativeCore.account.showPrivateKey(e);const p=O.fromSecretKey(new Uint8Array(M.decode(u))),d=new N(p);let h=await n.simulateTransaction(l);if(!h||!h.value||0===h.value.unitsConsumed||h.value.err)return{status:!1,output:h.value.err};let g=c.instructions.length,f=Math.trunc(1.2*h.value.unitsConsumed);if(c.instructions[g-2]=H.setComputeUnitLimit({units:f}),!o||"null"==o)try{o=await this.getPrioritizationFee(s)}catch(e){o=2e5}o<1e4&&(o=1e4),o>5e5&&(o=5e5),c.instructions[g-1]=H.setComputeUnitPrice({microLamports:o}),a=c.compileToV0Message(i),await F(1e3),a.recentBlockhash=(await n.getLatestBlockhash()).blockhash,l=new T(a),l.feePayer=d.publicKey,await F(3e3);let m=await this.wativeCore.account.signTransaction(e,l,s),y=new T(m.output.message,m.output.signatures).message.serialize();return y=Buffer.from(y).toString("hex"),{status:!0,output:{transactionHash:M.encode(m.output.signatures[0]),message:y,compute_units:h.value.unitsConsumed.toString()}}}async sendSignedSolanaTransaction(e,t,r,s){let o=[M.decode(t)],n=K.deserialize(Uint8Array.from(Buffer.from(r,"hex"))),i=new T(n,o);return await this.wativeCore.account.sendSignedTransaction(e,i,s)}async getPrioritizationFee(e){let t=new $("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4");const r=new C(e,"confirmed");let s=await r.getSignaturesForAddress(t,{limit:5});await F(2e3);let o=[];for(let e=0;e<s.length;e++)o.push(s[e].signature);let n=await r.getParsedTransactions(o,{maxSupportedTransactionVersion:0}),i=0;for(let e=0;e<n.length;e++){let t=n[e].transaction.message.instructions;for(let e=0;e<t.length;e++)if("ComputeBudget111111111111111111111111111111"===t[e].programId.toBase58()){let r=t[e].data;try{let e=new q({keys:[],programId:new $("ComputeBudget111111111111111111111111111111"),data:Buffer.from(M.decode(r))}),{microLamports:t}=L.decodeSetComputeUnitPrice(e);i+=Number(t);continue}catch(e){}}}return Math.ceil(i/5)}}const F=e=>new Promise(t=>setTimeout(t,e));"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;var B={exports:{}},W={name:"wative-core",version:"1.0.21",description:"An agile keystore management toolkit",main:"lib/index.umd.js",module:"lib/index.esm.js",types:"lib/index.d.ts",scripts:{test:"jest",compile:"tsc",build:"rollup --config"},repository:{type:"git",url:""},bugs:{url:"https://github.com"},homepage:"https://github.com",keywords:["keystore","wallet"],author:"",license:"ISC",files:["src/","lib/"],dependencies:{"@babel/plugin-transform-modules-commonjs":"7.24.1","@rollup/plugin-commonjs":"21.0.1","@solana/web3.js":"1.91.8","@types/bs58":"4.0.4","crypto-js":"4.2.0","ethereumjs-wallet":"1.0.2",jest:"27.5.1","micro-ed25519-hdkey":"0.1.2",rollup:"2.79.1","rollup-plugin-terser":"7.0.2","rollup-plugin-typescript2":"0.31.2",tslib:"2.6.2",typescript:"4.9.5",web3:"1.7.3","web3-core":"4.3.2","@coral-xyz/anchor":"0.30.1","@types/crypto-js":"4.2.2","nodejs-threadpool":"1.0.1",tweetnacl:"1.0.3","rpc-websockets":"7.10.0"}};!function(e,t,r,s,o,n,i,a,c,l,u,p){function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function h(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach(function(r){if("default"!==r){var s=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,s.get?s:{enumerable:!0,get:function(){return e[r]}})}}),t.default=e,Object.freeze(t)}var g=h(t),f=h(r),m=d(s),y=h(o),v=h(n),w=h(i),b=h(l),S=function(){return S=Object.assign||function(e){for(var t,r=1,s=arguments.length;r<s;r++)for(var o in t=arguments[r])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e},S.apply(this,arguments)};function k(e,t,r,s){return new(r||(r=Promise))(function(o,n){function i(e){try{c(s.next(e))}catch(e){n(e)}}function a(e){try{c(s.throw(e))}catch(e){n(e)}}function c(e){var t;e.done?o(e.value):(t=e.value,t instanceof r?t:new r(function(e){e(t)})).then(i,a)}c((s=s.apply(e,t||[])).next())})}function x(e,t){var r,s,o,n={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]},i=Object.create(("function"==typeof Iterator?Iterator:Object).prototype);return i.next=a(0),i.throw=a(1),i.return=a(2),"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function a(a){return function(c){return function(a){if(r)throw new TypeError("Generator is already executing.");for(;i&&(i=0,a[0]&&(n=0)),n;)try{if(r=1,s&&(o=2&a[0]?s.return:a[0]?s.throw||((o=s.return)&&o.call(s),0):s.next)&&!(o=o.call(s,a[1])).done)return o;switch(s=0,o&&(a=[2&a[0],o.value]),a[0]){case 0:case 1:o=a;break;case 4:return n.label++,{value:a[1],done:!1};case 5:n.label++,s=a[1],a=[0];continue;case 7:a=n.ops.pop(),n.trys.pop();continue;default:if(!((o=(o=n.trys).length>0&&o[o.length-1])||6!==a[0]&&2!==a[0])){n=0;continue}if(3===a[0]&&(!o||a[1]>o[0]&&a[1]<o[3])){n.label=a[1];break}if(6===a[0]&&n.label<o[1]){n.label=o[1],o=a;break}if(o&&n.label<o[2]){n.label=o[2],n.ops.push(a);break}o[2]&&n.ops.pop(),n.trys.pop();continue}a=t.call(e,n)}catch(e){a=[6,e],s=0}finally{r=o=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}"function"==typeof SuppressedError&&SuppressedError;var _=function(e,t){return k(void 0,void 0,void 0,function(){var r,s,o;return x(this,function(n){switch(n.label){case 0:return n.trys.push([0,2,,3]),[4,e.apply(void 0,t)];case 1:return s=n.sent(),r={status:!0,output:s},[3,3];case 2:return o=n.sent(),r={status:!1,output:o.toString()},[3,3];case 3:return[2,r]}})})},P=function(){function e(e){this.web3=new m.default(e)}return e.prototype.getEvmGasPrice=function(){return k(this,void 0,void 0,function(){return x(this,function(e){switch(e.label){case 0:return[4,_(this.web3.eth.getGasPrice,[])];case 1:return[2,e.sent()]}})})},e.prototype.getEvmGasLimit=function(e,t){return k(this,void 0,void 0,function(){return x(this,function(r){switch(r.label){case 0:return[4,_(this.web3.eth.estimateGas,[e,t])];case 1:return[2,r.sent()]}})})},e}(),I=function(e){return e=e.trim(),g.existsSync(e)},E=function(e,t){var r=t.length;if(0===r)return!0;for(var s=0;s<r;s++){var o=f.join(e,"accounts/".concat(t[s],".json"));if(!I(o))return!1}return!0},A=function(e){return(e=(e=(e=e.trim()).toLocaleLowerCase()).replace(/\s+/g,"-").trim()).replace(/\-+/g,"-").trim()},j=function(e,t){var r=[],s=f.join(e,"network.json");if(!I(s))throw new Error("network.json not found");for(var o=function(e){for(var t=[],r=0;r<e.length;r++)t.push(A(e[r]));return t}(C(s).accounts),n=0;n<t.length;n++)o.includes(t[n])&&r.push(t[n]);return r},C=function(e){var t=g.readFileSync(e).toString();return JSON.parse(t)},$=function(e,t){var r=JSON.stringify(e);g.writeFileSync(t,r)},T=function(e,t){return b.AES.encrypt(e,t).toString()},K=function(e,t){return b.AES.decrypt(e,t).toString(b.enc.Utf8)},M=["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","library","license","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","type","typical","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"],O=new m.default(m.default.givenProvider),D=function(){function e(e,t,r,s){if(this.account_passwords={},this.account_ciphertexts={},this.disable_address=!1,this.account_signatures="",this.setting_path=e,this.account_labels=t,0!==t.length){if(r){if(t.length!==r.length)throw new Error("account_labels should have same length for account_passwords");for(var o=0;o<t.length;o++){if(!this.checkPassword(t[o],r[o].trim()))throw new Error("account_passwords is not correct");this.account_passwords[t[o]]=r[o].trim()}}s&&(this.disable_address=s),this.reload()}}return e.prototype.isLogin=function(e){return e in this.account_passwords},e.prototype.reloadAccount=function(){this.reload()},e.prototype.getAccountLabel=function(e){var t=null;for(var r in this.account_ciphertexts)r.toLocaleLowerCase().includes(e.toLocaleLowerCase())&&(t=r);return null===t?null:{account_address:t,account_label:this.account_ciphertexts[t].account_label}},e.prototype.login=function(e,t){return this.checkPassword(e,t)?(this.account_passwords[e]=t,this.account_labels.push(e),this.reload(),{status:!0,output:"Login success"}):{status:!1,output:"Password is not correct"}},e.prototype.getAccounts=function(e){var t=this.getAccountSignature();t!==this.account_signatures&&(this.account_signatures=t,this.reload());for(var r=Object.keys(this.account_ciphertexts),s=[],o=0;o<r.length;o++)this.getAccountChainType(r[o])===e&&s.push(r[o]);return s},e.prototype.checkAccountLabelIsExist=function(e){return E(this.setting_path,[e])},e.prototype.checkAccountIsExist=function(e){return(e=this.getAccountChecksumAddress(e))in this.account_ciphertexts||(this.reload(),e in this.account_ciphertexts)},e.prototype.checkPassword=function(e,t){var r=f.join(this.setting_path,"accounts/".concat(e,".json"));if(!I(r))return!1;var s,o=C(r);s="PK"===o.account_type?S({salt:t},o.data[0].ciphertexts):{slat:t,data:o.pp_ciphertexts};var n=b.SHA256(JSON.stringify(s)).toString();return o.signature===n},e.prototype.showPrivateKey=function(e){if(!this.checkAccountIsExist(e))throw new Error("Account is not exist");e=this.getAccountChecksumAddress(e);var t=this.account_ciphertexts[e],r=this.account_passwords[t.account_label];return K(t.data,r)},e.prototype.getAccountChainType=function(e){return e.startsWith("0x")&&42===e.length?"evm":/^[A-HJ-NP-Za-km-z1-9]*$/.test(e)?"solana":"unknown"},e.prototype.generatePKAccount=function(e,t,r,s,o){if(o&&this.checkAccountLabelIsExist(e))throw new Error("Account labels already exist");if(!o&&!this.account_passwords[e])throw new Error("Password is not correct");o||(r=this.account_passwords[e]);var n,i=T(t,r);try{n=this.getAccountAddressByPrivateKey(t,s)}catch(e){return{status:!1,output:e.message}}var a={address:n,data:i},c=S({salt:r},a),l={signature:b.SHA256(JSON.stringify(c)).toString(),account_type:"PK",tag:"",ciphertexts:a};return o||(this.account_passwords[e]=r,this.account_labels.push(e)),{status:!0,output:l}},e.prototype.generatePPAccount=function(e,t,r){if(this.checkAccountLabelIsExist(e))return{status:!1,output:"Account labels already exist"};var s=T(t,r),o={slat:r,data:s},n=b.SHA256(JSON.stringify(o)).toString(),i=this.getSubAccount("evm",t,0);if(!1===i.status)return{status:!1,output:i.output};var a=this.getSubAccount("solana",t,0);if(!1===a.status)return{status:!1,output:a.output};var c={signature:n,account_type:"PP",pp_ciphertexts:s,tag:"",data:[{ciphertexts:{evm:{address:i.output.address,data:T(i.output.pk,r)},solana:{address:a.output.address,data:T(a.output.pk,r)}}}]};return this.account_passwords[e]=r,this.account_labels.push(e),{status:!0,output:c}},e.prototype.generateSubAccount=function(e,t){if(!this.checkAccountLabelIsExist(e))return{status:!1,output:"Account labels not exist"};var r=f.join(this.setting_path,"accounts/".concat(e,".json")),s=C(r).pp_ciphertexts,o=K(s,this.account_passwords[e]),n=this.getSubAccount("evm",o,t);if(!1===n.status)return{status:!1,output:n.output};var i=this.getSubAccount("solana",o,t);return!1===i.status?{status:!1,output:i.output}:{status:!0,output:{evm:{address:n.output.address,data:T(n.output.pk,this.account_passwords[e])},solana:{address:i.output.address,data:T(i.output.pk,this.account_passwords[e])}}}},e.prototype.resetPassword=function(e,t){if(!this.checkAccountLabelIsExist(e))return{status:!1,output:"Account labels not exist"};if(!this.checkPassword(e,this.account_passwords[e]))return{status:!1,output:"account passwords is not correct"};var r=f.join(this.setting_path,"accounts/".concat(e,".json")),s=C(r);if("PK"===s.account_type){for(var o=s.data,n=0;n<o.length;n++){var i=o[n].ciphertexts.data,a=K(i,this.account_passwords[e]);o[n].ciphertexts.data=T(a,t)}var c=S({salt:t},s.data[0].ciphertexts);return s.signature=b.SHA256(JSON.stringify(c)).toString(),$(s,r),delete this.account_passwords[e],{status:!0,output:"Password reset successfully"}}var l=K(s.pp_ciphertexts,this.account_passwords[e]);s.pp_ciphertexts=T(l,t);var u={slat:t,data:s.pp_ciphertexts};s.signature=b.SHA256(JSON.stringify(u)).toString();var p=s.data;for(n=0;n<p.length;n++){var d=K(p[n].ciphertexts.evm.data,this.account_passwords[e]);p[n].ciphertexts.evm.data=T(d,t);var h=K(p[n].ciphertexts.solana.data,this.account_passwords[e]);p[n].ciphertexts.solana.data=T(h,t)}return $(s,r),delete this.account_passwords[e],{status:!0,output:"Password reset successfully"}},e.prototype.signTransaction=function(e,t,r){return e=this.getAccountChecksumAddress(e),this.checkAccountIsExist(e)?"unknown"===this.getAccountChainType(e)?{status:!1,output:"Chain type unknown"}:"evm"===this.getAccountChainType(e)?this.signEvmTransaction(t,r):this.signSolanaTransaction(e,r,t):{status:!1,output:"Account is not exist"}},e.prototype.sendSignedTransaction=function(e,t,r){return e=this.getAccountChecksumAddress(e),this.checkAccountIsExist(e)?"unknown"===this.getAccountChainType(e)?{status:!1,output:"Chain type unknown"}:"evm"===this.getAccountChainType(e)?this.sendEvmTransaction(t,r):this.sendSolanaTransaction(t,r):{status:!1,output:"Account is not exist"}},e.prototype.signMessage=function(e,t){return e=this.getAccountChecksumAddress(e),this.checkAccountIsExist(e)?"unknown"===this.getAccountChainType(e)?{status:!1,output:"Chain type unknown"}:"evm"===this.getAccountChainType(e)?{status:!0,output:this.signEvmMessage(t,e)}:{status:!0,output:this.signSolanaMessage(t,e)}:{status:!1,output:"Account is not exist"}},e.prototype.simulateTransaction=function(e,t,r){return k(this,void 0,void 0,function(){var s,o,n;return x(this,function(i){switch(i.label){case 0:return s=new a.Connection(t),o=this.showPrivateKey(e),n=a.Keypair.fromSecretKey(v.decode(o)),[4,_(s.simulateTransaction.bind(s),[r,[n]])];case 1:return[2,i.sent()]}})})},e.prototype.signEvmTransaction=function(e,t){return k(this,void 0,void 0,function(){var r,s,o,n;return x(this,function(i){switch(i.label){case 0:return this.account_passwords?(r=e.from,e.gas?[3,2]:[4,new P(t).getEvmGasLimit(e,t)]):[2,{status:!1,output:"Please set password first"}];case 1:if(!(s=i.sent()).status)return[2,s];e.gas=s.output,i.label=2;case 2:return e.gasPrice?[3,4]:[4,new P(t).getEvmGasPrice()];case 3:if(!(s=i.sent()).status)return[2,s];e.gasPrice=s.output,i.label=4;case 4:return o=this.showPrivateKey(r),n=new m.default(t),[4,_(n.eth.accounts.signTransaction.bind(n.eth.accounts),[e,o])];case 5:return[2,i.sent()]}})})},e.prototype.sendEvmTransaction=function(e,t){return k(this,void 0,void 0,function(){var r;return x(this,function(s){switch(s.label){case 0:return r=new m.default(t),[4,_(r.eth.sendSignedTransaction.bind(r.eth),[e])];case 1:return[2,s.sent()]}})})},e.prototype.signSolanaTransaction=function(e,t,r){return k(this,void 0,void 0,function(){var s,o,n,i,l;return x(this,function(u){switch(u.label){case 0:return s=this.showPrivateKey(e),o=a.Keypair.fromSecretKey(v.decode(s)),n=new c.Wallet(o),"recentBlockhash"in r&&r.recentBlockhash?[3,2]:(i=new a.Connection(t),[4,_(i.getLatestBlockhash.bind(i),[])]);case 1:if(!(l=u.sent()).status)return[2,{status:!1,output:"Failed to get latest blockhash"}];r.recentBlockhash=l.output.blockhash,u.label=2;case 2:return r.feePayer=n.publicKey,[4,_(n.signTransaction.bind(n),[r])];case 3:return[2,u.sent()]}})})},e.prototype.sendSolanaTransaction=function(e,t){return k(this,void 0,void 0,function(){var r;return x(this,function(s){switch(s.label){case 0:return r=new a.Connection(t),[4,_(r.sendRawTransaction.bind(r),[e.serialize()])];case 1:return[2,s.sent()]}})})},e.prototype.signEvmMessage=function(e,t){var r=this.showPrivateKey(t);return O.eth.accounts.sign(e,r).signature},e.prototype.signSolanaMessage=function(e,t){var r=this.showPrivateKey(t),s=y.sign.detached(new Uint8Array(e.match(/.{1,2}/g).map(function(e){return parseInt(e,16)})),v.decode(r));return v.encode(s)},e.prototype.checkIsDisableAddress=function(e,t){if(!e||!this.disable_address)return!1;for(var r=e.length,s=0;s<r;s++){var o=e[s].from,n=e[s].to;if(t>=o&&t<=n)return!0}return!1},e.prototype.reload=function(){if(this.account_labels=j(this.setting_path,this.account_labels),!E(this.setting_path,this.account_labels))throw new Error("Account labels not exist");for(var e={},t=this.account_labels.length,r=0;r<t;r++){var s=f.join(this.setting_path,"accounts/".concat(this.account_labels[r],".json"));if(g.existsSync(s)){var o=JSON.parse(g.readFileSync(s,"utf8"));if("PK"!==o.account_type){var n=o.data.length,i=o.disabled_slots;for(l=0;l<n;l++)this.checkIsDisableAddress(i,l)||(e[o.data[l].ciphertexts.evm.address]={account_label:this.account_labels[r],data:o.data[l].ciphertexts.evm.data},e[o.data[l].ciphertexts.solana.address]={account_label:this.account_labels[r],data:o.data[l].ciphertexts.solana.data})}else{var a=o.data;if(!a)continue;for(var c=a.length,l=0;l<c;l++)e[a[l].ciphertexts.address]={account_label:this.account_labels[r],data:a[l].ciphertexts.data}}}}this.account_ciphertexts=e},e.prototype.getAccountChecksumAddress=function(e){return"evm"===this.getAccountChainType(e)&&(e=O.utils.toChecksumAddress(e)),e},e.prototype.getAccountAddressByPrivateKey=function(e,t){return"evm"===this.getNetworkTypeByChainId(t)?O.eth.accounts.privateKeyToAccount(e).address:a.Keypair.fromSecretKey(v.decode(e)).publicKey.toBase58()},e.prototype.getNetworkTypeByChainId=function(e){return"901"===e||"902"===e||"903"===e?"solana":"evm"},e.prototype.getSubAccount=function(e,t,r){if(!function(e){var t=e.split(/\s+/g),r=t.length;if(12!==r&&24!==r)return!1;for(var s=0;s<r;s++)if(!M.includes(t[s]))return!1;return!0}(t))return{status:!1,output:"Please set correct mnemonic"};if("solana"===e){var s=w.mnemonicToSeedSync(t),o=p.HDKey.fromMasterSeed(s),n=a.Keypair.fromSeed(o.derive("m/44'/501'/".concat(r,"'/0'")).privateKey);return{status:!0,output:{address:n.publicKey.toBase58(),pk:v.encode(n.secretKey)}}}if("evm"===e){s=w.mnemonicToSeedSync(t);var i=(o=u.hdkey.fromMasterSeed(s)).derivePath("m/44'/60'/0'/0").deriveChild(r).getWallet();return{status:!0,output:{address:O.utils.toChecksumAddress(i.getAddressString()),pk:i.getPrivateKeyString()}}}return{status:!1,output:"Unknown chain type"}},e.prototype.getAccountSignature=function(){for(var e=this.account_labels.length,t=[],r=0;r<e;r++){var s=f.join(this.setting_path,"accounts/".concat(this.account_labels[r],".json")),o=g.readFileSync(s,"utf8");t.push(o)}return b.MD5(JSON.stringify(t)).toString()},e}(),L=W,q=function(){function e(e,t,r,s){this.account=new D(e,t,r,s)}return e.version=L.version,e}();e.WativeCore=q,Object.defineProperty(e,"__esModule",{value:!0})}(B.exports,i,t,g,v,w,b,f,S,k,x,_);class U{constructor(t,r){this.runningServices=new Map,this.configManager=new I(t,r),this.pidDir=e.join(this.configManager.getKeystorePath(),"ssh","pids"),this.ensurePidDir(),this.setupLogger()}ensurePidDir(){n.existsSync(this.pidDir)||n.mkdirSync(this.pidDir,{recursive:!0})}async isPortInUse(e,t="127.0.0.1"){return new Promise(r=>{const s=P.createServer();s.listen(e,t,()=>{s.once("close",()=>{r(!1)}),s.close()}),s.on("error",e=>{"EADDRINUSE"===e.code?r(!0):r(!1)})})}getPidFilePath(t){return e.join(this.pidDir,`${t}.pid`)}writePidFile(e,t){const r=this.getPidFilePath(e);n.writeFileSync(r,t.toString())}readPidFile(e){const t=this.getPidFilePath(e);if(!n.existsSync(t))return null;try{const e=n.readFileSync(t,"utf8").trim();return parseInt(e,10)}catch(e){return null}}removePidFile(e){const t=this.getPidFilePath(e);n.existsSync(t)&&n.unlinkSync(t)}isProcessRunning(e){try{return process.kill(e,0),!0}catch(e){return!1}}async startService(e,t){if(this.runningServices.has(e))throw new Error(`Service '${e}' is already running.`);const r=this.configManager.loadServiceConfig(e);if(await this.isPortInUse(r.ssh.port,r.ssh.listen)){const t=`Port ${r.ssh.port} on ${r.ssh.listen} is already in use. Cannot start SSH service '${e}'.`;throw this.logger.error(t),console.error(`Error: ${t}`),new Error(t)}this.logger.info(`Port ${r.ssh.port} on ${r.ssh.listen} is available for service '${e}'`);const s=t||await this.promptForPasswords(r.keystore.allowed_keystores),o=await this.configManager.validateKeystorePasswords(r.keystore.allowed_keystores,s),n=Object.entries(o).filter(([e,t])=>!t).map(([e,t])=>e);if(n.length>0)throw new Error(`Invalid passwords for keystores: ${n.join(", ")}`);const i=this.createServerInstance(r,s);i.listen(r.ssh.listen,r.ssh.port),this.writePidFile(e,process.pid),this.logger.info(`SSH service '${e}' started on ${r.ssh.listen}:${r.ssh.port}`),console.log(`SSH service '${e}' is now running in the background on ${r.ssh.listen}:${r.ssh.port}`);const a={config:r,passwords:s,server:i};this.runningServices.set(e,a),this.setupServiceLogger(e)}async stopService(t){const r=this.runningServices.get(t),s=this.readPidFile(t),o=e.join(this.pidDir,`${t}-daemon.pid`),i=e.join(this.pidDir,`${t}-watcher.pid`);let a=null,c=null;if(n.existsSync(o)){const e=n.readFileSync(o,"utf8").trim();e&&(a=parseInt(e))}if(n.existsSync(i)){const e=n.readFileSync(i,"utf8").trim();e&&(c=parseInt(e))}if(r)r.server&&r.server.close&&r.server.close(),this.runningServices.delete(t);else if(c&&this.isProcessRunning(c))try{process.kill(c,"SIGTERM"),setTimeout(()=>{this.isProcessRunning(c)&&process.kill(c,"SIGKILL");try{n.existsSync(i)&&n.unlinkSync(i),n.existsSync(o)&&n.unlinkSync(o)}catch(e){}},5e3)}catch(e){if(a&&this.isProcessRunning(a))try{process.kill(a,"SIGTERM"),setTimeout(()=>{this.isProcessRunning(a)&&process.kill(a,"SIGKILL")},5e3)}catch(e){}try{n.existsSync(i)&&n.unlinkSync(i),n.existsSync(o)&&n.unlinkSync(o)}catch(e){}}else if(a&&this.isProcessRunning(a))try{process.kill(a,"SIGTERM"),setTimeout(()=>{this.isProcessRunning(a)&&process.kill(a,"SIGKILL")},5e3),n.existsSync(o)&&n.unlinkSync(o)}catch(e){}else{if(!s||!this.isProcessRunning(s))throw new Error(`Service '${t}' is not running.`);try{process.kill(s,"SIGTERM"),setTimeout(()=>{this.isProcessRunning(s)&&process.kill(s,"SIGKILL")},5e3)}catch(e){}}this.removePidFile(t),this.logger.info(`SSH service '${t}' stopped.`)}async restartService(e,t){this.runningServices.has(e)&&await this.stopService(e),await this.startService(e,t)}getRunningServices(){return Array.from(this.runningServices.keys())}getServiceConfig(e){return this.configManager.loadServiceConfig(e)}getServiceStatus(t){if(this.runningServices.has(t))return"running";try{this.configManager.loadServiceConfig(t);const r=e.join(this.pidDir,`${t}-daemon.pid`);if(n.existsSync(r)){const e=n.readFileSync(r,"utf8").trim();if(e){const t=parseInt(e);if(this.isProcessRunning(t))return"running";n.unlinkSync(r)}}const s=this.readPidFile(t);return s&&this.isProcessRunning(s)?"running":(s&&this.removePidFile(t),"stopped")}catch(e){return"not_found"}}async stopAllServices(){const e=Array.from(this.runningServices.keys());for(const t of e)await this.stopService(t)}async createService(e,t,r,s,o){return this.configManager.createServiceConfig(e,t,r,s,o)}async removeService(e){this.runningServices.has(e)&&await this.stopService(e),console.log("serviceName:",e),this.configManager.removeServiceConfig(e),this.logger.info(`Service '${e}' removed.`)}listServices(){return this.configManager.listServiceConfigs().map(e=>{const t=this.getServiceStatus(e);let r,s;try{const t=this.configManager.loadServiceConfig(e);r=t.ssh.port,s=t.description}catch(e){}return{name:e,status:t,port:r,description:s}})}updateServiceKeystores(e,t){this.configManager.updateServiceConfig(e,{keystore:{path:this.configManager.loadServiceConfig(e).keystore.path,allowed_keystores:t}})}async promptForPasswords(e){const t={};for(const r of e){let e,s=!1,o=0;const n=3;for(;!s&&o<n;){e=await A(`Enter password for keystore [${r}]`);try{const i=this.configManager.getKeystorePath();if(s=new B.exports.WativeCore(i,[r]).account.checkPassword(r,e),s){t[r]=e;break}if(o++,!(o<n))throw new Error(`Failed to authenticate keystore [${r}] after ${n} attempts.`);console.log(`Invalid password for ${r}`)}catch(e){if(o++,!(o<n))throw new Error(`Failed to authenticate keystore [${r}] after ${n} attempts: ${e.message}`);console.log("Error validating password for keystore")}}}return t}createServerInstance(e,t){const r=e.clients;if(0===r.length)throw new Error("No clients configured for service");if(r.length>1)throw new Error("Only one client is supported for this service");const s=JSON.parse(r[0]),o=[s.name],n=[s.public_key_path],i=[s.allowed_keystores],a=e.keystore.allowed_keystores;if(0===a.length)throw new Error("No keystores configured for service");let c=[];for(const e of a)c.push(t[e]);return new R(e.server_keys.private_key_path,e.server_keys.passphrase,o,n,i,e.keystore.path,a,c)}async showLogs(t,r=50,s=!1){const i=process.env.HOME+"/.wative/logs";let a;if(a=t?e.join(i,`${t}.log`):e.join(i,"service_manager.log"),!n.existsSync(a))throw new Error(`Log file not found: ${a}`);const c=o("tail",s?["-f",`-n${r}`,a]:[`-n${r}`,a],{stdio:["ignore","inherit","inherit"]});return s?(process.on("SIGINT",()=>{c.kill("SIGTERM"),process.exit(0)}),new Promise((e,t)=>{c.on("close",r=>{0===r?e():t(new Error(`tail process exited with code ${r}`))})})):new Promise((e,t)=>{c.on("close",r=>{0===r?e():t(new Error(`tail process exited with code ${r}`))})})}setupLogger(){const t=process.env.HOME+"/.wative/logs";n.existsSync(t)||n.mkdirSync(t,{recursive:!0}),m.configure({appenders:{file:{type:"file",filename:e.join(t,"service_manager.log"),maxLogSize:10485760,backups:3,compress:!0,keepFileExt:!0,layout:{type:"pattern",pattern:"%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %c - %m"},encoding:"utf-8"},console:{type:"console"}},categories:{default:{appenders:["file","console"],level:"info"}}}),this.logger=m.getLogger("service_manager"),this.logger.level="info"}setupServiceLogger(t){const r=process.env.HOME+"/.wative/logs";n.existsSync(r)||n.mkdirSync(r,{recursive:!0});const s=e.join(r,`${t}.log`);this.cleanupOldLogs(r),m.configure({appenders:{file:{type:"file",filename:e.join(r,"service_manager.log"),maxLogSize:10485760,backups:3,compress:!0,keepFileExt:!0,layout:{type:"pattern",pattern:"%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %c - %m"},encoding:"utf-8"},console:{type:"console"},[`${t}_file`]:{type:"file",filename:s,maxLogSize:10485760,backups:3,compress:!0,keepFileExt:!0,layout:{type:"pattern",pattern:"%d{yyyy-MM-dd hh:mm:ss.SSS} [%p] %c - %m"},encoding:"utf-8"}},categories:{default:{appenders:["file","console"],level:"info"},[t]:{appenders:[`${t}_file`],level:"info"}}})}cleanupOldLogs(t){try{const r=n.readdirSync(t),s=new Date;s.setDate(s.getDate()-3),r.forEach(r=>{const o=e.join(t,r);n.statSync(o).mtime<s&&r.endsWith(".log")&&(n.unlinkSync(o),this.logger.info(`Deleted old log file: ${r}`))})}catch(e){this.logger.warn(`Failed to cleanup old logs: ${e}`)}}}const G=new r,J=require("../package.json");let V;G.version(J.version).description("Wative CLI Tool"),G.command("version").description("Show the version of wative").action(()=>{console.log(`Wative CLI Tool v${J.version}`)});const Z=()=>{if(!V){const t=e.join(process.env.HOME||"",".wative","ssh");V=new U(t)}return V},Q=G.command("ssh").description("Manage SSH services");Q.command("start").description("Start SSH service").option("-c, --config <name>","Specify service configuration name").option("-d, --daemon","Run service in daemon mode").action(async t=>{const r=Z();try{t.config||(console.error("Error: Configuration name is required. Use -c or --config to specify a service configuration."),process.exit(1));const s=t.config,i=r.getServiceConfig(s),a=require("net"),c=async(e,t="127.0.0.1")=>new Promise(r=>{const s=a.createServer();s.listen(e,t,()=>{s.once("close",()=>{r(!1)}),s.close()}),s.on("error",e=>{"EADDRINUSE"===e.code?r(!0):r(!1)})});if(await c(i.ssh.port,i.ssh.listen)){const e=`Port ${i.ssh.port} on ${i.ssh.listen} is already in use. Cannot start SSH service '${s}'.`;console.error(`Error: ${e}`),process.exit(1)}if(console.log(`Port ${i.ssh.port} on ${i.ssh.listen} is available for service '${s}'`),t.daemon){console.log(`Starting SSH service '${s}' in daemon mode...`);const t=await r.promptForPasswords(i.keystore.allowed_keystores),a=require("crypto"),c=a.randomBytes(32),l=a.randomBytes(16),u=a.createCipheriv("aes-256-cbc",c,l);let p=u.update(JSON.stringify(t),"utf8","hex");p+=u.final("hex");const d=l.toString("hex")+":"+c.toString("hex")+":"+p;return void((t,r)=>{const s=e.join(process.env.HOME||"",".wative","logs"),i=e.join(process.env.HOME||"",".wative","ssh","pids");n.existsSync(s)||n.mkdirSync(s,{recursive:!0}),n.existsSync(i)||n.mkdirSync(i,{recursive:!0});const a=e.join(s,`${t}-daemon.log`),c=e.join(i,`${t}-daemon.pid`),l=e.join(i,`${t}-watcher.pid`),u=o("node",[e.resolve(__dirname,"daemon-watcher.js"),t,a,c,l,e.resolve(__dirname,"..")],{detached:!0,stdio:"ignore",env:{...process.env,WATIVE_ENCRYPTED_PASSWORDS:r}});n.writeFileSync(l,u.pid.toString()),u.unref(),console.log(`SSH service '${t}' daemon watcher started with PID: ${u.pid}`),console.log(`Daemon log file: ${a}`),console.log(`Watcher PID file: ${l}`)})(s,d)}if(process.env.WATIVE_DAEMON_PASSWORDS&&process.env.WATIVE_WORKER_MODE){const e=require("crypto"),t=process.env.WATIVE_DAEMON_PASSWORDS;delete process.env.WATIVE_DAEMON_PASSWORDS,delete process.env.WATIVE_WORKER_MODE;try{const r=t.split(":"),o=Buffer.from(r[0],"hex"),n=Buffer.from(r[1],"hex"),i=r[2],a=e.createDecipheriv("aes-256-cbc",n,o);let c=a.update(i,"hex","utf8");c+=a.final("utf8");const l=JSON.parse(c);console.log(`[${(new Date).toISOString()}] Worker process starting SSH service '${s}'...`);const u=Z();await u.startService(s,l);for(const e in l)l[e]=null,delete l[e];console.log(`[${(new Date).toISOString()}] SSH service '${s}' started successfully`);const p=async e=>{console.log(`[${(new Date).toISOString()}] Worker received ${e}, stopping service...`);try{await u.stopService(s),console.log(`[${(new Date).toISOString()}] Service stopped successfully`)}catch(e){console.error(`[${(new Date).toISOString()}] Error stopping service:`,e)}process.exit(0)};process.on("SIGTERM",()=>p("SIGTERM")),process.on("SIGINT",()=>p("SIGINT"));const d=setInterval(async()=>{try{const e=await u.getServiceStatus(s);"running"!==e&&(console.log(`[${(new Date).toISOString()}] Service status changed to: ${e}`),"stopped"===e&&(console.log(`[${(new Date).toISOString()}] Service stopped unexpectedly, exiting worker...`),clearInterval(d),process.exit(1)))}catch(e){console.error(`[${(new Date).toISOString()}] Error checking service status:`,e)}},3e4),h=setInterval(()=>{},6e4),g=()=>{clearInterval(d),clearInterval(h)};process.on("exit",g)}catch(e){console.error(`[${(new Date).toISOString()}] Worker process error:`,e),process.exit(1)}return}{await r.startService(s),console.log(`SSH service '${s}' started successfully`),process.on("SIGINT",async()=>{console.log("\nReceived SIGINT, stopping services..."),await r.stopAllServices(),process.exit(0)}),process.on("SIGTERM",async()=>{console.log("\nReceived SIGTERM, stopping services..."),await r.stopAllServices(),process.exit(0)});const e=setInterval(()=>{"running"!==r.getServiceStatus(s)&&(console.log(`Service ${s} is no longer running, exiting...`),clearInterval(e),process.exit(1))},5e3);process.stdin.resume()}}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Q.command("stop").description("Stop SSH service").option("-c, --config <name>","Specify service configuration name").action(async e=>{const t=Z();try{e.config||(console.error("Error: Configuration name is required. Use -c or --config to specify a service configuration."),process.exit(1)),await t.stopService(e.config),console.log(`SSH service '${e.config}' stopped successfully`)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Q.command("restart").description("Restart SSH service").option("-c, --config <name>","Specify service configuration name").action(async e=>{const t=Z();try{e.config||(console.error("Error: Configuration name is required. Use -c or --config to specify a service configuration."),process.exit(1)),await t.restartService(e.config),console.log(`SSH service '${e.config}' restarted successfully`)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Q.command("create").description("Create new SSH service configuration interactively").action(async()=>{const e=require("readline"),t=require("fs"),r=require("path"),s=e.createInterface({input:process.stdin,output:process.stdout}),o=e=>new Promise(t=>{s.question(e,t)});try{console.log("SSH create command started...");const e=r.join(process.env.HOME||"",".wative/ssh"),s=(await o(`SSH storage located in (default: ${e}): `)).trim()||e,n=r.join(process.env.HOME||"",".wative"),i=(await o(`Keystore storage located in (default: ${n}): `)).trim()||n,a=new I(s,i);let c,l,u,p;for(;;)if(c=await o("Enter service name: "),c=E(c),c.trim()){if(!a.serviceIsExist(c))break;console.log("Service name already exists, please enter a different name")}else console.log("Service name cannot be empty");for(;;){const e=await o("Enter port number: ");if(l=parseInt(e),isNaN(l)||l<1024||l>65535){console.log("Port number must be between 1024-65535");continue}const t=a.listServiceConfigs();let r=!1;for(const e of t)try{if(a.loadServiceConfig(e).ssh.port===l){r=!0;break}}catch(e){}if(!r)break;console.log(`Port ${l} is already in use by another service, please enter a different port`)}for(;;){const e=await o("Enter open keystore slugs (comma separated): ");if(!e.trim()){console.log("Keystore list cannot be empty");continue}if(u=e.split(",").map(e=>e.trim()).filter(e=>e),0===u.length){console.log("At least one valid keystore is required");continue}const s=r.join(i,"accounts");let n=!0;for(const e of u){const o=r.join(s,`${e}.json`);if(!t.existsSync(o)){console.log(`Keystore '${e}' does not exist`),n=!1;break}}if(n){console.log("All keystores verified to exist");break}console.log("Please re-enter valid keystore list")}for(;;){if(p=await o("Enter remote client name: "),p=E(p),p.trim()){console.log(`Client name: ${p}`);break}console.log("Client name cannot be empty")}const d=r.join(s,"conf.d",c);t.existsSync(d)||t.mkdirSync(d,{recursive:!0});const h=r.join(d,`${p}.pub`);for(console.log("\nPlease place the remote client's public key file at the following path:"),console.log(`${h}`),console.log("\nPress Enter to continue after placing the file...");;){if(await o(""),t.existsSync(h)){console.log("Client public key file found");break}console.log("Client public key file not found, please confirm the file is correctly placed and press Enter again")}const g=await o("Enter service description (optional): ");console.log("\nCreating SSH service configuration...");const f=await a.createServiceConfig(c,l,u,p,g||void 0);console.log("\nNote: Passwords will be requested when starting the service."),console.log(`\nSSH service configuration '${c}' created successfully!`),console.log(`Port: ${l}`),console.log(`Allowed keystores: ${u.join(", ")}`),console.log(`Client name: ${p}`),console.log(`Server private key: ${f.server_keys.private_key_path}`),console.log(`Client public key: ${h}`)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}finally{s.close()}}),Q.command("remove").description("Remove SSH service configuration").option("-c, --config <name>","Service configuration name").action(async e=>{const t=Z();try{e.config||(console.error("Error: Configuration name is required for remove command"),process.exit(1)),await t.removeService(e.config),console.log(`SSH service configuration '${e.config}' removed successfully`)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Q.command("list").description("List all SSH service configurations").action(async()=>{const e=new I,t=new U,r=e.listServiceConfigs();if(0!==r.length){console.log("SSH Service Configurations:");for(const s of r)try{const r=e.loadServiceConfig(s),o=t.getServiceStatus(s);console.log(` - ${s}: ${r.description||"No description"} (${o})`)}catch(e){const r=t.getServiceStatus(s);console.log(` - ${s}: Configuration error (${r})`)}}else console.log("No SSH service configurations found.")}),Q.command("status").description("Show SSH service status").option("-c, --config <name>","Service configuration name").action(async e=>{const t=Z();try{if(e.config){const r=t.getServiceStatus(e.config);console.log(`SSH service '${e.config}' status: ${r}`)}else{const e=t.listServices();if(0===e.length)return void console.log("No SSH service configurations found");console.log("SSH Service Status:"),e.forEach(e=>{const r=t.getServiceStatus(e.name);console.log(` - ${e.name}: ${r}`)})}}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),Q.command("log").description("Show SSH service logs").option("-c, --config <name>","Service configuration name").option("-n, --lines <number>","Number of lines to show (default: 50)","50").option("-f, --follow","Follow log output").action(async e=>{const t=Z();try{const r=parseInt(e.lines)||50;await t.showLogs(e.config,r,e.follow)}catch(e){console.error(`Error: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}),G.command("cmd").description("Start wallet-cli shell").action(async()=>{try{s("wallet-cli",{stdio:"inherit"})}catch(e){}}),(require.main===module||process.argv[1]&&(process.argv[1].includes("bin/wative.js")||process.argv[1].includes("wative")||process.argv[1].includes("ssh")))&&G.parse(process.argv);export{G as program};