wative 1.0.38 → 1.0.39

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.
@@ -0,0 +1,25 @@
1
+ #!/bin/bash
2
+ KEYSTORE_CONFIG_PATH="/etc/wative/config.ini"
3
+
4
+ # Create a temporary file to store the keystore list
5
+ TEMP_FILE="/tmp/allowed_keystores.tmp"
6
+
7
+ # Extract allowed_keystores and store them in the temporary file
8
+ awk -F "=" '/^\[keystore\]/ {flag=1} flag && /^allowed_keystores/ {print $2}' "$KEYSTORE_CONFIG_PATH" > "$TEMP_FILE"
9
+
10
+ # Iterate through the keystores and prompt for passwords
11
+ while IFS= read -r ALLOWED_KEYSTORE; do
12
+ # Skip empty lines
13
+ [[ -z "$ALLOWED_KEYSTORE" ]] && continue
14
+
15
+ # Prompt the user to input a password for the current keystore
16
+ PASSWORD_INPUT=$(systemd-ask-password "Input the password for keystore [$ALLOWED_KEYSTORE]: ")
17
+
18
+ done < "$TEMP_FILE"
19
+
20
+ # Clean up the temporary keystore file
21
+ rm -f "$TEMP_FILE"
22
+
23
+ # Execute wative-ssh with the loaded environment variables
24
+ TARGET_FILE=$(realpath "$(dirname "$(realpath "$0")")/../lib/wative-ssh.umd.js")
25
+ exec "$(which node)" "$TARGET_FILE" "$@"
package/bin/wative.js ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../lib/wative.umd.js')
@@ -0,0 +1 @@
1
+ import*as e from"path";import*as t from"fs";import{readFileSync as r}from"fs";import{utils as s,Server as n}from"ssh2";import{timingSafeEqual as a}from"crypto";import*as o from"ini";import{execSync as i}from"child_process";import"figlet";import"inquirer";import"web3";import"@solana/web3.js";import"@solana/spl-token";import"@metaplex-foundation/js";import"bignumber.js";import*as u from"log4js";import{ethers as c}from"ethers";function l(e,t,r,s){return new(r||(r=Promise))((function(n,a){function o(e){try{u(s.next(e))}catch(e){a(e)}}function i(e){try{u(s.throw(e))}catch(e){a(e)}}function u(e){var t;e.done?n(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(o,i)}u((s=s.apply(e,t||[])).next())}))}function p(e,t){var r,s,n,a,o={label:0,sent:function(){if(1&n[0])throw n[1];return n[1]},trys:[],ops:[]};return a={next:i(0),throw:i(1),return:i(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function i(i){return function(u){return function(i){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,i[0]&&(o=0)),o;)try{if(r=1,s&&(n=2&i[0]?s.return:i[0]?s.throw||((n=s.return)&&n.call(s),0):s.next)&&!(n=n.call(s,i[1])).done)return n;switch(s=0,n&&(i=[2&i[0],n.value]),i[0]){case 0:case 1:n=i;break;case 4:return o.label++,{value:i[1],done:!1};case 5:o.label++,s=i[1],i=[0];continue;case 7:i=o.ops.pop(),o.trys.pop();continue;default:if(!(n=o.trys,(n=n.length>0&&n[n.length-1])||6!==i[0]&&2!==i[0])){o=0;continue}if(3===i[0]&&(!n||i[1]>n[0]&&i[1]<n[3])){o.label=i[1];break}if(6===i[0]&&o.label<n[1]){o.label=n[1],n=i;break}if(n&&o.label<n[2]){o.label=n[2],o.ops.push(i);break}n[2]&&o.ops.pop(),o.trys.pop();continue}i=t.call(e,o)}catch(e){i=[6,e],s=0}finally{r=n=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,u])}}}"function"==typeof SuppressedError&&SuppressedError,require("chalk"),require("chalk"),require("chalk"),process.env.HOME||process.env.USERPROFILE;require("bn.js").BN,require("ethereumjs-util").stripHexPrefix,require("bignumber.js").BigNumber,require("chalk"),require("wative-core").WativeCore,require("chalk"),require("dotenv").config(),require("cli-progress"),require("wative-core").WativeCore;var d=function(r){return l(void 0,void 0,void 0,(function(){var s,n,a,u,c,d,h;return p(this,(function(f){switch(f.label){case 0:return s="/etc/wative",t.existsSync(s)||t.mkdirSync(s),[4,l(void 0,void 0,void 0,(function(){var r,s,n,a,o;return p(this,(function(u){return r="/etc/wative",s=e.join(r,"id_rsa_server.pub"),n=e.join(r,"id_rsa_server"),t.existsSync(s)&&t.existsSync(n)||(console.log("Generating SSH key pair..."),i("ssh-keygen -t rsa -f ".concat(n," -N 'wative_server'"),{stdio:"inherit"})),a=e.join(r,"id_rsa_detake.pub"),o=e.join(r,"id_rsa_detake"),t.existsSync(a)&&t.existsSync(o)||(console.log("Generating SSH key pair..."),i("ssh-keygen -t rsa -f ".concat(o," -N 'wative_detake'"),{stdio:"inherit"})),[2]}))}))];case 1:return f.sent(),n=e.join(s,"config.ini"),t.existsSync(n)||(g=r,m=e.resolve(g,"network.json"),a=JSON.parse(t.readFileSync(m,"utf8")),u=a.accounts,c=function(e){for(var t=[],r=0;r<e.length;r++)t.push(e[r].trim().toLocaleLowerCase().replace(/\s+/g,"-").trim().replace(/\-+/g,"-").trim());return t}(u),d={keystore:{path:r,allowed_keystores:c},ssh:{listen:"127.0.0.1",port:5678}},h=o.stringify(d),t.writeFileSync(n,h)),[2,o.parse(t.readFileSync(n,"utf-8"))]}var g,m}))}))},h=require("wative-core").WativeCore,f=require("@solana/web3.js"),g=f.Connection,m=f.PublicKey,v=f.VersionedTransaction,y=f.VersionedMessage,w=require("bs58"),b=require("@solana/web3.js"),_=b.Keypair,S=b.TransactionMessage,k=b.ComputeBudgetInstruction,x=b.TransactionInstruction,P=b.ComputeBudgetProgram,I=require("@coral-xyz/anchor").Wallet,C=u.getLogger();C.level="info";var A=function(){function o(e,n,a,o,i,u,c,l){if(this._allowedAppIds=[],this._allowedPubKeys=[],this._allowedKeystoreIds=[],this._sessionIdAppIdMap={},function(e){if(e=e.trim(),!t.existsSync(e))throw new Error("File not exists")}(e),0===a.length||0===o.length||0===i.length||a.length!==o.length||a.length!==i.length)throw new Error("WativeWielderServer:: constructor: Invaild AllowedApp");for(var p=0;p<i.length;p++)for(var d=0;d<i[p].length;d++){var f=i[p][d];if(!c.includes(f))throw new Error("WativeWielderServer:: constructor: Invaild AllowedKeystoreIds")}for(var g=0,m=a;g<m.length;g++){var v=m[g];this._allowedAppIds.push(Buffer.from(v))}for(var y=0,w=o;y<w.length;y++){var b=w[y],_=s.parseKey(r(b));this._allowedPubKeys.push(_)}this.wativeCore=new h(u,c,l),this._idRsaPrivatePath=e,this._idRsaPassphrase=n,this._allowedKeystoreIds=i,this._keystoreDirectoryPath=u}return o.prototype.listen=function(e,t){var s=this;new n({hostKeys:[{key:r(this._idRsaPrivatePath),passphrase:this._idRsaPassphrase}]},(function(e){e.on("authentication",(function(t){var r=!0;if(s&&(s.checkValue(Buffer.from(t.username),"appId")||(r=!1)),"publickey"!==t.method||!r)return t.reject();var n=s.getBytesIndex(Buffer.from(t.username),s._allowedAppIds),a=s._allowedPubKeys[n];if(t.key.algo!==a.type||!s.checkValue(t.key.data,"publicKey")||t.signature&&!0!==a.verify(t.blob,t.signature,t.hashAlgo))return t.reject();if(r){var o=e._protocol._kex.sessionID.toString("hex");s._sessionIdAppIdMap[o]=Buffer.from(t.username),t.accept()}else t.reject()})).on("ready",(function(){e.on("session",(function(t,r){t().once("exec",(function(t,r,n){return l(s,void 0,void 0,(function(){var r,s,a;return p(this,(function(o){switch(o.label){case 0:return r=e._protocol._kex.sessionID.toString("hex"),[4,this.web3Request(r,n.command)];case 1:return s=o.sent(),(a=t())?(JSON.stringify(s)?(a.write(JSON.stringify(s)),a.exit(0),a.end()):(a.write("ssh2 connect error"),a.exit(0),a.end()),[2]):[2]}}))}))}))}))})).on("close",(function(){C.info("Client disconnected")})).on("error",(function(e){C.error("err: ",e.message)}))})).listen(t,e,(function(){C.info("Listening on port "+t)}))},o.prototype.web3Request=function(e,t){return l(this,void 0,void 0,(function(){var r,s,n,a,o,i,u,c,l,d,h,f,g,m,v;return p(this,(function(p){switch(p.label){case 0:return p.trys.push([0,34,,35]),r=this._sessionIdAppIdMap[e],(s=this.getBytesIndex(r,this._allowedAppIds))<0?[2,{status:!1,msg:"app not found"}]:(n=JSON.parse(t),C.info("sign message: ",t),a=n.method,o=n.keystoreId||n.params.keystoreId,i=n.chainId||n.params.chainId,this._allowedKeystoreIds[s].includes(o)?(u=void 0,"get_root_account"!==a?[3,1]:(u=this.getRootAccount(o,i),[3,33])):[2,{status:!1,msg:"keystore not allowed"}]);case 1:return"get_sub_account"!==a?[3,2]:(g=n.params,u=this.getSubAccount(o,g.chainId,null==g?void 0:g.startIndex,null==g?void 0:g.endIndex),[3,33]);case 2:if("sign"!==a)return[3,7];g=n.params,p.label=3;case 3:return p.trys.push([3,5,,6]),[4,this.wativeCore.account.signTransaction(g.txParams.from,g.txParams,g.rpcUrl)];case 4:return u=p.sent(),[3,6];case 5:return c=p.sent(),C.error("sign error: ",c.message),[2,{status:!1,msg:c.msg}];case 6:return[3,33];case 7:if("sign_and_send"!==a)return[3,12];g=n.params,p.label=8;case 8:return p.trys.push([8,10,,11]),[4,this.wativeCore.account.signAndSendTx(g.txParams,g.rpcUrl)];case 9:return l=p.sent(),u={transactionHash:l},[3,11];case 10:return[2,{status:!1,msg:p.sent().msg}];case 11:return[3,33];case 12:if("solana_sign"!==a)return[3,17];p.label=13;case 13:return p.trys.push([13,15,,16]),g=n.params,[4,this.signSolanaTransaction(g.txParams.from,g.txParams.data,g.txParams.lookup_tables,g.rpcUrl,g.priority_fee)];case 14:return u=p.sent(),[3,16];case 15:return d=p.sent(),C.error("sign error: ",d.message),[2,{status:!1,msg:d.msg}];case 16:return[3,33];case 17:if("solana_send"!==a)return[3,22];p.label=18;case 18:return p.trys.push([18,20,,21]),g=n.params,[4,this.sendSignedSolanaTransaction(g.txParams.from,g.txParams.signature,g.txParams.data,g.rpcUrl)];case 19:return u=p.sent(),[3,21];case 20:return h=p.sent(),C.error("sign error: ",h.message),[2,{status:!1,msg:h.msg}];case 21:return[3,33];case 22:if("sign_message"!==a)return[3,27];p.label=23;case 23:return p.trys.push([23,25,,26]),g=n.params,C.debug("sign message: ",g),[4,this.signMessage(g.account,g.message)];case 24:return u=p.sent(),[3,26];case 25:return f=p.sent(),C.error("sign error: ",f.message),[2,{status:!1,msg:f.msg}];case 26:return[3,33];case 27:if("sign_typed_data"!==a)return[3,32];p.label=28;case 28:return p.trys.push([28,30,,31]),g=n.params,C.debug("sign message: ",g),[4,this.signTypedData(g.account,g.domain,g.types_name,g.types,g.message)];case 29:return u=p.sent(),[3,31];case 30:return m=p.sent(),C.error("sign error: ",m.message),[2,{status:!1,msg:m.msg}];case 31:return[3,33];case 32:return[2,{status:!1,msg:"message method not find"}];case 33:return[2,{status:!0,data:u}];case 34:return v=p.sent(),C.error("sign error: ",v.message),[2,{status:!1,msg:v.msg}];case 35:return[2]}}))}))},o.prototype.checkValue=function(e,t){if("appId"!==t&&"publicKey"!==t)return!1;for(var r=this._allowedAppIds.length,s=0;s<r;s++){var n=void 0;n="appId"===t?this._allowedAppIds[s]:this._allowedPubKeys[s].getPublicSSH();var o=e.length!==n.length;o&&(n=e);var i=a(e,n);if(!o&&i)return!0}},o.prototype.getBytesIndex=function(e,t){for(var r=t.length,s=0;s<r;s++)if(e.length===t[s].length&&a(e,t[s]))return s;return-1},o.prototype.getRootAccount=function(t,s){var n=e.resolve(this._keystoreDirectoryPath,"accounts/".concat(t,".json")),a=r(n);return a=JSON.parse(a.toString()),[{id:0,address:"SOLANA"===this.getChainType(s)?a.data[0].ciphertexts.solana.address:a.data[0].ciphertexts.evm.address,children:a.data.length,type:"M"}]},o.prototype.getChainType=function(e){return"901"===e||"902"===e||"903"===e?"SOLANA":"EVM"},o.prototype.getSubAccount=function(t,s,n,a){var o=e.resolve(this._keystoreDirectoryPath,"accounts/".concat(t,".json")),i=r(o),u=(i=JSON.parse(i.toString())).data.length-1;a&&a<u&&(u=a);var c=0;if(n&&n>0&&(c=n),c>u)return[];for(var l=this.getChainType(s),p=[],d=c;d<=u;d++)p.push(i.data[d].ciphertexts[l.toLocaleLowerCase()].address);return p},o.prototype.signMessage=function(e,t){return l(this,void 0,void 0,(function(){var r;return p(this,(function(s){switch(s.label){case 0:return[4,this.wativeCore.account.signMessage(e,t)];case 1:return r=s.sent(),console.log(r),[2,r]}}))}))},o.prototype.signTypedData=function(e,t,r,s,n){return l(this,void 0,void 0,(function(){var a,o,i,u,l,d;return p(this,(function(p){switch(p.label){case 0:return console.log("111"),a=JSON.parse(t),o=JSON.parse(s),i=JSON.parse(n),console.log(a),console.log(o),console.log(i),u=this.wativeCore.account.showPrivateKey(e),[4,new c.Wallet(u).signTypedData(a,(d={},d[r]=o,d),i)];case 1:return l=p.sent(),console.log(l),[2,{status:!0,output:l}]}}))}))},o.prototype.signSolanaTransaction=function(e,t,r,s,n){return l(this,void 0,void 0,(function(){var a,o,i,u,c,l,d,h,f,b,k,x,C,A,j,q,B,K,L,N;return p(this,(function(p){switch(p.label){case 0:if(a=new g(s),o=[],!r)return[3,5];i=0,u=r,p.label=1;case 1:return i<u.length?(c=u[i],[4,a.getAddressLookupTable(new m(c))]):[3,5];case 2:return l=p.sent().value,o.push(l),[4,T(1e3)];case 3:p.sent(),p.label=4;case 4:return i++,[3,1];case 5:return d=y.deserialize(Uint8Array.from(Buffer.from(t,"hex"))),(h=S.decompile(d)).instructions.push(P.setComputeUnitLimit({units:2e6})),h.instructions.push(P.setComputeUnitPrice({microLamports:1e3})),d=h.compileToV0Message(o),f=d,[4,a.getLatestBlockhash()];case 6:return f.recentBlockhash=p.sent().blockhash,[4,T(3e3)];case 7:return p.sent(),b=new v(d),k=this.wativeCore.account.showPrivateKey(e),x=_.fromSecretKey(new Uint8Array(w.decode(k))),C=new I(x),[4,a.simulateTransaction(b)];case 8:if(!(A=p.sent())||!A.value||0===A.value.unitsConsumed||A.value.err)return[2,{status:!1,output:A.value.err}];if(j=h.instructions.length,q=Math.trunc(1.2*A.value.unitsConsumed),h.instructions[j-2]=P.setComputeUnitLimit({units:q}),n&&"null"!=n)return[3,12];p.label=9;case 9:return p.trys.push([9,11,,12]),[4,this.getPrioritizationFee(s)];case 10:return n=p.sent(),[3,12];case 11:return p.sent(),n=2e5,[3,12];case 12:return n<1e4&&(n=1e4),n>5e5&&(n=5e5),h.instructions[j-1]=P.setComputeUnitPrice({microLamports:n}),d=h.compileToV0Message(o),[4,T(1e3)];case 13:return p.sent(),B=d,[4,a.getLatestBlockhash()];case 14:return B.recentBlockhash=p.sent().blockhash,(b=new v(d)).feePayer=C.publicKey,[4,T(3e3)];case 15:return p.sent(),[4,this.wativeCore.account.signTransaction(e,b,s)];case 16:return K=p.sent(),L=new v(K.output.message,K.output.signatures),N=L.message.serialize(),N=Buffer.from(N).toString("hex"),[2,{status:!0,output:{transactionHash:w.encode(K.output.signatures[0]),message:N,compute_units:A.value.unitsConsumed.toString()}}]}}))}))},o.prototype.sendSignedSolanaTransaction=function(e,t,r,s){return l(this,void 0,void 0,(function(){var n,a,o;return p(this,(function(i){switch(i.label){case 0:return n=[w.decode(t)],a=y.deserialize(Uint8Array.from(Buffer.from(r,"hex"))),o=new v(a,n),[4,this.wativeCore.account.sendSignedTransaction(e,o,s)];case 1:return[2,i.sent()]}}))}))},o.prototype.getPrioritizationFee=function(e){return l(this,void 0,void 0,(function(){var t,r,s,n,a,o,i,u,c,l,d,h;return p(this,(function(p){switch(p.label){case 0:return t=new m("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"),[4,(r=new g(e,"confirmed")).getSignaturesForAddress(t,{limit:5})];case 1:return s=p.sent(),[4,T(2e3)];case 2:for(p.sent(),n=[],i=0;i<s.length;i++)n.push(s[i].signature);return[4,r.getParsedTransactions(n,{maxSupportedTransactionVersion:0})];case 3:for(a=p.sent(),o=0,i=0;i<a.length;i++)for(u=a[i].transaction.message.instructions,c=0;c<u.length;c++)if("ComputeBudget111111111111111111111111111111"===u[c].programId.toBase58()){l=u[c].data;try{d=new x({keys:[],programId:new m("ComputeBudget111111111111111111111111111111"),data:Buffer.from(w.decode(l))}),h=k.decodeSetComputeUnitPrice(d).microLamports,o+=Number(h);continue}catch(e){}}return[2,Math.ceil(o/5)]}}))}))},o}(),T=function(e){return new Promise((function(t){return setTimeout(t,e)}))};require("dotenv").config();var j=require("os");process.on("unhandledRejection",(function(e,t){console.log("Unhandled Rejection at:",t,"reason:",e)})),l(void 0,void 0,void 0,(function(){var t,r,s,n,a,o,i,u,c,h,f;return p(this,(function(g){switch(g.label){case 0:return t=j.homedir(),r=e.join(t,".wative"),[4,d(r)];case 1:return s=g.sent(),n=s.ssh.listen,a=s.ssh.port,o="/etc/wative/id_rsa_server",i="wative_server",u="detake",c="/etc/wative/id_rsa_detake.pub",h=s.keystore.allowed_keystores,[4,(m=h,l(void 0,void 0,void 0,(function(){var e,t,r;return p(this,(function(s){for(e=[],t=0;t<m.length;t++)r=m[t],e.push(process.env[r]);return[2,e]}))})))];case 2:return f=g.sent(),new A(o,i,[u],[c],[h],r,h,f).listen(n,a),[2]}var m}))}));
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("path"),require("fs"),require("ssh2"),require("crypto"),require("ini"),require("child_process"),require("figlet"),require("inquirer"),require("web3"),require("@solana/web3.js"),require("@solana/spl-token"),require("@metaplex-foundation/js"),require("bignumber.js"),require("log4js"),require("ethers")):"function"==typeof define&&define.amd?define(["path","fs","ssh2","crypto","ini","child_process","figlet","inquirer","web3","@solana/web3.js","@solana/spl-token","@metaplex-foundation/js","bignumber.js","log4js","ethers"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).path,e.fs,e.ssh2,e.crypto,e.ini,e.child_process,null,null,null,null,null,null,null,e.log4js,e.ethers)}(this,(function(e,t,r,n,s,a,i,o,u,c,l,d,h,p,f){"use strict";function g(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var v=g(e),m=g(t),y=g(s),w=g(p);function b(e,t,r,n){return new(r||(r=Promise))((function(s,a){function i(e){try{u(n.next(e))}catch(e){a(e)}}function o(e){try{u(n.throw(e))}catch(e){a(e)}}function u(e){var t;e.done?s(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(i,o)}u((n=n.apply(e,t||[])).next())}))}function S(e,t){var r,n,s,a,i={label:0,sent:function(){if(1&s[0])throw s[1];return s[1]},trys:[],ops:[]};return a={next:o(0),throw:o(1),return:o(2)},"function"==typeof Symbol&&(a[Symbol.iterator]=function(){return this}),a;function o(o){return function(u){return function(o){if(r)throw new TypeError("Generator is already executing.");for(;a&&(a=0,o[0]&&(i=0)),i;)try{if(r=1,n&&(s=2&o[0]?n.return:o[0]?n.throw||((s=n.return)&&s.call(n),0):n.next)&&!(s=s.call(n,o[1])).done)return s;switch(n=0,s&&(o=[2&o[0],s.value]),o[0]){case 0:case 1:s=o;break;case 4:return i.label++,{value:o[1],done:!1};case 5:i.label++,n=o[1],o=[0];continue;case 7:o=i.ops.pop(),i.trys.pop();continue;default:if(!(s=i.trys,(s=s.length>0&&s[s.length-1])||6!==o[0]&&2!==o[0])){i=0;continue}if(3===o[0]&&(!s||o[1]>s[0]&&o[1]<s[3])){i.label=o[1];break}if(6===o[0]&&i.label<s[1]){i.label=s[1],s=o;break}if(s&&i.label<s[2]){i.label=s[2],i.ops.push(o);break}s[2]&&i.ops.pop(),i.trys.pop();continue}o=t.call(e,i)}catch(e){o=[6,e],n=0}finally{r=s=0}if(5&o[0])throw o[1];return{value:o[0]?o[1]:void 0,done:!0}}([o,u])}}}"function"==typeof SuppressedError&&SuppressedError,require("chalk"),require("chalk"),require("chalk"),process.env.HOME||process.env.USERPROFILE;require("bn.js").BN,require("ethereumjs-util").stripHexPrefix,require("bignumber.js").BigNumber,require("chalk"),require("wative-core").WativeCore,require("chalk"),require("dotenv").config(),require("cli-progress"),require("wative-core").WativeCore;var _=function(e){return b(void 0,void 0,void 0,(function(){var t,r,n,s,i,o,u;return S(this,(function(c){switch(c.label){case 0:return t="/etc/wative",m.existsSync(t)||m.mkdirSync(t),[4,b(void 0,void 0,void 0,(function(){var e,t,r,n,s;return S(this,(function(i){return e="/etc/wative",t=v.join(e,"id_rsa_server.pub"),r=v.join(e,"id_rsa_server"),m.existsSync(t)&&m.existsSync(r)||(console.log("Generating SSH key pair..."),a.execSync("ssh-keygen -t rsa -f ".concat(r," -N 'wative_server'"),{stdio:"inherit"})),n=v.join(e,"id_rsa_detake.pub"),s=v.join(e,"id_rsa_detake"),m.existsSync(n)&&m.existsSync(s)||(console.log("Generating SSH key pair..."),a.execSync("ssh-keygen -t rsa -f ".concat(s," -N 'wative_detake'"),{stdio:"inherit"})),[2]}))}))];case 1:return c.sent(),r=v.join(t,"config.ini"),m.existsSync(r)||(l=e,d=v.resolve(l,"network.json"),n=JSON.parse(m.readFileSync(d,"utf8")),s=n.accounts,i=function(e){for(var t=[],r=0;r<e.length;r++)t.push(e[r].trim().toLocaleLowerCase().replace(/\s+/g,"-").trim().replace(/\-+/g,"-").trim());return t}(s),o={keystore:{path:e,allowed_keystores:i},ssh:{listen:"127.0.0.1",port:5678}},u=y.stringify(o),m.writeFileSync(r,u)),[2,y.parse(m.readFileSync(r,"utf-8"))]}var l,d}))}))},k=require("wative-core").WativeCore,x=require("@solana/web3.js"),P=x.Connection,q=x.PublicKey,I=x.VersionedTransaction,j=x.VersionedMessage,C=require("bs58"),T=require("@solana/web3.js"),A=T.Keypair,B=T.TransactionMessage,K=T.ComputeBudgetInstruction,L=T.TransactionInstruction,O=T.ComputeBudgetProgram,N=require("@coral-xyz/anchor").Wallet,M=w.getLogger();M.level="info";var U=function(){function e(e,n,s,a,i,o,u,c){if(this._allowedAppIds=[],this._allowedPubKeys=[],this._allowedKeystoreIds=[],this._sessionIdAppIdMap={},function(e){if(e=e.trim(),!m.existsSync(e))throw new Error("File not exists")}(e),0===s.length||0===a.length||0===i.length||s.length!==a.length||s.length!==i.length)throw new Error("WativeWielderServer:: constructor: Invaild AllowedApp");for(var l=0;l<i.length;l++)for(var d=0;d<i[l].length;d++){var h=i[l][d];if(!u.includes(h))throw new Error("WativeWielderServer:: constructor: Invaild AllowedKeystoreIds")}for(var p=0,f=s;p<f.length;p++){var g=f[p];this._allowedAppIds.push(Buffer.from(g))}for(var v=0,y=a;v<y.length;v++){var w=y[v],b=r.utils.parseKey(t.readFileSync(w));this._allowedPubKeys.push(b)}this.wativeCore=new k(o,u,c),this._idRsaPrivatePath=e,this._idRsaPassphrase=n,this._allowedKeystoreIds=i,this._keystoreDirectoryPath=o}return e.prototype.listen=function(e,n){var s=this;new r.Server({hostKeys:[{key:t.readFileSync(this._idRsaPrivatePath),passphrase:this._idRsaPassphrase}]},(function(e){e.on("authentication",(function(t){var r=!0;if(s&&(s.checkValue(Buffer.from(t.username),"appId")||(r=!1)),"publickey"!==t.method||!r)return t.reject();var n=s.getBytesIndex(Buffer.from(t.username),s._allowedAppIds),a=s._allowedPubKeys[n];if(t.key.algo!==a.type||!s.checkValue(t.key.data,"publicKey")||t.signature&&!0!==a.verify(t.blob,t.signature,t.hashAlgo))return t.reject();if(r){var i=e._protocol._kex.sessionID.toString("hex");s._sessionIdAppIdMap[i]=Buffer.from(t.username),t.accept()}else t.reject()})).on("ready",(function(){e.on("session",(function(t,r){t().once("exec",(function(t,r,n){return b(s,void 0,void 0,(function(){var r,s,a;return S(this,(function(i){switch(i.label){case 0:return r=e._protocol._kex.sessionID.toString("hex"),[4,this.web3Request(r,n.command)];case 1:return s=i.sent(),(a=t())?(JSON.stringify(s)?(a.write(JSON.stringify(s)),a.exit(0),a.end()):(a.write("ssh2 connect error"),a.exit(0),a.end()),[2]):[2]}}))}))}))}))})).on("close",(function(){M.info("Client disconnected")})).on("error",(function(e){M.error("err: ",e.message)}))})).listen(n,e,(function(){M.info("Listening on port "+n)}))},e.prototype.web3Request=function(e,t){return b(this,void 0,void 0,(function(){var r,n,s,a,i,o,u,c,l,d,h,p,f,g,v;return S(this,(function(m){switch(m.label){case 0:return m.trys.push([0,34,,35]),r=this._sessionIdAppIdMap[e],(n=this.getBytesIndex(r,this._allowedAppIds))<0?[2,{status:!1,msg:"app not found"}]:(s=JSON.parse(t),M.info("sign message: ",t),a=s.method,i=s.keystoreId||s.params.keystoreId,o=s.chainId||s.params.chainId,this._allowedKeystoreIds[n].includes(i)?(u=void 0,"get_root_account"!==a?[3,1]:(u=this.getRootAccount(i,o),[3,33])):[2,{status:!1,msg:"keystore not allowed"}]);case 1:return"get_sub_account"!==a?[3,2]:(f=s.params,u=this.getSubAccount(i,f.chainId,null==f?void 0:f.startIndex,null==f?void 0:f.endIndex),[3,33]);case 2:if("sign"!==a)return[3,7];f=s.params,m.label=3;case 3:return m.trys.push([3,5,,6]),[4,this.wativeCore.account.signTransaction(f.txParams.from,f.txParams,f.rpcUrl)];case 4:return u=m.sent(),[3,6];case 5:return c=m.sent(),M.error("sign error: ",c.message),[2,{status:!1,msg:c.msg}];case 6:return[3,33];case 7:if("sign_and_send"!==a)return[3,12];f=s.params,m.label=8;case 8:return m.trys.push([8,10,,11]),[4,this.wativeCore.account.signAndSendTx(f.txParams,f.rpcUrl)];case 9:return l=m.sent(),u={transactionHash:l},[3,11];case 10:return[2,{status:!1,msg:m.sent().msg}];case 11:return[3,33];case 12:if("solana_sign"!==a)return[3,17];m.label=13;case 13:return m.trys.push([13,15,,16]),f=s.params,[4,this.signSolanaTransaction(f.txParams.from,f.txParams.data,f.txParams.lookup_tables,f.rpcUrl,f.priority_fee)];case 14:return u=m.sent(),[3,16];case 15:return d=m.sent(),M.error("sign error: ",d.message),[2,{status:!1,msg:d.msg}];case 16:return[3,33];case 17:if("solana_send"!==a)return[3,22];m.label=18;case 18:return m.trys.push([18,20,,21]),f=s.params,[4,this.sendSignedSolanaTransaction(f.txParams.from,f.txParams.signature,f.txParams.data,f.rpcUrl)];case 19:return u=m.sent(),[3,21];case 20:return h=m.sent(),M.error("sign error: ",h.message),[2,{status:!1,msg:h.msg}];case 21:return[3,33];case 22:if("sign_message"!==a)return[3,27];m.label=23;case 23:return m.trys.push([23,25,,26]),f=s.params,M.debug("sign message: ",f),[4,this.signMessage(f.account,f.message)];case 24:return u=m.sent(),[3,26];case 25:return p=m.sent(),M.error("sign error: ",p.message),[2,{status:!1,msg:p.msg}];case 26:return[3,33];case 27:if("sign_typed_data"!==a)return[3,32];m.label=28;case 28:return m.trys.push([28,30,,31]),f=s.params,M.debug("sign message: ",f),[4,this.signTypedData(f.account,f.domain,f.types_name,f.types,f.message)];case 29:return u=m.sent(),[3,31];case 30:return g=m.sent(),M.error("sign error: ",g.message),[2,{status:!1,msg:g.msg}];case 31:return[3,33];case 32:return[2,{status:!1,msg:"message method not find"}];case 33:return[2,{status:!0,data:u}];case 34:return v=m.sent(),M.error("sign error: ",v.message),[2,{status:!1,msg:v.msg}];case 35:return[2]}}))}))},e.prototype.checkValue=function(e,t){if("appId"!==t&&"publicKey"!==t)return!1;for(var r=this._allowedAppIds.length,s=0;s<r;s++){var a=void 0;a="appId"===t?this._allowedAppIds[s]:this._allowedPubKeys[s].getPublicSSH();var i=e.length!==a.length;i&&(a=e);var o=n.timingSafeEqual(e,a);if(!i&&o)return!0}},e.prototype.getBytesIndex=function(e,t){for(var r=t.length,s=0;s<r;s++)if(e.length===t[s].length&&n.timingSafeEqual(e,t[s]))return s;return-1},e.prototype.getRootAccount=function(e,r){var n=v.resolve(this._keystoreDirectoryPath,"accounts/".concat(e,".json")),s=t.readFileSync(n);return s=JSON.parse(s.toString()),[{id:0,address:"SOLANA"===this.getChainType(r)?s.data[0].ciphertexts.solana.address:s.data[0].ciphertexts.evm.address,children:s.data.length,type:"M"}]},e.prototype.getChainType=function(e){return"901"===e||"902"===e||"903"===e?"SOLANA":"EVM"},e.prototype.getSubAccount=function(e,r,n,s){var a=v.resolve(this._keystoreDirectoryPath,"accounts/".concat(e,".json")),i=t.readFileSync(a),o=(i=JSON.parse(i.toString())).data.length-1;s&&s<o&&(o=s);var u=0;if(n&&n>0&&(u=n),u>o)return[];for(var c=this.getChainType(r),l=[],d=u;d<=o;d++)l.push(i.data[d].ciphertexts[c.toLocaleLowerCase()].address);return l},e.prototype.signMessage=function(e,t){return b(this,void 0,void 0,(function(){var r;return S(this,(function(n){switch(n.label){case 0:return[4,this.wativeCore.account.signMessage(e,t)];case 1:return r=n.sent(),console.log(r),[2,r]}}))}))},e.prototype.signTypedData=function(e,t,r,n,s){return b(this,void 0,void 0,(function(){var a,i,o,u,c,l;return S(this,(function(d){switch(d.label){case 0:return console.log("111"),a=JSON.parse(t),i=JSON.parse(n),o=JSON.parse(s),console.log(a),console.log(i),console.log(o),u=this.wativeCore.account.showPrivateKey(e),[4,new f.ethers.Wallet(u).signTypedData(a,(l={},l[r]=i,l),o)];case 1:return c=d.sent(),console.log(c),[2,{status:!0,output:c}]}}))}))},e.prototype.signSolanaTransaction=function(e,t,r,n,s){return b(this,void 0,void 0,(function(){var a,i,o,u,c,l,d,h,p,f,g,v,m,y,w,b,_,k,x,T;return S(this,(function(S){switch(S.label){case 0:if(a=new P(n),i=[],!r)return[3,5];o=0,u=r,S.label=1;case 1:return o<u.length?(c=u[o],[4,a.getAddressLookupTable(new q(c))]):[3,5];case 2:return l=S.sent().value,i.push(l),[4,E(1e3)];case 3:S.sent(),S.label=4;case 4:return o++,[3,1];case 5:return d=j.deserialize(Uint8Array.from(Buffer.from(t,"hex"))),(h=B.decompile(d)).instructions.push(O.setComputeUnitLimit({units:2e6})),h.instructions.push(O.setComputeUnitPrice({microLamports:1e3})),d=h.compileToV0Message(i),p=d,[4,a.getLatestBlockhash()];case 6:return p.recentBlockhash=S.sent().blockhash,[4,E(3e3)];case 7:return S.sent(),f=new I(d),g=this.wativeCore.account.showPrivateKey(e),v=A.fromSecretKey(new Uint8Array(C.decode(g))),m=new N(v),[4,a.simulateTransaction(f)];case 8:if(!(y=S.sent())||!y.value||0===y.value.unitsConsumed||y.value.err)return[2,{status:!1,output:y.value.err}];if(w=h.instructions.length,b=Math.trunc(1.2*y.value.unitsConsumed),h.instructions[w-2]=O.setComputeUnitLimit({units:b}),s&&"null"!=s)return[3,12];S.label=9;case 9:return S.trys.push([9,11,,12]),[4,this.getPrioritizationFee(n)];case 10:return s=S.sent(),[3,12];case 11:return S.sent(),s=2e5,[3,12];case 12:return s<1e4&&(s=1e4),s>5e5&&(s=5e5),h.instructions[w-1]=O.setComputeUnitPrice({microLamports:s}),d=h.compileToV0Message(i),[4,E(1e3)];case 13:return S.sent(),_=d,[4,a.getLatestBlockhash()];case 14:return _.recentBlockhash=S.sent().blockhash,(f=new I(d)).feePayer=m.publicKey,[4,E(3e3)];case 15:return S.sent(),[4,this.wativeCore.account.signTransaction(e,f,n)];case 16:return k=S.sent(),x=new I(k.output.message,k.output.signatures),T=x.message.serialize(),T=Buffer.from(T).toString("hex"),[2,{status:!0,output:{transactionHash:C.encode(k.output.signatures[0]),message:T,compute_units:y.value.unitsConsumed.toString()}}]}}))}))},e.prototype.sendSignedSolanaTransaction=function(e,t,r,n){return b(this,void 0,void 0,(function(){var s,a,i;return S(this,(function(o){switch(o.label){case 0:return s=[C.decode(t)],a=j.deserialize(Uint8Array.from(Buffer.from(r,"hex"))),i=new I(a,s),[4,this.wativeCore.account.sendSignedTransaction(e,i,n)];case 1:return[2,o.sent()]}}))}))},e.prototype.getPrioritizationFee=function(e){return b(this,void 0,void 0,(function(){var t,r,n,s,a,i,o,u,c,l,d,h;return S(this,(function(p){switch(p.label){case 0:return t=new q("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"),[4,(r=new P(e,"confirmed")).getSignaturesForAddress(t,{limit:5})];case 1:return n=p.sent(),[4,E(2e3)];case 2:for(p.sent(),s=[],o=0;o<n.length;o++)s.push(n[o].signature);return[4,r.getParsedTransactions(s,{maxSupportedTransactionVersion:0})];case 3:for(a=p.sent(),i=0,o=0;o<a.length;o++)for(u=a[o].transaction.message.instructions,c=0;c<u.length;c++)if("ComputeBudget111111111111111111111111111111"===u[c].programId.toBase58()){l=u[c].data;try{d=new L({keys:[],programId:new q("ComputeBudget111111111111111111111111111111"),data:Buffer.from(C.decode(l))}),h=K.decodeSetComputeUnitPrice(d).microLamports,i+=Number(h);continue}catch(e){}}return[2,Math.ceil(i/5)]}}))}))},e}(),E=function(e){return new Promise((function(t){return setTimeout(t,e)}))};require("dotenv").config();var F=require("os");process.on("unhandledRejection",(function(e,t){console.log("Unhandled Rejection at:",t,"reason:",e)})),b(void 0,void 0,void 0,(function(){var e,t,r,n,s,a,i,o,u,c,l;return S(this,(function(d){switch(d.label){case 0:return e=F.homedir(),t=v.join(e,".wative"),[4,_(t)];case 1:return r=d.sent(),n=r.ssh.listen,s=r.ssh.port,a="/etc/wative/id_rsa_server",i="wative_server",o="detake",u="/etc/wative/id_rsa_detake.pub",c=r.keystore.allowed_keystores,[4,(h=c,b(void 0,void 0,void 0,(function(){var e,t,r;return S(this,(function(n){for(e=[],t=0;t<h.length;t++)r=h[t],e.push(process.env[r]);return[2,e]}))})))];case 2:return l=d.sent(),new U(a,i,[o],[u],[c],t,c,l).listen(n,s),[2]}var h}))}))}));
@@ -0,0 +1 @@
1
+ import*as e from"path";import{Command as t}from"commander";import{execSync as r}from"child_process";import*as i from"fs";import*as n from"ini";import"figlet";import"inquirer";import"web3";import"@solana/web3.js";import"@solana/spl-token";import"@metaplex-foundation/js";import"bignumber.js";function o(e,t,r,i){return new(r||(r=Promise))((function(n,o){function s(e){try{c(i.next(e))}catch(e){o(e)}}function a(e){try{c(i.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?n(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(s,a)}c((i=i.apply(e,t||[])).next())}))}function s(e,t){var r,i,n,o,s={label:0,sent:function(){if(1&n[0])throw n[1];return n[1]},trys:[],ops:[]};return o={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function a(a){return function(c){return function(a){if(r)throw new TypeError("Generator is already executing.");for(;o&&(o=0,a[0]&&(s=0)),s;)try{if(r=1,i&&(n=2&a[0]?i.return:a[0]?i.throw||((n=i.return)&&n.call(i),0):i.next)&&!(n=n.call(i,a[1])).done)return n;switch(i=0,n&&(a=[2&a[0],n.value]),a[0]){case 0:case 1:n=a;break;case 4:return s.label++,{value:a[1],done:!1};case 5:s.label++,i=a[1],a=[0];continue;case 7:a=s.ops.pop(),s.trys.pop();continue;default:if(!(n=s.trys,(n=n.length>0&&n[n.length-1])||6!==a[0]&&2!==a[0])){s=0;continue}if(3===a[0]&&(!n||a[1]>n[0]&&a[1]<n[3])){s.label=a[1];break}if(6===a[0]&&s.label<n[1]){s.label=n[1],n=a;break}if(n&&s.label<n[2]){s.label=n[2],s.ops.push(a);break}n[2]&&s.ops.pop(),s.trys.pop();continue}a=t.call(e,s)}catch(e){a=[6,e],i=0}finally{r=n=0}if(5&a[0])throw a[1];return{value:a[0]?a[1]:void 0,done:!0}}([a,c])}}}"function"==typeof SuppressedError&&SuppressedError,require("chalk"),require("chalk"),require("chalk"),process.env.HOME||process.env.USERPROFILE;require("bn.js").BN,require("ethereumjs-util").stripHexPrefix,require("bignumber.js").BigNumber,require("chalk"),require("wative-core").WativeCore,require("chalk"),require("dotenv").config(),require("cli-progress"),require("wative-core").WativeCore;var a=function(t){return o(void 0,void 0,void 0,(function(){var a,c,l,u,d,v,p;return s(this,(function(m){switch(m.label){case 0:return a="/etc/wative",i.existsSync(a)||i.mkdirSync(a),[4,o(void 0,void 0,void 0,(function(){var t,n,o,a,c;return s(this,(function(s){return t="/etc/wative",n=e.join(t,"id_rsa_server.pub"),o=e.join(t,"id_rsa_server"),i.existsSync(n)&&i.existsSync(o)||(console.log("Generating SSH key pair..."),r("ssh-keygen -t rsa -f ".concat(o," -N 'wative_server'"),{stdio:"inherit"})),a=e.join(t,"id_rsa_detake.pub"),c=e.join(t,"id_rsa_detake"),i.existsSync(a)&&i.existsSync(c)||(console.log("Generating SSH key pair..."),r("ssh-keygen -t rsa -f ".concat(c," -N 'wative_detake'"),{stdio:"inherit"})),[2]}))}))];case 1:return m.sent(),c=e.join(a,"config.ini"),i.existsSync(c)||(f=t,h=e.resolve(f,"network.json"),l=JSON.parse(i.readFileSync(h,"utf8")),u=l.accounts,d=function(e){for(var t=[],r=0;r<e.length;r++)t.push(e[r].trim().toLocaleLowerCase().replace(/\s+/g,"-").trim().replace(/\-+/g,"-").trim());return t}(u),v={keystore:{path:t,allowed_keystores:d},ssh:{listen:"127.0.0.1",port:5678}},p=n.stringify(v),i.writeFileSync(c,p)),[2,n.parse(i.readFileSync(c,"utf-8"))]}var f,h}))}))},c=require("os"),l=new t,u=require("../package.json"),d=function(){try{return r("systemctl --version",{stdio:"ignore"}),!0}catch(e){return!1}};l.version(u.version).description("Wative CLI Tool"),l.command("version").description("Show the version of wative").action((function(){console.log("Wative CLI Tool v".concat(u.version))}));var v=l.command("ssh").description("Manage SSH service");v.command("start").description("Start SSH service").action((function(){if(d()){try{r("wative-ssh",{stdio:"inherit"})}catch(e){}console.log("Starting SSH service...")}else console.log("Systemd is not available.")}));var p=v.command("service").description("Manage SSH service");p.command("add").description("Add SSH service").action((function(){return o(void 0,void 0,void 0,(function(){var t,i;return s(this,(function(n){switch(n.label){case 0:return d()?(t=c.homedir(),i=e.join(t,".wative"),[4,a(i)]):(console.log("Systemd is not available."),[2]);case 1:return n.sent(),console.log("Adding SSH service..."),r("echo '".concat("[Unit]\n Description=Wative SSH Server\n After=network.target\n\n [Service]\n ExecStart=/usr/local/bin/wative-ssh\n Restart=always\n User=root\n Group=root\n StandardOutput=append:/var/log/wative.log\n StandardError=append:/var/log/wative.err\n\n [Install]\n WantedBy=multi-user.target\n ","' > ").concat("/etc/systemd/system/wative.service"),{stdio:"inherit"}),r("systemctl daemon-reload",{stdio:"inherit"}),r("systemctl enable wative",{stdio:"inherit"}),r("systemctl start wative",{stdio:"inherit"}),[2]}}))}))})),p.command("remove").description("Remove SSH service").action((function(){d()?(console.log("Removing SSH service..."),r("systemctl stop wative",{stdio:"inherit"}),r("systemctl disable wative",{stdio:"inherit"}),r("rm /etc/systemd/system/wative.service",{stdio:"inherit"}),r("systemctl daemon-reload",{stdio:"inherit"})):console.log("Systemd is not available.")})),l.command("cmd").description("Start wallet-cli shell").action((function(){return o(void 0,void 0,void 0,(function(){return s(this,(function(e){try{r("wallet-cli",{stdio:"inherit"})}catch(e){}return[2]}))}))})),l.parse(process.argv);
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("path"),require("commander"),require("child_process"),require("fs"),require("ini"),require("figlet"),require("inquirer"),require("web3"),require("@solana/web3.js"),require("@solana/spl-token"),require("@metaplex-foundation/js"),require("bignumber.js")):"function"==typeof define&&define.amd?define(["path","commander","child_process","fs","ini","figlet","inquirer","web3","@solana/web3.js","@solana/spl-token","@metaplex-foundation/js","bignumber.js"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).path,e.commander,e.child_process,e.fs,e.ini)}(this,(function(e,t,r,n,i){"use strict";function o(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}})),t.default=e,Object.freeze(t)}var s=o(e),c=o(n),a=o(i);function l(e,t,r,n){return new(r||(r=Promise))((function(i,o){function s(e){try{a(n.next(e))}catch(e){o(e)}}function c(e){try{a(n.throw(e))}catch(e){o(e)}}function a(e){var t;e.done?i(e.value):(t=e.value,t instanceof r?t:new r((function(e){e(t)}))).then(s,c)}a((n=n.apply(e,t||[])).next())}))}function u(e,t){var r,n,i,o,s={label:0,sent:function(){if(1&i[0])throw i[1];return i[1]},trys:[],ops:[]};return o={next:c(0),throw:c(1),return:c(2)},"function"==typeof Symbol&&(o[Symbol.iterator]=function(){return this}),o;function c(c){return function(a){return function(c){if(r)throw new TypeError("Generator is already executing.");for(;o&&(o=0,c[0]&&(s=0)),s;)try{if(r=1,n&&(i=2&c[0]?n.return:c[0]?n.throw||((i=n.return)&&i.call(n),0):n.next)&&!(i=i.call(n,c[1])).done)return i;switch(n=0,i&&(c=[2&c[0],i.value]),c[0]){case 0:case 1:i=c;break;case 4:return s.label++,{value:c[1],done:!1};case 5:s.label++,n=c[1],c=[0];continue;case 7:c=s.ops.pop(),s.trys.pop();continue;default:if(!(i=s.trys,(i=i.length>0&&i[i.length-1])||6!==c[0]&&2!==c[0])){s=0;continue}if(3===c[0]&&(!i||c[1]>i[0]&&c[1]<i[3])){s.label=c[1];break}if(6===c[0]&&s.label<i[1]){s.label=i[1],i=c;break}if(i&&s.label<i[2]){s.label=i[2],s.ops.push(c);break}i[2]&&s.ops.pop(),s.trys.pop();continue}c=t.call(e,s)}catch(e){c=[6,e],n=0}finally{r=i=0}if(5&c[0])throw c[1];return{value:c[0]?c[1]:void 0,done:!0}}([c,a])}}}"function"==typeof SuppressedError&&SuppressedError,require("chalk"),require("chalk"),require("chalk"),process.env.HOME||process.env.USERPROFILE;require("bn.js").BN,require("ethereumjs-util").stripHexPrefix,require("bignumber.js").BigNumber,require("chalk"),require("wative-core").WativeCore,require("chalk"),require("dotenv").config(),require("cli-progress"),require("wative-core").WativeCore;var d=function(e){return l(void 0,void 0,void 0,(function(){var t,n,i,o,d,v,f;return u(this,(function(p){switch(p.label){case 0:return t="/etc/wative",c.existsSync(t)||c.mkdirSync(t),[4,l(void 0,void 0,void 0,(function(){var e,t,n,i,o;return u(this,(function(a){return e="/etc/wative",t=s.join(e,"id_rsa_server.pub"),n=s.join(e,"id_rsa_server"),c.existsSync(t)&&c.existsSync(n)||(console.log("Generating SSH key pair..."),r.execSync("ssh-keygen -t rsa -f ".concat(n," -N 'wative_server'"),{stdio:"inherit"})),i=s.join(e,"id_rsa_detake.pub"),o=s.join(e,"id_rsa_detake"),c.existsSync(i)&&c.existsSync(o)||(console.log("Generating SSH key pair..."),r.execSync("ssh-keygen -t rsa -f ".concat(o," -N 'wative_detake'"),{stdio:"inherit"})),[2]}))}))];case 1:return p.sent(),n=s.join(t,"config.ini"),c.existsSync(n)||(y=e,h=s.resolve(y,"network.json"),i=JSON.parse(c.readFileSync(h,"utf8")),o=i.accounts,d=function(e){for(var t=[],r=0;r<e.length;r++)t.push(e[r].trim().toLocaleLowerCase().replace(/\s+/g,"-").trim().replace(/\-+/g,"-").trim());return t}(o),v={keystore:{path:e,allowed_keystores:d},ssh:{listen:"127.0.0.1",port:5678}},f=a.stringify(v),c.writeFileSync(n,f)),[2,a.parse(c.readFileSync(n,"utf-8"))]}var y,h}))}))},v=require("os"),f=new t.Command,p=require("../package.json"),y=function(){try{return r.execSync("systemctl --version",{stdio:"ignore"}),!0}catch(e){return!1}};f.version(p.version).description("Wative CLI Tool"),f.command("version").description("Show the version of wative").action((function(){console.log("Wative CLI Tool v".concat(p.version))}));var h=f.command("ssh").description("Manage SSH service");h.command("start").description("Start SSH service").action((function(){if(y()){try{r.execSync("wative-ssh",{stdio:"inherit"})}catch(e){}console.log("Starting SSH service...")}else console.log("Systemd is not available.")}));var S=h.command("service").description("Manage SSH service");S.command("add").description("Add SSH service").action((function(){return l(void 0,void 0,void 0,(function(){var e,t;return u(this,(function(n){switch(n.label){case 0:return y()?(e=v.homedir(),t=s.join(e,".wative"),[4,d(t)]):(console.log("Systemd is not available."),[2]);case 1:return n.sent(),console.log("Adding SSH service..."),r.execSync("echo '".concat("[Unit]\n Description=Wative SSH Server\n After=network.target\n\n [Service]\n ExecStart=/usr/local/bin/wative-ssh\n Restart=always\n User=root\n Group=root\n StandardOutput=append:/var/log/wative.log\n StandardError=append:/var/log/wative.err\n\n [Install]\n WantedBy=multi-user.target\n ","' > ").concat("/etc/systemd/system/wative.service"),{stdio:"inherit"}),r.execSync("systemctl daemon-reload",{stdio:"inherit"}),r.execSync("systemctl enable wative",{stdio:"inherit"}),r.execSync("systemctl start wative",{stdio:"inherit"}),[2]}}))}))})),S.command("remove").description("Remove SSH service").action((function(){y()?(console.log("Removing SSH service..."),r.execSync("systemctl stop wative",{stdio:"inherit"}),r.execSync("systemctl disable wative",{stdio:"inherit"}),r.execSync("rm /etc/systemd/system/wative.service",{stdio:"inherit"}),r.execSync("systemctl daemon-reload",{stdio:"inherit"})):console.log("Systemd is not available.")})),f.command("cmd").description("Start wallet-cli shell").action((function(){return l(void 0,void 0,void 0,(function(){return u(this,(function(e){try{r.execSync("wallet-cli",{stdio:"inherit"})}catch(e){}return[2]}))}))})),f.parse(process.argv)}));
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "wative",
3
- "version": "1.0.38",
3
+ "version": "1.0.39",
4
4
  "description": "An agile keystore management toolkit",
