diff --git a/chrome-extension/public/injected.js b/chrome-extension/public/injected.js index f26da71..3792b27 100644 --- a/chrome-extension/public/injected.js +++ b/chrome-extension/public/injected.js @@ -1,19 +1,19 @@ -"use strict";(()=>{var V="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function L(r){let e=[0];for(let t of r){let s=V.indexOf(t);if(s===-1)throw new Error("Invalid base58 character");let n=s;for(let a=0;a>=8;for(;n>0;)e.push(n&255),n>>=8}for(let t of r){if(t!=="1")break;e.push(0)}return new Uint8Array(e.reverse())}var U=class r{#a;#e=[];#t=null;#r=new Set;version="1.0.0";name="KeepKey";icon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAIKADAAQAAAABAAAAIAAAAACshmLzAAADUklEQVRYCb1XTUgUYRie3bXEWhVLQaUsgwVLoUtEQjUJiZX0A0GX7BIZXurkOTSvdo2kvETHAsOshFgqOqhlRD9C7SGS1JTCsj1krU7PM+w7zMzOzuzMqi88+73v9z7vz3zzzTeziuIgmqbFgG5gBPguFOgq4CXLIMwCo0AXEJN4zxHkEuA6kAIMkUBMqMZk7so/UG8AUcnjOIKwFXgHZIgEwKFmOHOfYO4aySVjmAoc7O4R0EB7lYS5h9K1jBJ6A7CuAfXG7OopbKLXkh4dccNZ7jlsi0gAJlWLI5jBPWFsTK5AGxCRImswFqDGWanDBo6IsYbjUanFbmrFWIHxD3IsmfJsgB4y2aJuF4UrUC5GnuNtxJeEQqEoAb3LJV+F4ctlHwkZXDULv8fEKQCHB4+rCJ9ngKcIGUTVRubT027y8yR9bOM4mhKTTwNJZD4miaDXAG8dqzlMShw3YRCZRVAr7vU4g5F/D4ZBoJK2H+Em9CsfEdBoKn4K9jPAd3G9sMPqZEzpRPzAwRfWJpN9EfZSRkAOE5LD7wrw8dkpwRh55VMm27fqt4FiVBjGBTaxEm4Db8d+4BPtIOK3AdbYCPC1qh/haGIS9gHgDeBbgjTAIkXAfTRxkgaamMNwCHgB+BMk4Decq0hGkFQbka/WMyZ/EeyHNo6TuSwx3Nn8gHQVIYOkOhB5Gp4zcdbBHiDvZ2pRuzozru2euKuDOucg/KliTAjKKMa9ksBpxBLrbzRwVfifOnB4RR2g3QSH3Cfx5FRdc2KoGstroUeQKh47vnAwWvUKjsPcA/wWdBUkjRAgZdsznO8D5xLGC/Opxc3NiQeV9uIsgkNDaUoMFpNDLleAn0cTQNBjGaFW6fn2Wrky/dI6abPOl9eN9deoWhjLloCv3+bPy7w3/9kzfvjX120g1cuSdsJ47xm1CgS9AaxCErlbV6qJ02W1nq22lG75AtIHWQEeJpOYaAT6gBQQWC5XNCjc7dkkHFKWe6v3FcLfbzRAMlcC6IC6C+gGxgCectZnCRMuopVG1v+Nx04sYINlxLH4wI6W52UFhT+Q41b2Nl0qeLnwZPGQucNHrXN6ZDG94RQuO688XbwNFzvjlSuwH03wEW8H+Bf/dxrUOWdc+H8mKXtEpGpY3AAAAABJRU5ErkJggg==";chains=["solana:mainnet"];static ACCOUNT_FEATURES=["solana:signTransaction","solana:signAndSendTransaction","solana:signMessage"];get accounts(){return this.#e}features={"standard:connect":{version:"1.0.0",connect:async()=>{if(this.#e.length>0)return{accounts:this.#e};let e=await this.#s("solana_getAccounts",[]).catch(()=>null);if(!Array.isArray(e)||e.length===0){let t=this.#t||await this.#s("solana_connect",[]);e=t?[{address:t}]:[]}return this.#o(e),{accounts:this.#e}}},"standard:disconnect":{version:"1.0.0",disconnect:async()=>{await this.#s("solana_disconnect",[]).catch(()=>{}),this.#e=[];try{localStorage.removeItem("keepkey-solana")}catch{}this.#n()}},"standard:events":{version:"1.0.0",on:(e,t)=>(e==="change"&&this.#r.add(t),()=>{this.#r.delete(t)})},"solana:signMessage":{version:"1.0.0",signMessage:async(...e)=>{let t=[];for(let{message:s,account:n}of e){let a=await this.#s("solana_signMessage",[Array.from(s),{accountAddress:n==null?void 0:n.address}]);t.push({signedMessage:s,signature:new Uint8Array(a)})}return t}},"solana:signTransaction":{version:"1.0.0",supportedTransactionVersions:new Set(["legacy",0]),signTransaction:async(...e)=>{let t=[];for(let{transaction:s,account:n}of e){let a=await this.#s("solana_signTransaction",[Array.from(s),{accountAddress:n==null?void 0:n.address}]);t.push({signedTransaction:new Uint8Array(a)})}return t}},"solana:signAndSendTransaction":{version:"1.0.0",supportedTransactionVersions:new Set(["legacy",0]),signAndSendTransaction:async(...e)=>{let t=[];for(let{transaction:s,account:n}of e){let a=await this.#s("solana_signAndSendTransaction",[Array.from(s),{accountAddress:n==null?void 0:n.address}]);t.push({signature:L(a)})}return t}},"keepkey:signOffchainMessage":{version:"1.0.0",signOffchainMessage:async e=>{let t=typeof e.message=="string"?Array.from(new TextEncoder().encode(e.message)):Array.from(e.message);return await this.#s("solana_signOffchainMessage",[{message:t,version:e.version,messageFormat:e.messageFormat}])}},"solana:signIn":{version:"1.0.0",signIn:async(...e)=>{var s;let t=[];for(let n of e){if(this.#e.length===0){let E=this.#t||await this.#s("solana_connect",[]);E&&this.#c(E)}let a=(n==null?void 0:n.address)&&this.#e.find(E=>E.address===n.address)||this.#e[0];if(!a)throw new Error("Not connected");let i=(n==null?void 0:n.domain)||location.host,o=(n==null?void 0:n.address)||a.address,f=(n==null?void 0:n.uri)||location.href,A=(n==null?void 0:n.version)||"1",y=(n==null?void 0:n.chainId)||"mainnet",w=(n==null?void 0:n.nonce)||Math.random().toString(36).substring(2),v=(n==null?void 0:n.issuedAt)||new Date().toISOString(),C=(n==null?void 0:n.statement)||"",b=`${i} wants you to sign in with your Solana account: -${o}`;if(C&&(b+=` +"use strict";(()=>{var V="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function L(a){let e=[0];for(let t of a){let s=V.indexOf(t);if(s===-1)throw new Error("Invalid base58 character");let n=s;for(let r=0;r>=8;for(;n>0;)e.push(n&255),n>>=8}for(let t of a){if(t!=="1")break;e.push(0)}return new Uint8Array(e.reverse())}var U=class a{#r;#e=[];#t=null;#a=new Set;version="1.0.0";name="KeepKey";icon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAIKADAAQAAAABAAAAIAAAAACshmLzAAADUklEQVRYCb1XTUgUYRie3bXEWhVLQaUsgwVLoUtEQjUJiZX0A0GX7BIZXurkOTSvdo2kvETHAsOshFgqOqhlRD9C7SGS1JTCsj1krU7PM+w7zMzOzuzMqi88+73v9z7vz3zzzTeziuIgmqbFgG5gBPguFOgq4CXLIMwCo0AXEJN4zxHkEuA6kAIMkUBMqMZk7so/UG8AUcnjOIKwFXgHZIgEwKFmOHOfYO4aySVjmAoc7O4R0EB7lYS5h9K1jBJ6A7CuAfXG7OopbKLXkh4dccNZ7jlsi0gAJlWLI5jBPWFsTK5AGxCRImswFqDGWanDBo6IsYbjUanFbmrFWIHxD3IsmfJsgB4y2aJuF4UrUC5GnuNtxJeEQqEoAb3LJV+F4ctlHwkZXDULv8fEKQCHB4+rCJ9ngKcIGUTVRubT027y8yR9bOM4mhKTTwNJZD4miaDXAG8dqzlMShw3YRCZRVAr7vU4g5F/D4ZBoJK2H+Em9CsfEdBoKn4K9jPAd3G9sMPqZEzpRPzAwRfWJpN9EfZSRkAOE5LD7wrw8dkpwRh55VMm27fqt4FiVBjGBTaxEm4Db8d+4BPtIOK3AdbYCPC1qh/haGIS9gHgDeBbgjTAIkXAfTRxkgaamMNwCHgB+BMk4Decq0hGkFQbka/WMyZ/EeyHNo6TuSwx3Nn8gHQVIYOkOhB5Gp4zcdbBHiDvZ2pRuzozru2euKuDOucg/KliTAjKKMa9ksBpxBLrbzRwVfifOnB4RR2g3QSH3Cfx5FRdc2KoGstroUeQKh47vnAwWvUKjsPcA/wWdBUkjRAgZdsznO8D5xLGC/Opxc3NiQeV9uIsgkNDaUoMFpNDLleAn0cTQNBjGaFW6fn2Wrky/dI6abPOl9eN9deoWhjLloCv3+bPy7w3/9kzfvjX120g1cuSdsJ47xm1CgS9AaxCErlbV6qJ02W1nq22lG75AtIHWQEeJpOYaAT6gBQQWC5XNCjc7dkkHFKWe6v3FcLfbzRAMlcC6IC6C+gGxgCectZnCRMuopVG1v+Nx04sYINlxLH4wI6W52UFhT+Q41b2Nl0qeLnwZPGQucNHrXN6ZDG94RQuO688XbwNFzvjlSuwH03wEW8H+Bf/dxrUOWdc+H8mKXtEpGpY3AAAAABJRU5ErkJggg==";chains=["solana:mainnet"];static ACCOUNT_FEATURES=["solana:signTransaction","solana:signAndSendTransaction","solana:signMessage"];get accounts(){return this.#e}features={"standard:connect":{version:"1.0.0",connect:async()=>{if(this.#e.length>0)return{accounts:this.#e};let e=await this.#s("solana_getAccounts",[]).catch(()=>null);if(!Array.isArray(e)||e.length===0){let t=this.#t||await this.#s("solana_connect",[]);e=t?[{address:t}]:[]}return this.#o(e),{accounts:this.#e}}},"standard:disconnect":{version:"1.0.0",disconnect:async()=>{await this.#s("solana_disconnect",[]).catch(()=>{}),this.#e=[];try{localStorage.removeItem("keepkey-solana")}catch{}this.#n()}},"standard:events":{version:"1.0.0",on:(e,t)=>(e==="change"&&this.#a.add(t),()=>{this.#a.delete(t)})},"solana:signMessage":{version:"1.0.0",signMessage:async(...e)=>{let t=[];for(let{message:s,account:n}of e){let r=await this.#s("solana_signMessage",[Array.from(s),{accountAddress:n==null?void 0:n.address}]);t.push({signedMessage:s,signature:new Uint8Array(r)})}return t}},"solana:signTransaction":{version:"1.0.0",supportedTransactionVersions:new Set(["legacy",0]),signTransaction:async(...e)=>{let t=[];for(let{transaction:s,account:n}of e){let r=await this.#s("solana_signTransaction",[Array.from(s),{accountAddress:n==null?void 0:n.address}]);t.push({signedTransaction:new Uint8Array(r)})}return t}},"solana:signAndSendTransaction":{version:"1.0.0",supportedTransactionVersions:new Set(["legacy",0]),signAndSendTransaction:async(...e)=>{let t=[];for(let{transaction:s,account:n}of e){let r=await this.#s("solana_signAndSendTransaction",[Array.from(s),{accountAddress:n==null?void 0:n.address}]);t.push({signature:L(r)})}return t}},"keepkey:signOffchainMessage":{version:"1.0.0",signOffchainMessage:async e=>{let t=typeof e.message=="string"?Array.from(new TextEncoder().encode(e.message)):Array.from(e.message);return await this.#s("solana_signOffchainMessage",[{message:t,version:e.version,messageFormat:e.messageFormat}])}},"solana:signIn":{version:"1.0.0",signIn:async(...e)=>{var s;let t=[];for(let n of e){if(this.#e.length===0){let E=this.#t||await this.#s("solana_connect",[]);E&&this.#c(E)}let r=(n==null?void 0:n.address)&&this.#e.find(E=>E.address===n.address)||this.#e[0];if(!r)throw new Error("Not connected");let o=(n==null?void 0:n.domain)||location.host,i=(n==null?void 0:n.address)||r.address,f=(n==null?void 0:n.uri)||location.href,h=(n==null?void 0:n.version)||"1",y=(n==null?void 0:n.chainId)||"mainnet",p=(n==null?void 0:n.nonce)||Math.random().toString(36).substring(2),b=(n==null?void 0:n.issuedAt)||new Date().toISOString(),M=(n==null?void 0:n.statement)||"",k=`${o} wants you to sign in with your Solana account: +${i}`;if(M&&(k+=` -${C}`),b+=` +${M}`),k+=` -URI: ${f}`,b+=` -Version: ${A}`,b+=` -Chain ID: ${y}`,b+=` -Nonce: ${w}`,b+=` -Issued At: ${v}`,n!=null&&n.expirationTime&&(b+=` -Expiration Time: ${n.expirationTime}`),n!=null&&n.notBefore&&(b+=` -Not Before: ${n.notBefore}`),n!=null&&n.requestId&&(b+=` -Request ID: ${n.requestId}`),(s=n==null?void 0:n.resources)!=null&&s.length){b+=` -Resources:`;for(let E of n.resources)b+=` -- ${E}`}let S=new TextEncoder().encode(b),R=await this.#s("solana_signMessage",[Array.from(S),{accountAddress:a.address}]);t.push({account:a,signedMessage:S,signature:new Uint8Array(R)})}return t}}};constructor(e){this.#a=e;try{let t=localStorage.getItem("keepkey-solana");if(t){let{address:s}=JSON.parse(t);s&&typeof s=="string"&&(this.#t=s)}}catch{}this.#l()}#i(e){return{address:e,publicKey:L(e),chains:["solana:mainnet"],features:[...r.ACCOUNT_FEATURES]}}#c(e){this.#e=[this.#i(e)];try{localStorage.setItem("keepkey-solana",JSON.stringify({address:e}))}catch{}this.#n()}#o(e){var t;this.#e=e.filter(s=>s==null?void 0:s.address).map(s=>this.#i(s.address));try{let s=(t=this.#e[0])==null?void 0:t.address;s&&localStorage.setItem("keepkey-solana",JSON.stringify({address:s}))}catch{}this.#n()}async#l(){try{let e=await this.#s("solana_connect",[]);if(e&&typeof e=="string"){this.#t=e;try{localStorage.setItem("keepkey-solana",JSON.stringify({address:e}))}catch{}}}catch{}}#n(){let e=this.#e,t=this.features;this.#r.forEach(s=>{try{s({accounts:e,features:t})}catch{}})}#s(e,t){return new Promise((s,n)=>{this.#a(e,t,"solana",(a,i)=>{a?n(a):s(i)})})}};function x(r){let e=({register:s})=>{s(r)};try{let s=window.navigator;s.wallets||(s.wallets=[]),Array.isArray(s.wallets)?s.wallets.push(e):typeof s.wallets.register=="function"&&s.wallets.register(r)}catch{}let t=()=>{try{window.dispatchEvent(new CustomEvent("wallet-standard:register-wallet",{detail:e}))}catch{}};t(),setTimeout(t,100),setTimeout(t,1e3),window.addEventListener("wallet-standard:app-ready",s=>{let n=s.detail;try{n&&typeof n.register=="function"?e(n):typeof n=="function"&&n(e)}catch{}})}var Y="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function Z(r){let e=[0];for(let t of r){let s=Y.indexOf(t);if(s===-1)throw new Error("Invalid base58 character");let n=s;for(let a=0;a>=8;for(;n>0;)e.push(n&255),n>>=8}for(let t of r){if(t!=="1")break;e.push(0)}return new Uint8Array(e.reverse())}function $(r){let e=Z(r);return{toString:()=>r,toBase58:()=>r,toBytes:()=>e,toBuffer:()=>e,equals:t=>{var s,n;try{return((s=t==null?void 0:t.toBase58)==null?void 0:s.call(t))===r||((n=t==null?void 0:t.toString)==null?void 0:n.call(t))===r}catch{return!1}}}}function j(r){return r!=null&&typeof r=="object"&&"version"in r&&r.message!=null}function F(r){if(!r||typeof r.serialize!="function")throw new Error("Unsupported transaction: missing serialize()");return j(r)?new Uint8Array(r.serialize()):new Uint8Array(r.serialize({requireAllSignatures:!1,verifySignatures:!1}))}function ee(r){let e=r[0];if(!e)throw new Error("Signed transaction has no signatures");if(e&128)throw new Error("Unexpected multi-byte signature count");return r.slice(1,65)}function te(r){var t,s;if(j(r)){let n=(t=r.message)==null?void 0:t.staticAccountKeys;if(n&&n.length)return n[0];throw new Error("Versioned transaction missing account keys")}if(r.feePayer)return r.feePayer;let e=(s=r.signatures)==null?void 0:s[0];if(e!=null&&e.publicKey)return e.publicKey;throw new Error("Legacy transaction missing fee payer")}var O=class{#a;#e=new Map;#t=null;#r=null;isPhantom=!0;isKeepKey=!0;constructor(e){this.#a=e;try{let t=localStorage.getItem("keepkey-solana");if(t){let{address:s}=JSON.parse(t);s&&typeof s=="string"&&(this.#r=s)}}catch{}this.#l()}get publicKey(){return this.#t}get isConnected(){return this.#t!==null}async connect(e){if(this.#t)return{publicKey:this.#t};let t=this.#r||await this.#n("solana_connect",[]);if(!t)throw new Error("Failed to connect to KeepKey");return this.#c(t),{publicKey:this.#t}}async disconnect(){await this.#n("solana_disconnect",[]).catch(()=>{}),this.#t=null;try{localStorage.removeItem("keepkey-solana")}catch{}this.#i("disconnect")}async signMessage(e,t){await this.#o();let s=await this.#n("solana_signMessage",[Array.from(e)]);return{signature:new Uint8Array(s),publicKey:this.#t}}async signTransaction(e){await this.#o();let t=F(e),s=await this.#n("solana_signTransaction",[Array.from(t)]),n=new Uint8Array(s),a=ee(n);return e.addSignature(te(e),a),e}async signAllTransactions(e){let t=[];for(let s of e)t.push(await this.signTransaction(s));return t}async signAndSendTransaction(e,t){await this.#o();let s=F(e);return{signature:await this.#n("solana_signAndSendTransaction",[Array.from(s)]),publicKey:this.#t}}async request({method:e,params:t}){var n,a,i,o,f,A;let s=Array.isArray(t)?t:t!=null?[t]:[];switch(e){case"connect":return this.connect(s[0]);case"disconnect":return this.disconnect();case"signTransaction":return this.signTransaction(((n=s[0])==null?void 0:n.transaction)??s[0]);case"signAllTransactions":return this.signAllTransactions(((a=s[0])==null?void 0:a.transactions)??s[0]);case"signAndSendTransaction":return this.signAndSendTransaction(((i=s[0])==null?void 0:i.transaction)??s[0],((o=s[0])==null?void 0:o.options)??s[1]);case"signMessage":return this.signMessage(((f=s[0])==null?void 0:f.message)??s[0],(A=s[0])==null?void 0:A.display);default:throw new Error(`KeepKey (Solana): unsupported method "${e}"`)}}on(e,t){return this.#e.has(e)||this.#e.set(e,new Set),this.#e.get(e).add(t),this}off(e,t){var s;return(s=this.#e.get(e))==null||s.delete(t),this}removeListener(e,t){return this.off(e,t)}removeAllListeners(e){return e?this.#e.delete(e):this.#e.clear(),this}#i(e,...t){var s;(s=this.#e.get(e))==null||s.forEach(n=>{try{n(...t)}catch{}})}#c(e){this.#t=$(e),this.#r=e;try{localStorage.setItem("keepkey-solana",JSON.stringify({address:e}))}catch{}this.#i("connect",this.#t)}async#o(){this.#t||await this.connect()}async#l(){try{let e=await this.#n("solana_connect",[]);if(e&&typeof e=="string"){this.#r=e;try{localStorage.setItem("keepkey-solana",JSON.stringify({address:e}))}catch{}}}catch{}}#n(e,t){return new Promise((s,n)=>{this.#a(e,t,"solana",(a,i)=>{a?n(a):s(i)})})}};var P="https://api.trongrid.io",ne="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function se(r){let e=[0];for(let t of r){let s=ne.indexOf(t);if(s===-1)throw new Error("Invalid base58 character");let n=s;for(let a=0;a>=8;for(;n>0;)e.push(n&255),n>>=8}for(let t of r){if(t!=="1")break;e.push(0)}return new Uint8Array(e.reverse())}function re(r){let e="";for(let t of r)e+=t.toString(16).padStart(2,"0");return e}function W(r){let e=se(r);if(e.length!==25||e[0]!==65)throw new Error(`Invalid Tron address: ${r}`);return re(e.slice(0,21))}function D(r){if(typeof r!="string"||r.length!==34||!r.startsWith("T"))return!1;try{return W(r),!0}catch{return!1}}var B=class{events=new Map;on(e,t){this.events.has(e)||this.events.set(e,new Set),this.events.get(e).add(t)}off(e,t){var s;(s=this.events.get(e))==null||s.delete(t)}emit(e,...t){var s;(s=this.events.get(e))==null||s.forEach(n=>{try{n(...t)}catch{}})}};function K(r,e,t){return new Promise((s,n)=>{r(e,t,"tron",(a,i)=>{a?n(a):s(i)})})}var ae=8e3,ie=12e3,oe=r=>r>=500&&r<600;async function M(r,e){let s=r.includes("broadcasttransaction")?ie:ae,n=2,a;for(let i=1;i<=n;i++)try{let o=await fetch(`${P}${r}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),signal:AbortSignal.timeout(s)});if(!o.ok){if(oe(o.status)&&isetTimeout(A,200*i));continue}let f=await o.text().catch(()=>"");throw new Error(`TronGrid ${r} failed (${o.status}): ${f}`)}return await o.json()}catch(o){if(a=o,isetTimeout(f,200*i));continue}}throw a}var N=class{tronWeb;tronLink;address=null;hexAddress=null;emitter=new B;walletRequest;constructor(e){this.walletRequest=e,this.tronWeb=this.buildTronWeb(),this.tronLink=this.buildTronLink()}setAddress(e){!e||!D(e)||(this.address=e,this.hexAddress=W(e),this.tronWeb.ready=!0,this.tronWeb.defaultAddress={base58:e,hex:this.hexAddress,name:"KeepKey",type:1},this.tronLink.ready=!0,this.fireMessage("setAccount",{address:e,name:"KeepKey",type:1}),this.fireMessage("accountsChanged",{address:e}))}fireMessage(e,t){try{window.postMessage({message:{action:e,data:t},isTronLink:!0},window.location.origin)}catch{}this.emitter.emit(e,t)}buildTronLink(){return{isTronLink:!0,ready:!1,tronWeb:null,request:async({method:e,params:t})=>{switch(e){case"tron_requestAccounts":case"tron_accounts":{let s=await K(this.walletRequest,"tron_requestAccounts",[]);return!s||typeof s!="string"?{code:4001,message:"User denied account access"}:(this.setAddress(s),{code:200,message:"ok"})}default:return K(this.walletRequest,e,Array.isArray(t)?t:[t])}},on:(e,t)=>this.emitter.on(e,t),off:(e,t)=>this.emitter.off(e,t)}}buildTronWeb(){let e=this,t={sign:async(i,o,f,A)=>{if(typeof i=="string")throw new Error("tronWeb.trx.sign(message) not supported \u2014 use tronWeb.trx.signMessage()");if(!i||!i.raw_data_hex)throw new Error("tronWeb.trx.sign expects a built transaction with raw_data_hex");return await K(e.walletRequest,"tron_sign",[i])},signMessage:async(i,o)=>await K(e.walletRequest,"tron_signMessage",[i]),signMessageV2:async(i,o)=>await K(e.walletRequest,"signMessageV2",[i]),sendRawTransaction:async i=>M("/wallet/broadcasttransaction",i),broadcast:async i=>t.sendRawTransaction(i),getBalance:async i=>{let o=i||e.address;if(!o)throw new Error("No address \u2014 call tron_requestAccounts first");let f=await M("/wallet/getaccount",{address:o,visible:!0});return typeof(f==null?void 0:f.balance)=="number"?f.balance:0},getAccount:async i=>{let o=i||e.address;if(!o)throw new Error("No address \u2014 call tron_requestAccounts first");return M("/wallet/getaccount",{address:o,visible:!0})},getUnconfirmedAccount:async i=>{let o=i||e.address;if(!o)throw new Error("No address \u2014 call tron_requestAccounts first");return M("/wallet/getaccount",{address:o,visible:!0})},getTransaction:async i=>M("/wallet/gettransactionbyid",{value:i})},a={isTronLink:!0,ready:!1,defaultAddress:{base58:!1,hex:!1,name:!1,type:-1},fullNode:{host:P},solidityNode:{host:P},eventServer:{host:P},trx:t,transactionBuilder:{sendTrx:async(i,o,f)=>{let A=f||e.address;if(!A)throw new Error("No address \u2014 call tron_requestAccounts first");return M("/wallet/createtransaction",{owner_address:A,to_address:i,amount:o,visible:!0})},triggerSmartContract:async(i,o,f={},A=[],y)=>{let w=y||e.address;if(!w)throw new Error("No address \u2014 call tron_requestAccounts first");return M("/wallet/triggersmartcontract",{contract_address:i,function_selector:o,parameter:ce(A),fee_limit:f.feeLimit??1e8,call_value:f.callValue??0,owner_address:w,visible:!0})}},utils:{isAddress:i=>D(i),fromSun:i=>String(Number(i)/1e6),toSun:i=>String(Math.round(Number(i)*1e6)),toHex:i=>W(i)},on:(i,o)=>this.emitter.on(i,o),off:(i,o)=>this.emitter.off(i,o),setAddress:i=>{},isConnected:()=>this.address!==null};return queueMicrotask(()=>{this.tronLink&&(this.tronLink.tronWeb=a)}),a}};function ce(r){if(!Array.isArray(r)||r.length===0)return"";let e="";for(let t of r)if(t.type==="address"){let s=String(t.value),n=s.startsWith("T")?W(s).slice(2):s.replace(/^0x/,"").replace(/^41/,"");e+=n.padStart(64,"0")}else if(t.type==="uint256"||t.type==="uint"){let s=BigInt(t.value);e+=s.toString(16).padStart(64,"0")}else{let s=String(t.value).replace(/^0x/,"");e+=s.padStart(64,"0")}return e}function G(r){let e=1;function t(o,f,A,y,w){if(typeof o!="function")return;let v=y?(y==null?void 0:y.message)||String(y):null;o({success:!y,error:y?(y==null?void 0:y.code)===4001?"user_cancel":v:null,message:v,request_id:f,result:y?null:w??null,data:A})}function s(o,f,A){let y=e++;r(o,[f],"hive",(w,v)=>{t(A,y,f,w,v)})}function n(o,f,A){t(A,e++,f,{message:`KeepKey does not support Keychain request "${o}" yet`})}let a={current_id:1,requestHandshake:function(o){s("hive_handshake",{},()=>{typeof o=="function"&&o()})},requestTransfer:function(o,f,A,y,w,v,C=!1,b){s("hive_transfer",{type:"transfer",username:o,to:f,amount:A,memo:y,enforce:C,currency:w,rpc:b},v)}},i=["requestEncodeMessage","requestEncodeWithKeys","requestVerifyKey","requestSignBuffer","requestAddAccountAuthority","requestRemoveAccountAuthority","requestAddKeyAuthority","requestRemoveKeyAuthority","requestBroadcast","requestSignTx","requestSignedCall","requestPost","requestVote","requestCustomJson","requestSendToken","requestDelegation","requestWitnessVote","requestProxy","requestPowerUp","requestPowerDown","requestCreateClaimedAccount","requestCreateProposal","requestRemoveProposal","requestUpdateProposalVote","requestAddAccount","requestConversion","requestRecurrentTransfer","requestSavingsOperation","requestSwap"];for(let o of i)a[o]=(...f)=>{let A=f.find(y=>typeof y=="function");n(o.replace(/^request/,""),{type:o},A)};return a}(function(){let r="2.1.0",a=window,i={isInjected:!1,version:r,injectedAt:Date.now(),retryCount:0};if(a.keepkeyInjectionState&&a.keepkeyInjectionState.version>=r)return;a.keepkeyInjectionState=i;let o=(()=>{var l;let g={enableMetaMaskMasking:!1,enableXfiMasking:!1,enableKeplrMasking:!1,enablePhantomMasking:!1};try{let d=document.currentScript,c=document.getElementById("keepkey-injected-script"),u=(l=d==null?void 0:d.dataset)!=null&&l.masking?d:c,m=u==null?void 0:u.dataset.masking;if(!m)return g;let h=JSON.parse(m);return{enableMetaMaskMasking:h.enableMetaMaskMasking===!0,enableXfiMasking:h.enableXfiMasking===!0,enableKeplrMasking:h.enableKeplrMasking===!0,enablePhantomMasking:h.enablePhantomMasking===!0}}catch{return g}})();console.log(`[KeepKey] masking: metamask=${o.enableMetaMaskMasking?"on":"off"} xfi=${o.enableXfiMasking?"on":"off"} keplr=${o.enableKeplrMasking?"on":"off"} phantom=${o.enablePhantomMasking?"on":"off"}`);let f={siteUrl:window.location.href,scriptSource:"KeepKey Extension",version:r,injectedTime:new Date().toISOString(),origin:window.location.origin,protocol:window.location.protocol},A=0,y=new Map,w=[],v=!1;setInterval(()=>{let g=Date.now();y.forEach((l,d)=>{g-l.timestamp>3e5&&(l.callback(new Error("Request timeout")),y.delete(d))})},5e3);let b=g=>{w.length>=100&&w.shift(),w.push(g)},S=()=>{if(v)for(;w.length>0;){let g=w.shift();g&&window.postMessage(g,window.location.origin)}},R=(g=0)=>new Promise(l=>{let d=++A,c=setTimeout(()=>{g<3?setTimeout(()=>{R(g+1).then(l)},100*Math.pow(2,g)):(i.lastError="Failed to verify injection",l(!1))},1e3),u=m=>{var h,k,T;m.source===window&&((h=m.data)==null?void 0:h.source)==="keepkey-content"&&((k=m.data)==null?void 0:k.type)==="INJECTION_CONFIRMED"&&((T=m.data)==null?void 0:T.requestId)===d&&(clearTimeout(c),window.removeEventListener("message",u),v=!0,i.isInjected=!0,S(),l(!0))};window.addEventListener("message",u),window.postMessage({source:"keepkey-injected",type:"INJECTION_VERIFY",requestId:d,version:r,timestamp:Date.now()},window.location.origin)});function E(g,l=[],d,c){if(!g||typeof g!="string"){c(new Error("Invalid method"));return}Array.isArray(l)||(l=[l]);try{let u=++A,m={id:u,method:g,params:l,chain:d,siteUrl:f.siteUrl,scriptSource:f.scriptSource,version:f.version,requestTime:new Date().toISOString(),referrer:document.referrer,href:window.location.href,userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language};y.set(u,{callback:c,timestamp:Date.now(),method:g});let h={source:"keepkey-injected",type:"WALLET_REQUEST",requestId:u,requestInfo:m,timestamp:Date.now()};v?window.postMessage(h,window.location.origin):b(h)}catch(u){c(u)}}window.addEventListener("message",g=>{if(g.source!==window)return;let l=g.data;if(!(!l||typeof l!="object")){if(l.source==="keepkey-content"&&l.type==="INJECTION_CONFIRMED"){v=!0,S();return}if(l.source==="keepkey-content"&&l.type==="WALLET_RESPONSE"&&l.requestId){let d=y.get(l.requestId);d&&(l.error?d.callback(l.error):d.callback(null,l.result),y.delete(l.requestId))}}});class H{events=new Map;on(l,d){this.events.has(l)||this.events.set(l,new Set),this.events.get(l).add(d)}off(l,d){var c;(c=this.events.get(l))==null||c.delete(d)}removeListener(l,d){this.off(l,d)}removeAllListeners(l){l?this.events.delete(l):this.events.clear()}emit(l,...d){var c;(c=this.events.get(l))==null||c.forEach(u=>{try{u(...d)}catch{}})}once(l,d){let c=(...u)=>{d(...u),this.off(l,c)};this.on(l,c)}}function p(g){let l=new H,d={network:"mainnet",isKeepKey:!0,isMetaMask:o.enableMetaMaskMasking,isConnected:()=>v,request:({method:c,params:u=[]})=>new Promise((m,h)=>{E(c,u,g,(k,T)=>{if(k)console.log(`[HANDOFF] dApp \u2190 KeepKey (${g}/${c}) REJECT +URI: ${f}`,k+=` +Version: ${h}`,k+=` +Chain ID: ${y}`,k+=` +Nonce: ${p}`,k+=` +Issued At: ${b}`,n!=null&&n.expirationTime&&(k+=` +Expiration Time: ${n.expirationTime}`),n!=null&&n.notBefore&&(k+=` +Not Before: ${n.notBefore}`),n!=null&&n.requestId&&(k+=` +Request ID: ${n.requestId}`),(s=n==null?void 0:n.resources)!=null&&s.length){k+=` +Resources:`;for(let E of n.resources)k+=` +- ${E}`}let C=new TextEncoder().encode(k),R=await this.#s("solana_signMessage",[Array.from(C),{accountAddress:r.address}]);t.push({account:r,signedMessage:C,signature:new Uint8Array(R)})}return t}}};constructor(e){this.#r=e;try{let t=localStorage.getItem("keepkey-solana");if(t){let{address:s}=JSON.parse(t);s&&typeof s=="string"&&(this.#t=s)}}catch{}this.#l()}#i(e){return{address:e,publicKey:L(e),chains:["solana:mainnet"],features:[...a.ACCOUNT_FEATURES]}}#c(e){this.#e=[this.#i(e)];try{localStorage.setItem("keepkey-solana",JSON.stringify({address:e}))}catch{}this.#n()}#o(e){var t;this.#e=e.filter(s=>s==null?void 0:s.address).map(s=>this.#i(s.address));try{let s=(t=this.#e[0])==null?void 0:t.address;s&&localStorage.setItem("keepkey-solana",JSON.stringify({address:s}))}catch{}this.#n()}async#l(){try{let e=await this.#s("solana_connect",[]);if(e&&typeof e=="string"){this.#t=e;try{localStorage.setItem("keepkey-solana",JSON.stringify({address:e}))}catch{}}}catch{}}#n(){let e=this.#e,t=this.features;this.#a.forEach(s=>{try{s({accounts:e,features:t})}catch{}})}#s(e,t){return new Promise((s,n)=>{this.#r(e,t,"solana",(r,o)=>{r?n(r):s(o)})})}};function x(a){let e=({register:s})=>{s(a)};try{let s=window.navigator;s.wallets||(s.wallets=[]),Array.isArray(s.wallets)?s.wallets.push(e):typeof s.wallets.register=="function"&&s.wallets.register(a)}catch{}let t=()=>{try{window.dispatchEvent(new CustomEvent("wallet-standard:register-wallet",{detail:e}))}catch{}};t(),setTimeout(t,100),setTimeout(t,1e3),window.addEventListener("wallet-standard:app-ready",s=>{let n=s.detail;try{n&&typeof n.register=="function"?e(n):typeof n=="function"&&n(e)}catch{}})}var Y="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function Z(a){let e=[0];for(let t of a){let s=Y.indexOf(t);if(s===-1)throw new Error("Invalid base58 character");let n=s;for(let r=0;r>=8;for(;n>0;)e.push(n&255),n>>=8}for(let t of a){if(t!=="1")break;e.push(0)}return new Uint8Array(e.reverse())}function $(a){let e=Z(a);return{toString:()=>a,toBase58:()=>a,toBytes:()=>e,toBuffer:()=>e,equals:t=>{var s,n;try{return((s=t==null?void 0:t.toBase58)==null?void 0:s.call(t))===a||((n=t==null?void 0:t.toString)==null?void 0:n.call(t))===a}catch{return!1}}}}function j(a){return a!=null&&typeof a=="object"&&"version"in a&&a.message!=null}function F(a){if(!a||typeof a.serialize!="function")throw new Error("Unsupported transaction: missing serialize()");return j(a)?new Uint8Array(a.serialize()):new Uint8Array(a.serialize({requireAllSignatures:!1,verifySignatures:!1}))}function ee(a){let e=a[0];if(!e)throw new Error("Signed transaction has no signatures");if(e&128)throw new Error("Unexpected multi-byte signature count");return a.slice(1,65)}function te(a){var t,s;if(j(a)){let n=(t=a.message)==null?void 0:t.staticAccountKeys;if(n&&n.length)return n[0];throw new Error("Versioned transaction missing account keys")}if(a.feePayer)return a.feePayer;let e=(s=a.signatures)==null?void 0:s[0];if(e!=null&&e.publicKey)return e.publicKey;throw new Error("Legacy transaction missing fee payer")}var O=class{#r;#e=new Map;#t=null;#a=null;isPhantom=!0;isKeepKey=!0;constructor(e){this.#r=e;try{let t=localStorage.getItem("keepkey-solana");if(t){let{address:s}=JSON.parse(t);s&&typeof s=="string"&&(this.#a=s)}}catch{}this.#l()}get publicKey(){return this.#t}get isConnected(){return this.#t!==null}async connect(e){if(this.#t)return{publicKey:this.#t};let t=this.#a||await this.#n("solana_connect",[]);if(!t)throw new Error("Failed to connect to KeepKey");return this.#c(t),{publicKey:this.#t}}async disconnect(){await this.#n("solana_disconnect",[]).catch(()=>{}),this.#t=null;try{localStorage.removeItem("keepkey-solana")}catch{}this.#i("disconnect")}async signMessage(e,t){await this.#o();let s=await this.#n("solana_signMessage",[Array.from(e)]);return{signature:new Uint8Array(s),publicKey:this.#t}}async signTransaction(e){await this.#o();let t=F(e),s=await this.#n("solana_signTransaction",[Array.from(t)]),n=new Uint8Array(s),r=ee(n);return e.addSignature(te(e),r),e}async signAllTransactions(e){let t=[];for(let s of e)t.push(await this.signTransaction(s));return t}async signAndSendTransaction(e,t){await this.#o();let s=F(e);return{signature:await this.#n("solana_signAndSendTransaction",[Array.from(s)]),publicKey:this.#t}}async request({method:e,params:t}){var n,r,o,i,f,h;let s=Array.isArray(t)?t:t!=null?[t]:[];switch(e){case"connect":return this.connect(s[0]);case"disconnect":return this.disconnect();case"signTransaction":return this.signTransaction(((n=s[0])==null?void 0:n.transaction)??s[0]);case"signAllTransactions":return this.signAllTransactions(((r=s[0])==null?void 0:r.transactions)??s[0]);case"signAndSendTransaction":return this.signAndSendTransaction(((o=s[0])==null?void 0:o.transaction)??s[0],((i=s[0])==null?void 0:i.options)??s[1]);case"signMessage":return this.signMessage(((f=s[0])==null?void 0:f.message)??s[0],(h=s[0])==null?void 0:h.display);default:throw new Error(`KeepKey (Solana): unsupported method "${e}"`)}}on(e,t){return this.#e.has(e)||this.#e.set(e,new Set),this.#e.get(e).add(t),this}off(e,t){var s;return(s=this.#e.get(e))==null||s.delete(t),this}removeListener(e,t){return this.off(e,t)}removeAllListeners(e){return e?this.#e.delete(e):this.#e.clear(),this}#i(e,...t){var s;(s=this.#e.get(e))==null||s.forEach(n=>{try{n(...t)}catch{}})}#c(e){this.#t=$(e),this.#a=e;try{localStorage.setItem("keepkey-solana",JSON.stringify({address:e}))}catch{}this.#i("connect",this.#t)}async#o(){this.#t||await this.connect()}async#l(){try{let e=await this.#n("solana_connect",[]);if(e&&typeof e=="string"){this.#a=e;try{localStorage.setItem("keepkey-solana",JSON.stringify({address:e}))}catch{}}}catch{}}#n(e,t){return new Promise((s,n)=>{this.#r(e,t,"solana",(r,o)=>{r?n(r):s(o)})})}};var P="https://api.trongrid.io",ne="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function se(a){let e=[0];for(let t of a){let s=ne.indexOf(t);if(s===-1)throw new Error("Invalid base58 character");let n=s;for(let r=0;r>=8;for(;n>0;)e.push(n&255),n>>=8}for(let t of a){if(t!=="1")break;e.push(0)}return new Uint8Array(e.reverse())}function ae(a){let e="";for(let t of a)e+=t.toString(16).padStart(2,"0");return e}function W(a){let e=se(a);if(e.length!==25||e[0]!==65)throw new Error(`Invalid Tron address: ${a}`);return ae(e.slice(0,21))}function D(a){if(typeof a!="string"||a.length!==34||!a.startsWith("T"))return!1;try{return W(a),!0}catch{return!1}}var N=class{events=new Map;on(e,t){this.events.has(e)||this.events.set(e,new Set),this.events.get(e).add(t)}off(e,t){var s;(s=this.events.get(e))==null||s.delete(t)}emit(e,...t){var s;(s=this.events.get(e))==null||s.forEach(n=>{try{n(...t)}catch{}})}};function K(a,e,t){return new Promise((s,n)=>{a(e,t,"tron",(r,o)=>{r?n(r):s(o)})})}var re=8e3,ie=12e3,oe=a=>a>=500&&a<600;async function S(a,e){let s=a.includes("broadcasttransaction")?ie:re,n=2,r;for(let o=1;o<=n;o++)try{let i=await fetch(`${P}${a}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e),signal:AbortSignal.timeout(s)});if(!i.ok){if(oe(i.status)&&osetTimeout(h,200*o));continue}let f=await i.text().catch(()=>"");throw new Error(`TronGrid ${a} failed (${i.status}): ${f}`)}return await i.json()}catch(i){if(r=i,osetTimeout(f,200*o));continue}}throw r}var B=class{tronWeb;tronLink;address=null;hexAddress=null;emitter=new N;walletRequest;constructor(e){this.walletRequest=e,this.tronWeb=this.buildTronWeb(),this.tronLink=this.buildTronLink()}setAddress(e){!e||!D(e)||(this.address=e,this.hexAddress=W(e),this.tronWeb.ready=!0,this.tronWeb.defaultAddress={base58:e,hex:this.hexAddress,name:"KeepKey",type:1},this.tronLink.ready=!0,this.fireMessage("setAccount",{address:e,name:"KeepKey",type:1}),this.fireMessage("accountsChanged",{address:e}))}fireMessage(e,t){try{window.postMessage({message:{action:e,data:t},isTronLink:!0},window.location.origin)}catch{}this.emitter.emit(e,t)}buildTronLink(){return{isTronLink:!0,ready:!1,tronWeb:null,request:async({method:e,params:t})=>{switch(e){case"tron_requestAccounts":case"tron_accounts":{let s=await K(this.walletRequest,"tron_requestAccounts",[]);return!s||typeof s!="string"?{code:4001,message:"User denied account access"}:(this.setAddress(s),{code:200,message:"ok"})}default:return K(this.walletRequest,e,Array.isArray(t)?t:[t])}},on:(e,t)=>this.emitter.on(e,t),off:(e,t)=>this.emitter.off(e,t)}}buildTronWeb(){let e=this,t={sign:async(o,i,f,h)=>{if(typeof o=="string")throw new Error("tronWeb.trx.sign(message) not supported \u2014 use tronWeb.trx.signMessage()");if(!o||!o.raw_data_hex)throw new Error("tronWeb.trx.sign expects a built transaction with raw_data_hex");return await K(e.walletRequest,"tron_sign",[o])},signMessage:async(o,i)=>await K(e.walletRequest,"tron_signMessage",[o]),signMessageV2:async(o,i)=>await K(e.walletRequest,"signMessageV2",[o]),sendRawTransaction:async o=>S("/wallet/broadcasttransaction",o),broadcast:async o=>t.sendRawTransaction(o),getBalance:async o=>{let i=o||e.address;if(!i)throw new Error("No address \u2014 call tron_requestAccounts first");let f=await S("/wallet/getaccount",{address:i,visible:!0});return typeof(f==null?void 0:f.balance)=="number"?f.balance:0},getAccount:async o=>{let i=o||e.address;if(!i)throw new Error("No address \u2014 call tron_requestAccounts first");return S("/wallet/getaccount",{address:i,visible:!0})},getUnconfirmedAccount:async o=>{let i=o||e.address;if(!i)throw new Error("No address \u2014 call tron_requestAccounts first");return S("/wallet/getaccount",{address:i,visible:!0})},getTransaction:async o=>S("/wallet/gettransactionbyid",{value:o})},r={isTronLink:!0,ready:!1,defaultAddress:{base58:!1,hex:!1,name:!1,type:-1},fullNode:{host:P},solidityNode:{host:P},eventServer:{host:P},trx:t,transactionBuilder:{sendTrx:async(o,i,f)=>{let h=f||e.address;if(!h)throw new Error("No address \u2014 call tron_requestAccounts first");return S("/wallet/createtransaction",{owner_address:h,to_address:o,amount:i,visible:!0})},triggerSmartContract:async(o,i,f={},h=[],y)=>{let p=y||e.address;if(!p)throw new Error("No address \u2014 call tron_requestAccounts first");return S("/wallet/triggersmartcontract",{contract_address:o,function_selector:i,parameter:ce(h),fee_limit:f.feeLimit??1e8,call_value:f.callValue??0,owner_address:p,visible:!0})}},utils:{isAddress:o=>D(o),fromSun:o=>String(Number(o)/1e6),toSun:o=>String(Math.round(Number(o)*1e6)),toHex:o=>W(o)},on:(o,i)=>this.emitter.on(o,i),off:(o,i)=>this.emitter.off(o,i),setAddress:o=>{},isConnected:()=>this.address!==null};return queueMicrotask(()=>{this.tronLink&&(this.tronLink.tronWeb=r)}),r}};function ce(a){if(!Array.isArray(a)||a.length===0)return"";let e="";for(let t of a)if(t.type==="address"){let s=String(t.value),n=s.startsWith("T")?W(s).slice(2):s.replace(/^0x/,"").replace(/^41/,"");e+=n.padStart(64,"0")}else if(t.type==="uint256"||t.type==="uint"){let s=BigInt(t.value);e+=s.toString(16).padStart(64,"0")}else{let s=String(t.value).replace(/^0x/,"");e+=s.padStart(64,"0")}return e}function G(a){let e=1;function t(i,f,h,y,p){if(typeof i!="function")return;let b=y?(y==null?void 0:y.message)||String(y):null,M={success:!y,error:y?(y==null?void 0:y.code)===4001?"user_cancel":b:null,message:b,request_id:f,result:y?null:p??null,data:h};if(!y&&p&&typeof p=="object"&&"result"in p){i({...M,...p});return}i(M)}function s(i,f,h){let y=e++;a(i,[f],"hive",(p,b)=>{t(h,y,f,p,b)})}function n(i,f,h){t(h,e++,f,{message:`KeepKey does not support Keychain request "${i}" yet`})}let r={current_id:1,requestHandshake:function(i){s("hive_handshake",{},()=>{typeof i=="function"&&i()})},requestTransfer:function(i,f,h,y,p,b,M=!1,k){s("hive_transfer",{type:"transfer",username:i,to:f,amount:h,memo:y,enforce:M,currency:p,rpc:k},b)},requestSignBuffer:function(i,f,h,y,p,b){s("hive_signBuffer",{type:"signBuffer",username:i,message:f,method:h,rpc:p,title:b},y)}},o=["requestEncodeMessage","requestEncodeWithKeys","requestVerifyKey","requestAddAccountAuthority","requestRemoveAccountAuthority","requestAddKeyAuthority","requestRemoveKeyAuthority","requestBroadcast","requestSignTx","requestSignedCall","requestPost","requestVote","requestCustomJson","requestSendToken","requestDelegation","requestWitnessVote","requestProxy","requestPowerUp","requestPowerDown","requestCreateClaimedAccount","requestCreateProposal","requestRemoveProposal","requestUpdateProposalVote","requestAddAccount","requestConversion","requestRecurrentTransfer","requestSavingsOperation","requestSwap"];for(let i of o)r[i]=(...f)=>{let h=f.find(y=>typeof y=="function");n(i.replace(/^request/,""),{type:i},h)};return r}(function(){let a="2.1.0",r=window,o={isInjected:!1,version:a,injectedAt:Date.now(),retryCount:0};if(r.keepkeyInjectionState&&r.keepkeyInjectionState.version>=a)return;r.keepkeyInjectionState=o;let i=(()=>{var l;let g={enableMetaMaskMasking:!1,enableXfiMasking:!1,enableKeplrMasking:!1,enablePhantomMasking:!1};try{let d=document.currentScript,c=document.getElementById("keepkey-injected-script"),u=(l=d==null?void 0:d.dataset)!=null&&l.masking?d:c,m=u==null?void 0:u.dataset.masking;if(!m)return g;let A=JSON.parse(m);return{enableMetaMaskMasking:A.enableMetaMaskMasking===!0,enableXfiMasking:A.enableXfiMasking===!0,enableKeplrMasking:A.enableKeplrMasking===!0,enablePhantomMasking:A.enablePhantomMasking===!0}}catch{return g}})();console.log(`[KeepKey] masking: metamask=${i.enableMetaMaskMasking?"on":"off"} xfi=${i.enableXfiMasking?"on":"off"} keplr=${i.enableKeplrMasking?"on":"off"} phantom=${i.enablePhantomMasking?"on":"off"}`);let f={siteUrl:window.location.href,scriptSource:"KeepKey Extension",version:a,injectedTime:new Date().toISOString(),origin:window.location.origin,protocol:window.location.protocol},h=0,y=new Map,p=[],b=!1;setInterval(()=>{let g=Date.now();y.forEach((l,d)=>{g-l.timestamp>3e5&&(l.callback(new Error("Request timeout")),y.delete(d))})},5e3);let k=g=>{p.length>=100&&p.shift(),p.push(g)},C=()=>{if(b)for(;p.length>0;){let g=p.shift();g&&window.postMessage(g,window.location.origin)}},R=(g=0)=>new Promise(l=>{let d=++h,c=setTimeout(()=>{g<3?setTimeout(()=>{R(g+1).then(l)},100*Math.pow(2,g)):(o.lastError="Failed to verify injection",l(!1))},1e3),u=m=>{var A,v,T;m.source===window&&((A=m.data)==null?void 0:A.source)==="keepkey-content"&&((v=m.data)==null?void 0:v.type)==="INJECTION_CONFIRMED"&&((T=m.data)==null?void 0:T.requestId)===d&&(clearTimeout(c),window.removeEventListener("message",u),b=!0,o.isInjected=!0,C(),l(!0))};window.addEventListener("message",u),window.postMessage({source:"keepkey-injected",type:"INJECTION_VERIFY",requestId:d,version:a,timestamp:Date.now()},window.location.origin)});function E(g,l=[],d,c){if(!g||typeof g!="string"){c(new Error("Invalid method"));return}Array.isArray(l)||(l=[l]);try{let u=++h,m={id:u,method:g,params:l,chain:d,siteUrl:f.siteUrl,scriptSource:f.scriptSource,version:f.version,requestTime:new Date().toISOString(),referrer:document.referrer,href:window.location.href,userAgent:navigator.userAgent,platform:navigator.platform,language:navigator.language};y.set(u,{callback:c,timestamp:Date.now(),method:g});let A={source:"keepkey-injected",type:"WALLET_REQUEST",requestId:u,requestInfo:m,timestamp:Date.now()};b?window.postMessage(A,window.location.origin):k(A)}catch(u){c(u)}}window.addEventListener("message",g=>{if(g.source!==window)return;let l=g.data;if(!(!l||typeof l!="object")){if(l.source==="keepkey-content"&&l.type==="INJECTION_CONFIRMED"){b=!0,C();return}if(l.source==="keepkey-content"&&l.type==="WALLET_RESPONSE"&&l.requestId){let d=y.get(l.requestId);d&&(l.error?d.callback(l.error):d.callback(null,l.result),y.delete(l.requestId))}}});class H{events=new Map;on(l,d){this.events.has(l)||this.events.set(l,new Set),this.events.get(l).add(d)}off(l,d){var c;(c=this.events.get(l))==null||c.delete(d)}removeListener(l,d){this.off(l,d)}removeAllListeners(l){l?this.events.delete(l):this.events.clear()}emit(l,...d){var c;(c=this.events.get(l))==null||c.forEach(u=>{try{u(...d)}catch{}})}once(l,d){let c=(...u)=>{d(...u),this.off(l,c)};this.on(l,c)}}function w(g){let l=new H,d={network:"mainnet",isKeepKey:!0,isMetaMask:i.enableMetaMaskMasking,isConnected:()=>b,request:({method:c,params:u=[]})=>new Promise((m,A)=>{E(c,u,g,(v,T)=>{if(v)console.log(`[HANDOFF] dApp \u2190 KeepKey (${g}/${c}) REJECT params=${JSON.stringify(u)} - error=`,k),h(k);else{let _=typeof T,X=_==="string"?`len=${T.length} value=${T}`:`value=${JSON.stringify(T)}`;console.log(`[HANDOFF] dApp \u2190 KeepKey (${g}/${c}) RESOLVE + error=`,v),A(v);else{let _=typeof T,X=_==="string"?`len=${T.length} value=${T}`:`value=${JSON.stringify(T)}`;console.log(`[HANDOFF] dApp \u2190 KeepKey (${g}/${c}) RESOLVE params=${JSON.stringify(u)} - type=${_} ${X}`),m(T)}})}),send:(c,u,m)=>{if(c.chain||(c.chain=g),typeof m=="function"){E(c.method,c.params||u,g,(h,k)=>{h?m(h):m(null,{id:c.id,jsonrpc:"2.0",result:k})});return}else return{id:c.id,jsonrpc:"2.0",result:null}},sendAsync:(c,u,m)=>{c.chain||(c.chain=g);let h=m||u;typeof h=="function"&&E(c.method,c.params||u,g,(k,T)=>{k?h(k):h(null,{id:c.id,jsonrpc:"2.0",result:T})})},on:(c,u)=>(l.on(c,u),d),off:(c,u)=>(l.off(c,u),d),removeListener:(c,u)=>(l.removeListener(c,u),d),removeAllListeners:c=>(l.removeAllListeners(c),d),emit:(c,...u)=>(l.emit(c,...u),d),once:(c,u)=>(l.once(c,u),d),enable:()=>d.request({method:"eth_requestAccounts"}),_metamask:{isUnlocked:()=>Promise.resolve(!0)}};return g==="ethereum"&&(d.chainId="0x1",d.networkVersion="1",d.selectedAddress=null,d._handleAccountsChanged=c=>{d.selectedAddress=c[0]||null,l.emit("accountsChanged",c)},d._handleChainChanged=c=>{d.chainId=c,l.emit("chainChanged",c)},d._handleConnect=c=>{l.emit("connect",c)},d._handleDisconnect=c=>{d.selectedAddress=null,l.emit("disconnect",c)}),d}let z="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAIKADAAQAAAABAAAAIAAAAACshmLzAAADUklEQVRYCb1XTUgUYRie3bXEWhVLQaUsgwVLoUtEQjUJiZX0A0GX7BIZXurkOTSvdo2kvETHAsOshFgqOqhlRD9C7SGS1JTCsj1krU7PM+w7zMzOzuzMqi88+73v9z7vz3zzzTeziuIgmqbFgG5gBPguFOgq4CXLIMwCo0AXEJN4zxHkEuA6kAIMkUBMqMZk7so/UG8AUcnjOIKwFXgHZIgEwKFmOHOfYO4aySVjmAoc7O4R0EB7lYS5h9K1jBJ6A7CuAfXG7OopbKLXkh4dccNZ7jlsi0gAJlWLI5jBPWFsTK5AGxCRImswFqDGWanDBo6IsYbjUanFbmrFWIHxD3IsmfJsgB4y2aJuF4UrUC5GnuNtxJeEQqEoAb3LJV+F4ctlHwkZXDULv8fEKQCHB4+rCJ9ngKcIGUTVRubT027y8yR9bOM4mhKTTwNJZD4miaDXAG8dqzlMShw3YRCZRVAr7vU4g5F/D4ZBoJK2H+Em9CsfEdBoKn4K9jPAd3G9sMPqZEzpRPzAwRfWJpN9EfZSRkAOE5LD7wrw8dkpwRh55VMm27fqt4FiVBjGBTaxEm4Db8d+4BPtIOK3AdbYCPC1qh/haGIS9gHgDeBbgjTAIkXAfTRxkgaamMNwCHgB+BMk4Decq0hGkFQbka/WMyZ/EeyHNo6TuSwx3Nn8gHQVIYOkOhB5Gp4zcdbBHiDvZ2pRuzozru2euKuDOucg/KliTAjKKMa9ksBpxBLrbzRwVfifOnB4RR2g3QSH3Cfx5FRdc2KoGstroUeQKh47vnAwWvUKjsPcA/wWdBUkjRAgZdsznO8D5xLGC/Opxc3NiQeV9uIsgkNDaUoMFpNDLleAn0cTQNBjGaFW6fn2Wrky/dI6abPOl9eN9deoWhjLloCv3+bPy7w3/9kzfvjX120g1cuSdsJ47xm1CgS9AaxCErlbV6qJ22W1nq22lG75AtIHWQEeJpOYaAT6gBQQWC5XNCjc7dkkHFKWe6v3FcLfbzRAMlcC6IC6C+gGxgCectZnCRMuopVG1v+Nx04sYINlxLH4wI6W52UFhT+Q41b2Nl0qeLnwZPGQucNHrXN6ZDG94RQuO688XbwNFzvjlSuwH03wEW8H+Bf/dxrUOWdc+H8mKXtEpGpY3AAAAABJRU5ErkJggg==",J="data:image/svg+xml;utf8,"+encodeURIComponent('MM');function q(g){let l={uuid:"350670db-19fa-4704-a166-e52e178b59d4",name:"KeepKey",icon:z,rdns:"com.keepkey.client"};if(window.dispatchEvent(new CustomEvent("eip6963:announceProvider",{detail:Object.freeze({info:l,provider:g})})),o.enableMetaMaskMasking){let d={uuid:"9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",name:"MetaMask",icon:J,rdns:"io.metamask"};window.dispatchEvent(new CustomEvent("eip6963:announceProvider",{detail:Object.freeze({info:d,provider:g})}))}}async function Q(){let g=p("ethereum"),l={binance:p("binance"),bitcoin:p("bitcoin"),bitcoincash:p("bitcoincash"),dogecoin:p("dogecoin"),dash:p("dash"),ethereum:g,keplr:p("keplr"),litecoin:p("litecoin"),thorchain:p("thorchain"),mayachain:p("mayachain")},d={binance:p("binance"),bitcoin:p("bitcoin"),bitcoincash:p("bitcoincash"),dogecoin:p("dogecoin"),dash:p("dash"),ethereum:g,osmosis:p("osmosis"),cosmos:p("cosmos"),litecoin:p("litecoin"),thorchain:p("thorchain"),mayachain:p("mayachain"),ripple:p("ripple")},c=(u,m,{force:h=!1}={})=>{if(!(a[u]&&!h))try{Object.defineProperty(a,u,{value:m,writable:!1,configurable:!0})}catch{i.lastError=`Failed to mount ${u}`}};o.enableMetaMaskMasking&&c("ethereum",g,{force:!0}),o.enableXfiMasking&&c("xfi",l,{force:!0}),c("keepkey",d,{force:!0}),window.addEventListener("eip6963:requestProvider",()=>{q(g)}),q(g),setTimeout(()=>{q(g)},100);try{let u=new U(E);x(u)}catch{}if(o.enablePhantomMasking)try{let u=new O(E);Object.defineProperty(a,"solana",{value:u,writable:!1,configurable:!0})}catch{}try{let u=new N(E);a.tronLink||Object.defineProperty(a,"tronLink",{value:u.tronLink,writable:!1,configurable:!0}),a.tronWeb||Object.defineProperty(a,"tronWeb",{value:u.tronWeb,writable:!1,configurable:!0})}catch{}try{a.hive_keychain||(a.hive_keychain=G(E))}catch{}window.addEventListener("message",u=>{var m,h,k;((m=u.data)==null?void 0:m.type)==="CHAIN_CHANGED"&&g.emit("chainChanged",(h=u.data.provider)==null?void 0:h.chainId),((k=u.data)==null?void 0:k.type)==="ACCOUNTS_CHANGED"&&g._handleAccountsChanged&&g._handleAccountsChanged(u.data.accounts||[])}),R().then(u=>{u||(i.lastError="Injection not verified")})}Q(),document.readyState==="loading"&&document.addEventListener("DOMContentLoaded",()=>{if(a.ethereum&&typeof a.dispatchEvent=="function"){let g=a.ethereum;q(g)}})})();})(); + type=${_} ${X}`),m(T)}})}),send:(c,u,m)=>{if(c.chain||(c.chain=g),typeof m=="function"){E(c.method,c.params||u,g,(A,v)=>{A?m(A):m(null,{id:c.id,jsonrpc:"2.0",result:v})});return}else return{id:c.id,jsonrpc:"2.0",result:null}},sendAsync:(c,u,m)=>{c.chain||(c.chain=g);let A=m||u;typeof A=="function"&&E(c.method,c.params||u,g,(v,T)=>{v?A(v):A(null,{id:c.id,jsonrpc:"2.0",result:T})})},on:(c,u)=>(l.on(c,u),d),off:(c,u)=>(l.off(c,u),d),removeListener:(c,u)=>(l.removeListener(c,u),d),removeAllListeners:c=>(l.removeAllListeners(c),d),emit:(c,...u)=>(l.emit(c,...u),d),once:(c,u)=>(l.once(c,u),d),enable:()=>d.request({method:"eth_requestAccounts"}),_metamask:{isUnlocked:()=>Promise.resolve(!0)}};return g==="ethereum"&&(d.chainId="0x1",d.networkVersion="1",d.selectedAddress=null,d._handleAccountsChanged=c=>{d.selectedAddress=c[0]||null,l.emit("accountsChanged",c)},d._handleChainChanged=c=>{d.chainId=c,l.emit("chainChanged",c)},d._handleConnect=c=>{l.emit("connect",c)},d._handleDisconnect=c=>{d.selectedAddress=null,l.emit("disconnect",c)}),d}let z="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAIKADAAQAAAABAAAAIAAAAACshmLzAAADUklEQVRYCb1XTUgUYRie3bXEWhVLQaUsgwVLoUtEQjUJiZX0A0GX7BIZXurkOTSvdo2kvETHAsOshFgqOqhlRD9C7SGS1JTCsj1krU7PM+w7zMzOzuzMqi88+73v9z7vz3zzzTeziuIgmqbFgG5gBPguFOgq4CXLIMwCo0AXEJN4zxHkEuA6kAIMkUBMqMZk7so/UG8AUcnjOIKwFXgHZIgEwKFmOHOfYO4aySVjmAoc7O4R0EB7lYS5h9K1jBJ6A7CuAfXG7OopbKLXkh4dccNZ7jlsi0gAJlWLI5jBPWFsTK5AGxCRImswFqDGWanDBo6IsYbjUanFbmrFWIHxD3IsmfJsgB4y2aJuF4UrUC5GnuNtxJeEQqEoAb3LJV+F4ctlHwkZXDULv8fEKQCHB4+rCJ9ngKcIGUTVRubT027y8yR9bOM4mhKTTwNJZD4miaDXAG8dqzlMShw3YRCZRVAr7vU4g5F/D4ZBoJK2H+Em9CsfEdBoKn4K9jPAd3G9sMPqZEzpRPzAwRfWJpN9EfZSRkAOE5LD7wrw8dkpwRh55VMm27fqt4FiVBjGBTaxEm4Db8d+4BPtIOK3AdbYCPC1qh/haGIS9gHgDeBbgjTAIkXAfTRxkgaamMNwCHgB+BMk4Decq0hGkFQbka/WMyZ/EeyHNo6TuSwx3Nn8gHQVIYOkOhB5Gp4zcdbBHiDvZ2pRuzozru2euKuDOucg/KliTAjKKMa9ksBpxBLrbzRwVfifOnB4RR2g3QSH3Cfx5FRdc2KoGstroUeQKh47vnAwWvUKjsPcA/wWdBUkjRAgZdsznO8D5xLGC/Opxc3NiQeV9uIsgkNDaUoMFpNDLleAn0cTQNBjGaFW6fn2Wrky/dI6abPOl9eN9deoWhjLloCv3+bPy7w3/9kzfvjX120g1cuSdsJ47xm1CgS9AaxCErlbV6qJ22W1nq22lG75AtIHWQEeJpOYaAT6gBQQWC5XNCjc7dkkHFKWe6v3FcLfbzRAMlcC6IC6C+gGxgCectZnCRMuopVG1v+Nx04sYINlxLH4wI6W52UFhT+Q41b2Nl0qeLnwZPGQucNHrXN6ZDG94RQuO688XbwNFzvjlSuwH03wEW8H+Bf/dxrUOWdc+H8mKXtEpGpY3AAAAABJRU5ErkJggg==",J="data:image/svg+xml;utf8,"+encodeURIComponent('MM');function q(g){let l={uuid:"350670db-19fa-4704-a166-e52e178b59d4",name:"KeepKey",icon:z,rdns:"com.keepkey.client"};if(window.dispatchEvent(new CustomEvent("eip6963:announceProvider",{detail:Object.freeze({info:l,provider:g})})),i.enableMetaMaskMasking){let d={uuid:"9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",name:"MetaMask",icon:J,rdns:"io.metamask"};window.dispatchEvent(new CustomEvent("eip6963:announceProvider",{detail:Object.freeze({info:d,provider:g})}))}}async function Q(){let g=w("ethereum"),l={binance:w("binance"),bitcoin:w("bitcoin"),bitcoincash:w("bitcoincash"),dogecoin:w("dogecoin"),dash:w("dash"),ethereum:g,keplr:w("keplr"),litecoin:w("litecoin"),thorchain:w("thorchain"),mayachain:w("mayachain")},d={binance:w("binance"),bitcoin:w("bitcoin"),bitcoincash:w("bitcoincash"),dogecoin:w("dogecoin"),dash:w("dash"),ethereum:g,osmosis:w("osmosis"),cosmos:w("cosmos"),litecoin:w("litecoin"),thorchain:w("thorchain"),mayachain:w("mayachain"),ripple:w("ripple")},c=(u,m,{force:A=!1}={})=>{if(!(r[u]&&!A))try{Object.defineProperty(r,u,{value:m,writable:!1,configurable:!0})}catch{o.lastError=`Failed to mount ${u}`}};i.enableMetaMaskMasking&&c("ethereum",g,{force:!0}),i.enableXfiMasking&&c("xfi",l,{force:!0}),c("keepkey",d,{force:!0}),window.addEventListener("eip6963:requestProvider",()=>{q(g)}),q(g),setTimeout(()=>{q(g)},100);try{let u=new U(E);x(u)}catch{}if(i.enablePhantomMasking)try{let u=new O(E);Object.defineProperty(r,"solana",{value:u,writable:!1,configurable:!0})}catch{}try{let u=new B(E);r.tronLink||Object.defineProperty(r,"tronLink",{value:u.tronLink,writable:!1,configurable:!0}),r.tronWeb||Object.defineProperty(r,"tronWeb",{value:u.tronWeb,writable:!1,configurable:!0})}catch{}try{r.hive_keychain||(r.hive_keychain=G(E))}catch{}window.addEventListener("message",u=>{var m,A,v;((m=u.data)==null?void 0:m.type)==="CHAIN_CHANGED"&&g.emit("chainChanged",(A=u.data.provider)==null?void 0:A.chainId),((v=u.data)==null?void 0:v.type)==="ACCOUNTS_CHANGED"&&g._handleAccountsChanged&&g._handleAccountsChanged(u.data.accounts||[])}),R().then(u=>{u||(o.lastError="Injection not verified")})}Q(),document.readyState==="loading"&&document.addEventListener("DOMContentLoaded",()=>{if(r.ethereum&&typeof r.dispatchEvent=="function"){let g=r.ethereum;q(g)}})})();})(); diff --git a/chrome-extension/src/background/chains/hiveHandler.ts b/chrome-extension/src/background/chains/hiveHandler.ts index 8b4b1fe..b519075 100644 --- a/chrome-extension/src/background/chains/hiveHandler.ts +++ b/chrome-extension/src/background/chains/hiveHandler.ts @@ -281,6 +281,91 @@ async function hiveTransfer( }; } +/** + * Keychain requestSignBuffer — dApp login. Firmware signs SHA256(message) + * with the requested role's SLIP-48 key and we return the signature hex as + * `result` with the STM pubkey beside it, exactly like Hive Keychain. + */ +async function hiveSignBuffer( + params: any[], + requestInfo: any, + requireApproval: (networkId: string, requestInfo: any, chain: any, method: string, params: any) => Promise, +) { + const { username, message, method: keyRole, title } = params[0] || {}; + if (!message || typeof message !== 'string') { + throw createProviderRpcError(-32602, 'signBuffer requires a message'); + } + const role = String(keyRole || '').toLowerCase(); + // Owner is deliberately excluded (matches firmware — owner' is not a + // signBuffer role; it exists for recovery/authority changes only). + if (!['posting', 'active', 'memo'].includes(role)) { + throw createProviderRpcError(-32602, `signBuffer key must be Posting, Active or Memo (got ${keyRole})`); + } + + // Keychain contract: a message that JSON-parses to a serialized Node + // Buffer ({type:'Buffer',data:[...]}) is signed as those raw bytes; + // anything else is signed as the UTF-8 string. + let payload = message; + let isText = true; + try { + const o = JSON.parse(message, (_k, v) => + v !== null && typeof v === 'object' && v.type === 'Buffer' && Array.isArray(v.data) ? Uint8Array.from(v.data) : v, + ); + if (o instanceof Uint8Array) { + payload = Array.from(o) + .map(b => b.toString(16).padStart(2, '0')) + .join(''); + isText = false; + } + } catch { + /* not JSON — sign the raw string */ + } + + await requireHiveFirmware('Hive message signing'); + const from = await getHiveAccount(); + if (username && username !== from.name) { + throw createProviderRpcError(4100, `This KeepKey controls @${from.name}, not @${username}`); + } + + const event = buildEvent(requestInfo, 'signBuffer', params); + (event as any).unsignedTx = { + from: from.name, + messageUtf8: isText ? payload : undefined, + message: isText ? undefined : payload, + role, + title: title || '', + }; + await requestUserApproval(event, requestInfo, 'signBuffer', params, requireApproval); + + let resp: Response; + try { + resp = await fetch(`${VAULT_URL}/hive/sign-message`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${getApiKey()}` }, + body: JSON.stringify({ + address_n: hiveAddressN(role as keyof typeof HIVE_ROLES, 0), + message: payload, + is_text: isText, + }), + signal: AbortSignal.timeout(300_000), + }); + } catch (e: any) { + if (e.name === 'TimeoutError' || e.name === 'AbortError') throw createTimeoutError('Vault signing timed out'); + throw createProviderRpcError(-32603, `Vault connection failed: ${e.message}`); + } + if (!resp.ok) { + const text = await resp.text().catch(() => ''); + throw createProviderRpcError(-32603, `Vault Hive sign-message failed (${resp.status}): ${text}`); + } + const { signature, public_key } = await resp.json(); + if (!signature) throw createProviderRpcError(-32603, 'Vault returned no Hive message signature'); + + chrome.runtime.sendMessage({ action: 'signature_complete', eventId: requestInfo.id }).catch(() => {}); + + // Keychain shape: result = signature hex, publicKey beside it. + return { result: signature, publicKey: public_key }; +} + export const handleHiveRequest = async ( method: string, params: any[], @@ -302,6 +387,9 @@ export const handleHiveRequest = async ( case 'hive_transfer': { return await hiveTransfer(params, requestInfo, requireApproval); } + case 'hive_signBuffer': { + return await hiveSignBuffer(params, requestInfo, requireApproval); + } default: throw createProviderRpcError(4200, `Hive method ${method} not supported`); } diff --git a/chrome-extension/src/injected/hive-provider.ts b/chrome-extension/src/injected/hive-provider.ts index 0d44e13..4b735ff 100644 --- a/chrome-extension/src/injected/hive-provider.ts +++ b/chrome-extension/src/injected/hive-provider.ts @@ -41,14 +41,21 @@ export function createHiveKeychainShim(walletRequest: WalletRequestFn) { function respond(callback: KeychainCallback | undefined, requestId: number, data: any, error: any, result?: any) { if (typeof callback !== 'function') return; const message = error ? error?.message || String(error) : null; - callback({ + const base = { success: !error, error: error ? (error?.code === 4001 ? 'user_cancel' : message) : null, message, request_id: requestId, result: error ? null : (result ?? null), data, - }); + }; + // A handler can return { result, ...extras } to control the top-level + // response shape — Keychain puts e.g. publicKey beside result, not in it. + if (!error && result && typeof result === 'object' && 'result' in result) { + callback({ ...base, ...result }); + return; + } + callback(base); } function dispatch(method: string, data: any, callback?: KeychainCallback) { @@ -88,6 +95,19 @@ export function createHiveKeychainShim(walletRequest: WalletRequestFn) { const data = { type: 'transfer', username: account, to, amount, memo, enforce, currency, rpc }; dispatch('hive_transfer', data, callback); }, + + /** Message signing (dApp login), mirrors Keychain's signature exactly. */ + requestSignBuffer: function ( + account: string, + message: string, + key: string, + callback: KeychainCallback, + rpc?: string, + title?: string, + ) { + const data = { type: 'signBuffer', username: account, message, method: key, rpc, title }; + dispatch('hive_signBuffer', data, callback); + }, }; // The rest of Keychain's public surface (per public/hive_keychain.js). @@ -99,7 +119,6 @@ export function createHiveKeychainShim(walletRequest: WalletRequestFn) { 'requestEncodeMessage', 'requestEncodeWithKeys', 'requestVerifyKey', - 'requestSignBuffer', 'requestAddAccountAuthority', 'requestRemoveAccountAuthority', 'requestAddKeyAuthority',