5
5
  "main": "index.ts",
6
6
  "scripts": {
7
7
  "test": "jest",
8
8
  "compile": "tsc",
9
- "build": "rollup --config"
9
+ "build": "rollup --config rollup.config.js"
10
10
  },
11
11
  "bin": {
12
- "wallet-cli": "bin/wative-cli.js"
12
+ "wallet-cli": "bin/wative-cli.js",
13
+ "wative": "bin/wative.js",
14
+ "wative-ssh": "bin/wative-ssh.sh"
13
15
  },
14
16
  "repository": {
15
17
  "type": "git",
@@ -30,8 +32,10 @@
30
32
  "@metamask/bip39": "4.0.0",
31
33
  "@metaplex-foundation/js": "0.20.1",
32
34
  "@rollup/plugin-commonjs": "21.0.1",
35
+ "@rollup/plugin-typescript": "^12.1.2",
33
36
  "@solana/web3.js": "1.91.8",
34
37
  "@types/figlet": "1.5.8",
38
+ "@types/ini": "^4.1.1",
35
39
  "@types/inquirer": "9.0.7",
36
40
  "@types/node-fetch": "2.6.11",
37
41
  "bip39": "3.1.0",
@@ -41,16 +45,19 @@
41
45
  "ethereumjs-wallet": "1.0.2",
42
46
  "ethers-multicall": "0.2.3",
43
47
  "figlet": "1.7.0",
48
+ "ini": "^5.0.0",
44
49
  "inquirer": "8.0.0",
45
50
  "inquirer-table-input": "0.0.3",
46
51
  "inquirer-tree-prompt": "1.1.2",
47
52
  "keythereum": "2.0.0",
53
+ "log4js": "^6.9.1",
48
54
  "micro-ed25519-hdkey": "0.1.2",
49
55
  "node-fetch": "2.6.0",
50
56
  "rollup": "2.79.1",
51
57
  "rollup-plugin-terser": "7.0.2",
52
58
  "rollup-plugin-typescript2": "0.31.2",
53
59
  "rpc-websockets": "7.10.0",
60
+ "ssh2": "1.14.0",
54
61
  "uuid": "9.0.0",
55
62
  "wative-core": "1.0.17",
56
63
  "web3": "1.7.3"
@@ -59,5 +66,8 @@
59
66
  "lib": "lib",
60
67
  "test": "test"
61
68
  },
62
- "keywords": []
63
- }
69
+ "keywords": [],
70
+ "devDependencies": {
71
+ "@types/ssh2": "^1.15.4"
72
+ }
73
+ }
@@ -0,0 +1,52 @@
1
+ import WativeServer from './wative_server';
2
+ import * as path from 'path';
3
+ import { getAndGenerateConfig } from './utils';
4
+
5
+ require('dotenv').config();
6
+ const os = require('os');
7
+
8
+ const getKeystorePasswords = async (allowedKeystores: string[]) => {
9
+ const passwords: any = [];
10
+ for (let i = 0; i < allowedKeystores.length; i++) {
11
+ const keystore = allowedKeystores[i];
12
+ passwords.push(process.env[keystore]);
13
+ }
14
+ return passwords;
15
+ }
16
+
17
+ const main = async () => {
18
+ const userHomeDirectory = os.homedir();
19
+ const keystorePath = path.join(userHomeDirectory, '.wative');
20
+
21
+ let config = await getAndGenerateConfig(keystorePath);
22
+
23
+ const export_server_listen = config.ssh.listen;
24
+ const export_server_port = config.ssh.port;
25
+ const id_rsa_private_key_path = "/etc/wative/id_rsa_server";
26
+ const id_rsa_password = "wative_server";
27
+
28
+ const client_name = 'detake';
29
+ const client_id_rsa_public_key_path = "/etc/wative/id_rsa_detake.pub";
30
+ const client_keystores = config.keystore.allowed_keystores;
31
+ const client_keystore_passwords = await getKeystorePasswords(client_keystores);
32
+
33
+ // return
34
+ const wativeServer = new WativeServer(
35
+ id_rsa_private_key_path,
36
+ id_rsa_password,
37
+ [client_name],
38
+ [client_id_rsa_public_key_path],
39
+ [client_keystores],
40
+ keystorePath,
41
+ client_keystores,
42
+ client_keystore_passwords,
43
+ );
44
+
45
+ wativeServer.listen(export_server_listen, export_server_port);
46
+ }
47
+
48
+ process.on('unhandledRejection', (reason, p) => {
49
+ console.log('Unhandled Rejection at:', p, 'reason:', reason);
50
+ });
51
+
52
+ main()
@@ -0,0 +1,18 @@
1
+ import { TxParams } from "@walletbunker/core/lib/types"
2
+
3
+ type SubAccountMessageParams = {
4
+ rootAccount: string,
5
+ chainId: string,
6
+ startIndex?: number,
7
+ endIndex?: number
8
+ }
9
+
10
+ type SignMessageParams = {
11
+ txParams: TxParams,
12
+ rpcUrl: string
13
+ }
14
+
15
+ export {
16
+ SubAccountMessageParams,
17
+ SignMessageParams
18
+ }
@@ -0,0 +1,85 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as ini from 'ini';
4
+ import { execSync } from 'child_process';
5
+ import { getNetworkInfo } from '../account';
6
+ import { batchGetKeystoreSlugByAccountName } from '../utils';
7
+
8
+
9
+ /**
10
+ * Check the existence of the file
11
+ * @filePath
12
+ */
13
+ const checkFileExistence = (filePath: string) => {
14
+ filePath = filePath.trim()
15
+ let isExists = fs.existsSync(filePath)
16
+ if (!isExists) {
17
+ throw new Error('File not exists')
18
+ }
19
+ }
20
+
21
+ function sleep(time = 0) {
22
+ return new Promise((resolve, reject) => {
23
+ setTimeout(() => {
24
+ resolve(true)
25
+ }, time)
26
+ })
27
+ }
28
+
29
+ const createSSHKeyPair = async () => {
30
+ const configDir = "/etc/wative";
31
+ const idRsaServerPublicKeyPath = path.join(configDir, 'id_rsa_server.pub');
32
+ const idRsaServerPrivateKeyPath = path.join(configDir, 'id_rsa_server');
33
+
34
+ if (!fs.existsSync(idRsaServerPublicKeyPath) || !fs.existsSync(idRsaServerPrivateKeyPath)) {
35
+ console.log('Generating SSH key pair...');
36
+ execSync(`ssh-keygen -t rsa -f ${idRsaServerPrivateKeyPath} -N 'wative_server'`, { stdio: 'inherit' });
37
+ }
38
+
39
+ const idRsaDetakePublicKeyPath = path.join(configDir, 'id_rsa_detake.pub');
40
+ const idRsaDetakePrivateKeyPath = path.join(configDir, 'id_rsa_detake');
41
+
42
+ if (!fs.existsSync(idRsaDetakePublicKeyPath) || !fs.existsSync(idRsaDetakePrivateKeyPath)) {
43
+ console.log('Generating SSH key pair...');
44
+ execSync(`ssh-keygen -t rsa -f ${idRsaDetakePrivateKeyPath} -N 'wative_detake'`, { stdio: 'inherit' });
45
+ }
46
+ }
47
+
48
+
49
+ const getAndGenerateConfig = async (keystorePath: string) => {
50
+ const configDir = "/etc/wative";
51
+ if (!fs.existsSync(configDir)) {
52
+ fs.mkdirSync(configDir);
53
+ }
54
+
55
+ await createSSHKeyPair();
56
+ const configPath = path.join(configDir, 'config.ini');
57
+ if (!fs.existsSync(configPath)) {
58
+ const networks = getNetworkInfo(keystorePath);
59
+ const account_name_list = networks.accounts;
60
+ const keystore_slug_list = batchGetKeystoreSlugByAccountName(account_name_list);
61
+ const keystore: any = {
62
+ path: keystorePath,
63
+ allowed_keystores: keystore_slug_list,
64
+ }
65
+ const ssh: any = {
66
+ listen: '127.0.0.1',
67
+ port: 5678,
68
+ }
69
+ const config = {
70
+ keystore,
71
+ ssh,
72
+ }
73
+ let text = ini.stringify(config);
74
+ fs.writeFileSync(configPath, text);
75
+ }
76
+
77
+ const config = ini.parse(fs.readFileSync(configPath, 'utf-8'));
78
+ return config;
79
+ }
80
+
81
+ export {
82
+ checkFileExistence,
83
+ sleep,
84
+ getAndGenerateConfig,
85
+ }
@@ -0,0 +1,515 @@
1
+ import * as path from "path";
2
+ import { readFileSync } from 'fs';
3
+ import { utils, Server } from 'ssh2';
4
+ import { timingSafeEqual } from 'crypto';
5
+ import { checkFileExistence } from './utils';
6
+ import { SignMessageParams, SubAccountMessageParams } from './types';
7
+ import * as log4js from "log4js";
8
+ import { ethers } from 'ethers';
9
+
10
+ const { WativeCore } = require("wative-core");
11
+ const { Connection, PublicKey, VersionedTransaction, VersionedMessage } = require("@solana/web3.js");
12
+ const bs58 = require("bs58");
13
+ const { Keypair, TransactionMessage, ComputeBudgetInstruction, TransactionInstruction, ComputeBudgetProgram } = require("@solana/web3.js");
14
+ const { Wallet } = require("@coral-xyz/anchor");
15
+ const logger = log4js.getLogger();
16
+ logger.level = "info";
17
+
18
+ export class WativeWielderServer {
19
+ private wativeCore: any;
20
+ private _allowedAppIds: Buffer[] = [];
21
+ private _allowedPubKeys: any[] = [];
22
+ private _allowedKeystoreIds: string[][] = [];
23
+
24
+ private _idRsaPrivatePath: string;
25
+ private _idRsaPassphrase: string | undefined;
26
+
27
+ private _keystoreDirectoryPath: string;
28
+ private _sessionIdAppIdMap: any = {};
29
+
30
+ public constructor(
31
+ idRsaPrivatePath: string,
32
+ idRsaPassphrase: string | undefined,
33
+
34
+ allowedAppIds: string[],
35
+ allowedPublicKeyPath: string[],
36
+ allowedKeystoreIds: string[][],
37
+
38
+ keystoreDirectoryPath: string,
39
+ keystoreIds: string[],
40
+ passwords: string[],
41
+ ) {
42
+ checkFileExistence(idRsaPrivatePath);
43
+
44
+ if (
45
+ allowedAppIds.length === 0 ||
46
+ allowedPublicKeyPath.length === 0 ||
47
+ allowedKeystoreIds.length === 0 ||
48
+ allowedAppIds.length !== allowedPublicKeyPath.length ||
49
+ allowedAppIds.length !== allowedKeystoreIds.length
50
+ ) {
51
+ throw new Error('WativeWielderServer:: constructor: Invaild AllowedApp');
52
+ }
53
+
54
+ for (let i = 0; i < allowedKeystoreIds.length; i++) {
55
+ for (let j = 0; j < allowedKeystoreIds[i].length; j++) {
56
+ const keystoreId = allowedKeystoreIds[i][j];
57
+
58
+ if (!keystoreIds.includes(keystoreId)) {
59
+ throw new Error('WativeWielderServer:: constructor: Invaild AllowedKeystoreIds');
60
+ }
61
+ }
62
+ }
63
+
64
+ for (let allowedAppId of allowedAppIds) {
65
+ this._allowedAppIds.push(
66
+ Buffer.from(allowedAppId)
67
+ )
68
+ }
69
+
70
+ for (let _allowedPublicKeyFilePath of allowedPublicKeyPath) {
71
+ let _parsedKey = utils.parseKey(readFileSync(_allowedPublicKeyFilePath));
72
+ this._allowedPubKeys.push(_parsedKey)
73
+ }
74
+
75
+ this.wativeCore = new WativeCore(keystoreDirectoryPath, keystoreIds, passwords);
76
+
77
+ this._idRsaPrivatePath = idRsaPrivatePath;
78
+ this._idRsaPassphrase = idRsaPassphrase;
79
+ this._allowedKeystoreIds = allowedKeystoreIds;
80
+
81
+ this._keystoreDirectoryPath = keystoreDirectoryPath;
82
+ }
83
+
84
+ public listen(host: string, port: number) {
85
+ new Server({
86
+ hostKeys: [{
87
+ key: readFileSync(this._idRsaPrivatePath),
88
+ passphrase: this._idRsaPassphrase
89
+ }]
90
+ }, (client: any) => {
91
+ client.on('authentication', (ctx: any) => {
92
+ let allowed = true;
93
+
94
+ if (this)
95
+ if (!this.checkValue(Buffer.from(ctx.username), 'appId')) {
96
+ allowed = false;
97
+ }
98
+
99
+ if (ctx.method === 'publickey' && allowed) {
100
+ let allowedAppIndex = this.getBytesIndex(Buffer.from(ctx.username), this._allowedAppIds);
101
+
102
+ let allowedPubKey = this._allowedPubKeys[allowedAppIndex];
103
+
104
+ if (ctx.key.algo !== allowedPubKey.type
105
+ || !this.checkValue(ctx.key.data, 'publicKey')
106
+ || (ctx.signature && allowedPubKey.verify(ctx.blob, ctx.signature, ctx.hashAlgo) !== true)) {
107
+ return ctx.reject();
108
+ }
109
+ } else {
110
+ return ctx.reject();
111
+ }
112
+
113
+ if (allowed) {
114
+ const sessionID = client._protocol._kex.sessionID.toString('hex');
115
+ this._sessionIdAppIdMap[sessionID] = Buffer.from(ctx.username);
116
+ ctx.accept();
117
+ } else {
118
+ ctx.reject();
119
+ }
120
+ }).on('ready', () => {
121
+
122
+ client.on('session', (accept: any, reject: any) => {
123
+ const session = accept();
124
+ session.once('exec', async (accept: any, reject: any, info: any) => {
125
+ const sessionID = client._protocol._kex.sessionID.toString('hex');
126
+ const result = await this.web3Request(sessionID, info.command);
127
+ const stream = accept();
128
+ if (!stream) {
129
+ return;
130
+ }
131
+
132
+ if (!JSON.stringify(result)) {
133
+ stream.write("ssh2 connect error");
134
+ stream.exit(0);
135
+ stream.end();
136
+ } else {
137
+ stream.write(JSON.stringify(result));
138
+ stream.exit(0);
139
+ stream.end();
140
+ }
141
+ })
142
+ });
143
+ }).on('close', () => {
144
+ logger.info('Client disconnected');
145
+ }).on('error', (err: any) => {
146
+ logger.error('err: ', err.message);
147
+ });
148
+ }).listen(port, host, function () {
149
+ logger.info('Listening on port ' + port);
150
+ })
151
+ }
152
+
153
+ private async web3Request(sessionID: string, message: string) {
154
+ try {
155
+ const appId = this._sessionIdAppIdMap[sessionID];
156
+ const appIndex = this.getBytesIndex(appId, this._allowedAppIds);
157
+ if (appIndex < 0) {
158
+ return { status: false, msg: 'app not found' };
159
+ }
160
+
161
+ let messageData = JSON.parse(message);
162
+ logger.info("sign message: ", message);
163
+ let _messageMethod: string = messageData.method;
164
+ let _keystoreId: string = messageData.keystoreId || messageData.params.keystoreId;
165
+ let _chainId: string = messageData.chainId || messageData.params.chainId;
166
+
167
+ const allowedKeystoreIds = this._allowedKeystoreIds[appIndex];
168
+ if (!allowedKeystoreIds.includes(_keystoreId)) {
169
+ return { status: false, msg: 'keystore not allowed' };
170
+ }
171
+
172
+ let _data: any;
173
+ if (_messageMethod === "get_root_account") {
174
+ _data = this.getRootAccount(_keystoreId, _chainId);
175
+ // _data = this.wativeCore.account.getRootAccounts(_keystoreId);
176
+
177
+ } else if (_messageMethod === "get_sub_account") {
178
+ let _message: SubAccountMessageParams = messageData.params;
179
+
180
+ _data = this.getSubAccount(_keystoreId, _message.chainId, _message?.startIndex, _message?.endIndex);
181
+ } else if (_messageMethod === "sign") {
182
+ let _message: SignMessageParams = messageData.params;
183
+ try {
184
+ _data = await this.wativeCore.account.signTransaction(_message.txParams.from, _message.txParams, _message.rpcUrl);
185
+ } catch (err: any) {
186
+ logger.error("sign error: ", err.message);
187
+ return { status: false, msg: err.msg };
188
+ }
189
+ } else if (_messageMethod === "sign_and_send") {
190
+ let _message: SignMessageParams = messageData.params;
191
+ try {
192
+ let txHash = await this.wativeCore.account.signAndSendTx(_message.txParams, _message.rpcUrl);
193
+ _data = {
194
+ transactionHash: txHash
195
+ }
196
+ } catch (err: any) {
197
+ return { status: false, msg: err.msg };
198
+ }
199
+ } else if (_messageMethod === "solana_sign") {
200
+ try {
201
+ let _message = messageData.params;
202
+ _data = await this.signSolanaTransaction(_message.txParams.from, _message.txParams.data, _message.txParams.lookup_tables, _message.rpcUrl, _message.priority_fee);
203
+ } catch (err: any) {
204
+ logger.error("sign error: ", err.message);
205
+ return { status: false, msg: err.msg };
206
+ }
207
+ } else if (_messageMethod === "solana_send") {
208
+ try {
209
+ let _message = messageData.params;
210
+ _data = await this.sendSignedSolanaTransaction(_message.txParams.from, _message.txParams.signature, _message.txParams.data, _message.rpcUrl);
211
+ } catch (err: any) {
212
+ logger.error("sign error: ", err.message);
213
+ return { status: false, msg: err.msg };
214
+ }
215
+
216
+ } else if (_messageMethod === "sign_message") {
217
+ try {
218
+ let _message = messageData.params;
219
+ logger.debug("sign message: ", _message);
220
+ _data = await this.signMessage(_message.account, _message.message);
221
+ } catch (err: any) {
222
+ logger.error("sign error: ", err.message);
223
+ return { status: false, msg: err.msg };
224
+ }
225
+ } else if (_messageMethod === "sign_typed_data") {
226
+ try {
227
+ let _message = messageData.params;
228
+ logger.debug("sign message: ", _message);
229
+ _data = await this.signTypedData(_message.account, _message.domain, _message.types_name, _message.types, _message.message)
230
+ } catch (err: any) {
231
+ logger.error("sign error: ", err.message);
232
+ return { status: false, msg: err.msg };
233
+ }
234
+ } else {
235
+ return { status: false, msg: 'message method not find' };
236
+ }
237
+
238
+ return { status: true, data: _data };
239
+ } catch (err: any) {
240
+ logger.error("sign error: ", err.message);
241
+ return { status: false, msg: err.msg };
242
+ }
243
+ }
244
+
245
+ private checkValue(input: Buffer, checkTypes: string) {
246
+
247
+ if (checkTypes !== 'appId' && checkTypes !== 'publicKey') {
248
+ return false;
249
+ }
250
+
251
+ let allowedSize = this._allowedAppIds.length;
252
+ for (let i = 0; i < allowedSize; i++) {
253
+ let allowed: Buffer;
254
+ if (checkTypes === 'appId') {
255
+ allowed = this._allowedAppIds[i];
256
+ } else {
257
+ allowed = this._allowedPubKeys[i].getPublicSSH();
258
+ }
259
+
260
+ const autoReject = (input.length !== allowed.length);
261
+ if (autoReject) {
262
+ allowed = input;
263
+ }
264
+ const isMatch = timingSafeEqual(input, allowed);
265
+
266
+ if (!autoReject && isMatch) {
267
+ return true;
268
+ }
269
+ }
270
+ }
271
+
272
+ private getBytesIndex(buf: Buffer, bufList: Buffer[]) {
273
+ let bufSize = bufList.length;
274
+
275
+ for (let i = 0; i < bufSize; i++) {
276
+ if (buf.length === bufList[i].length && timingSafeEqual(buf, bufList[i])) {
277
+ return i;
278
+ }
279
+ }
280
+
281
+ return -1;
282
+ }
283
+
284
+ private getRootAccount(keystoreId: string, chainId: string) {
285
+ const keystore_path = path.resolve(this._keystoreDirectoryPath, `accounts/${keystoreId}.json`);
286
+ let keystore_info: any = readFileSync(keystore_path);
287
+ keystore_info = JSON.parse(keystore_info.toString());
288
+
289
+ let chainType = this.getChainType(chainId);
290
+
291
+ let root_address;
292
+ if (chainType === "SOLANA") {
293
+ root_address = keystore_info.data[0].ciphertexts.solana.address;
294
+ } else {
295
+ root_address = keystore_info.data[0].ciphertexts.evm.address;
296
+ }
297
+ return [{
298
+ id: 0,
299
+ address: root_address,
300
+ children: keystore_info.data.length,
301
+ type: "M"
302
+ }];
303
+ }
304
+
305
+
306
+ private getChainType(chainId: string) {
307
+ if (chainId === "901" || chainId === "902" || chainId === "903") {
308
+ return "SOLANA";
309
+ }
310
+ return "EVM";
311
+ }
312
+
313
+ private getSubAccount(keystoreId: string, chainId: string, startIndex?: number, endIndex?: number) {
314
+ const keystore_path = path.resolve(this._keystoreDirectoryPath, `accounts/${keystoreId}.json`);
315
+ let keystore_info: any = readFileSync(keystore_path);
316
+ keystore_info = JSON.parse(keystore_info.toString());
317
+
318
+ let keystore_info_len = keystore_info.data.length;
319
+ let _endIndex = keystore_info_len - 1;
320
+ if (endIndex && endIndex < _endIndex) {
321
+ _endIndex = endIndex;
322
+ }
323
+
324
+ let _startIndex = 0;
325
+ if (startIndex && startIndex > 0) {
326
+ _startIndex = startIndex;
327
+ }
328
+
329
+ if (_startIndex > _endIndex) {
330
+ return [];
331
+ }
332
+
333
+ let chainType = this.getChainType(chainId);
334
+ let result: any = [];
335
+ for (let i = _startIndex; i <= _endIndex; i++) {
336
+ result.push(keystore_info.data[i].ciphertexts[chainType.toLocaleLowerCase()].address);
337
+ }
338
+
339
+ return result;
340
+ }
341
+
342
+ private async signMessage(account: string, message: string) {
343
+ let signature = await this.wativeCore.account.signMessage(account, message);
344
+ console.log(signature);
345
+ return signature;
346
+ }
347
+
348
+ private async signTypedData(account: string, message_domain: string, message_types_name: string, message_types: string, message_data: string) {
349
+ console.log("111");
350
+ let domain = JSON.parse(message_domain);
351
+ let types = JSON.parse(message_types);
352
+ let data = JSON.parse(message_data);
353
+
354
+ console.log(domain);
355
+ console.log(types);
356
+ console.log(data);
357
+ let pkl = this.wativeCore.account.showPrivateKey(account);
358
+ let wallet: any = new ethers.Wallet(pkl);
359
+ let signature = await wallet.signTypedData(domain, {
360
+ [message_types_name]: types
361
+ }, data);
362
+
363
+ console.log(signature);
364
+ return {
365
+ "status": true,
366
+ "output": signature
367
+ };
368
+ }
369
+
370
+ private async signSolanaTransaction(from: string, data: string, lookup_table_addresses: any, rpc_url: string, prioritization_fee: any) {
371
+ let connection = new Connection(rpc_url);
372
+
373
+ let lookup_table_list: any = [];
374
+ if (lookup_table_addresses) {
375
+ for (let lookup_table_address of lookup_table_addresses) {
376
+ let lookup_table = (await connection.getAddressLookupTable(new PublicKey(lookup_table_address))).value;
377
+ lookup_table_list.push(lookup_table);
378
+ await sleep(1000);
379
+ }
380
+ }
381
+
382
+ let versionedMessage = VersionedMessage.deserialize(Uint8Array.from(Buffer.from(data, "hex")));
383
+ let decompiled_transaction_message = TransactionMessage.decompile(versionedMessage);
384
+ decompiled_transaction_message.instructions.push(
385
+ ComputeBudgetProgram.setComputeUnitLimit({
386
+ units: 2000000
387
+ })
388
+ );
389
+ decompiled_transaction_message.instructions.push(
390
+ ComputeBudgetProgram.setComputeUnitPrice({
391
+ microLamports: 1000
392
+ })
393
+ );
394
+
395
+ versionedMessage = decompiled_transaction_message.compileToV0Message(lookup_table_list);
396
+ versionedMessage.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
397
+
398
+ await sleep(3000);
399
+ let versionedTransaction = new VersionedTransaction(versionedMessage);
400
+ let pkl = this.wativeCore.account.showPrivateKey(from);
401
+ const owner = Keypair.fromSecretKey(new Uint8Array(bs58.decode(pkl)));
402
+ const wallet = new Wallet(owner);
403
+
404
+ let simulate_transaction_result = await connection.simulateTransaction(versionedTransaction);
405
+ if (!simulate_transaction_result || !simulate_transaction_result.value || simulate_transaction_result.value.unitsConsumed === 0 || simulate_transaction_result.value.err) {
406
+ return {
407
+ status: false,
408
+ output: simulate_transaction_result.value.err
409
+ }
410
+ }
411
+
412
+ let message_instruction_length = decompiled_transaction_message.instructions.length;
413
+ let units_consumed = Math.trunc(simulate_transaction_result.value.unitsConsumed * 1.2);
414
+ decompiled_transaction_message.instructions[message_instruction_length - 2] = ComputeBudgetProgram.setComputeUnitLimit({
415
+ units: units_consumed
416
+ });
417
+
418
+ if (!prioritization_fee || prioritization_fee == "null") {
419
+ try {
420
+ prioritization_fee = await this.getPrioritizationFee(rpc_url);
421
+ } catch (err) {
422
+ prioritization_fee = 200000;
423
+ }
424
+ }
425
+
426
+ if (prioritization_fee < 10000) {
427
+ prioritization_fee = 10000;
428
+ }
429
+
430
+ if (prioritization_fee > 500000) {
431
+ prioritization_fee = 500000;
432
+ }
433
+
434
+ decompiled_transaction_message.instructions[message_instruction_length - 1] = ComputeBudgetProgram.setComputeUnitPrice({
435
+ microLamports: prioritization_fee
436
+ })
437
+
438
+ versionedMessage = decompiled_transaction_message.compileToV0Message(lookup_table_list);
439
+ await sleep(1000);
440
+ versionedMessage.recentBlockhash = (await connection.getLatestBlockhash()).blockhash;
441
+ versionedTransaction = new VersionedTransaction(versionedMessage);
442
+
443
+ versionedTransaction.feePayer = wallet.publicKey;
444
+ await sleep(3000);
445
+ let signedTransaction = await this.wativeCore.account.signTransaction(from, versionedTransaction, rpc_url);
446
+ let new_versioned_transaction = new VersionedTransaction(signedTransaction.output.message, signedTransaction.output.signatures);
447
+ let new_message = new_versioned_transaction.message.serialize();
448
+ new_message = Buffer.from(new_message).toString("hex");
449
+
450
+ let tx_hash = bs58.encode(signedTransaction.output.signatures[0]);
451
+ return {
452
+ status: true,
453
+ output: {
454
+ transactionHash: tx_hash,
455
+ message: new_message,
456
+ compute_units: simulate_transaction_result.value.unitsConsumed.toString()
457
+ }
458
+ }
459
+ }
460
+
461
+ private async sendSignedSolanaTransaction(from: string, signature: string, data: string, rpc_url: string) {
462
+ let signatures = [
463
+ bs58.decode(signature)
464
+ ];
465
+
466
+ let versionedMessage = VersionedMessage.deserialize(Uint8Array.from(Buffer.from(data, "hex")));
467
+ let versionedTransaction = new VersionedTransaction(versionedMessage, signatures);
468
+
469
+ return await this.wativeCore.account.sendSignedTransaction(from, versionedTransaction, rpc_url);
470
+ }
471
+
472
+ private async getPrioritizationFee(rpc_url: string) {
473
+ let program_id = new PublicKey("JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4");
474
+ const connection = new Connection(rpc_url, "confirmed");
475
+ let signatures_info: any = await connection.getSignaturesForAddress(program_id, { limit: 5 });
476
+ await sleep(2000);
477
+
478
+ let signatures: any = [];
479
+ for (let i = 0; i < signatures_info.length; i++) {
480
+ signatures.push(signatures_info[i].signature);
481
+ }
482
+ let transaction: any = await connection.getParsedTransactions(signatures, {
483
+ maxSupportedTransactionVersion: 0,
484
+ });
485
+
486
+ let total_prioritization_fee = 0;
487
+ for (let i = 0; i < transaction.length; i++) {
488
+ let instructions_list = transaction[i].transaction.message.instructions;
489
+ for (let j = 0; j < instructions_list.length; j++) {
490
+ if (instructions_list[j].programId.toBase58() === "ComputeBudget111111111111111111111111111111") {
491
+ let data = instructions_list[j].data;
492
+ try {
493
+ let instruction = new TransactionInstruction({
494
+ keys: [],
495
+ programId: new PublicKey("ComputeBudget111111111111111111111111111111"),
496
+ data: Buffer.from(bs58.decode(data))
497
+ });
498
+
499
+ let { microLamports } = ComputeBudgetInstruction.decodeSetComputeUnitPrice(instruction)
500
+ total_prioritization_fee += Number(microLamports);
501
+ continue;
502
+ } catch (error) { }
503
+ }
504
+ }
505
+ }
506
+
507
+ return Math.ceil(total_prioritization_fee / 5)
508
+ }
509
+ }
510
+
511
+ export const sleep = (ms: number) => {
512
+ return new Promise((resolve) => setTimeout(resolve, ms));
513
+ }
514
+
515
+ export default WativeWielderServer;
package/src/wative.ts ADDED
@@ -0,0 +1,127 @@
1
+ import * as path from 'path';
2
+ import { Command } from 'commander';
3
+ import { execSync } from 'child_process';
4
+ import { getAndGenerateConfig } from './ssh/utils';
5
+
6
+ const os = require('os');
7
+ const program = new Command();
8
+ const packageJson = require('../package.json');
9
+
10
+ const hasSystemd = () => {
11
+ try {
12
+ execSync('systemctl --version', { stdio: 'ignore' });
13
+ return true;
14
+ } catch (error) {
15
+ return false;
16
+ }
17
+ };
18
+
19
+ program
20
+ .version(packageJson.version) // 版本信息
21
+ .description('Wative CLI Tool');
22
+
23
+ // 定义 wative version 命令
24
+ program
25
+ .command('version')
26
+ .description('Show the version of wative')
27
+ .action(() => {
28
+ console.log(`Wative CLI Tool v${packageJson.version}`);
29
+ });
30
+
31
+
32
+ const sshCommand = program.command('ssh').description('Manage SSH service');
33
+
34
+ sshCommand
35
+ .command('start')
36
+ .description('Start SSH service')
37
+ .action(() => {
38
+ if (!hasSystemd()) {
39
+ console.log('Systemd is not available.');
40
+ return;
41
+ }
42
+
43
+ try {
44
+ execSync('wative-ssh', { stdio: 'inherit' });
45
+ } catch (error) { }
46
+
47
+ console.log('Starting SSH service...');
48
+ });
49
+
50
+ // sshCommand
51
+ // .command('stop')
52
+ // .description('Stop SSH service')
53
+ // .action(() => {
54
+ // if (!hasSystemd()) {
55
+ // console.log('Systemd is not available.');
56
+ // return;
57
+ // }
58
+ // console.log('Stopping SSH service...');
59
+ // });
60
+
61
+
62
+ const sshServiceCommand = sshCommand.command('service').description('Manage SSH service');
63
+ sshServiceCommand
64
+ .command('add')
65
+ .description('Add SSH service')
66
+ .action(async () => {
67
+ if (!hasSystemd()) {
68
+ console.log('Systemd is not available.');
69
+ return;
70
+ }
71
+
72
+ const userHomeDirectory = os.homedir();
73
+ const keystorePath = path.join(userHomeDirectory, '.wative');
74
+
75
+ await getAndGenerateConfig(keystorePath);
76
+
77
+ const serviceFilePath = '/etc/systemd/system/wative.service';
78
+ const serviceContent = `[Unit]
79
+ Description=Wative SSH Server
80
+ After=network.target
81
+
82
+ [Service]
83
+ ExecStart=/usr/local/bin/wative-ssh
84
+ Restart=always
85
+ User=root
86
+ Group=root
87
+ StandardOutput=append:/var/log/wative.log
88
+ StandardError=append:/var/log/wative.err
89
+
90
+ [Install]
91
+ WantedBy=multi-user.target
92
+ `;
93
+
94
+ console.log('Adding SSH service...');
95
+ execSync(`echo '${serviceContent}' > ${serviceFilePath}`, { stdio: 'inherit' });
96
+ execSync('systemctl daemon-reload', { stdio: 'inherit' });
97
+ execSync('systemctl enable wative', { stdio: 'inherit' });
98
+ execSync('systemctl start wative', { stdio: 'inherit' });
99
+ });
100
+
101
+ sshServiceCommand
102
+ .command('remove')
103
+ .description('Remove SSH service')
104
+ .action(() => {
105
+ if (!hasSystemd()) {
106
+ console.log('Systemd is not available.');
107
+ return;
108
+ }
109
+ console.log('Removing SSH service...');
110
+ execSync('systemctl stop wative', { stdio: 'inherit' });
111
+ execSync('systemctl disable wative', { stdio: 'inherit' });
112
+ execSync('rm /etc/systemd/system/wative.service', { stdio: 'inherit' });
113
+ execSync('systemctl daemon-reload', { stdio: 'inherit' });
114
+ });
115
+
116
+
117
+ // 定义 wative cmd 命令
118
+ program
119
+ .command('cmd')
120
+ .description('Start wallet-cli shell')
121
+ .action(async () => {
122
+ try {
123
+ execSync('wallet-cli', { stdio: 'inherit' });
124
+ } catch (error) { }
125
+ });
126
+
127
+ program.parse(process.argv);