From 4a1d46cc1151fcad9b3e29992add26e592ff59a0 Mon Sep 17 00:00:00 2001 From: Vincent Tse Date: Mon, 25 Sep 2023 09:39:05 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=91=8C=20IMPROVE:=20Add=20derive=20path?= =?UTF-8?q?=20support=20to=20sign=20transaction=20/=20preview=20transactio?= =?UTF-8?q?n=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/content.js | 2 +- src/lib/actions/preview-transaction.ts | 7 +++++-- src/lib/actions/sign-transaction.ts | 16 ++++------------ src/lib/crypto.ts | 15 +++++++++++---- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/public/content.js b/public/content.js index d941108..c5e9286 100644 --- a/public/content.js +++ b/public/content.js @@ -1 +1 @@ -(function(){"use strict";var Z=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},X={exports:{}};(function(u,q){(function(D,p){u.exports=p()})(Z,function(){var D=1e3,p=6e4,H=36e5,L="millisecond",T="second",m="minute",M="hour",$="day",_="week",w="month",k="quarter",v="year",x="date",K="Invalid Date",wt=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,gt=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,mt={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(r){var e=["th","st","nd","rd"],t=r%100;return"["+r+(e[(t-20)%10]||e[t]||e[0])+"]"}},I=function(r,e,t){var i=String(r);return!i||i.length>=e?r:""+Array(e+1-i.length).join(t)+r},Mt={s:I,z:function(r){var e=-r.utcOffset(),t=Math.abs(e),i=Math.floor(t/60),n=t%60;return(e<=0?"+":"-")+I(i,2,"0")+":"+I(n,2,"0")},m:function r(e,t){if(e.date()1)return r(a[0])}else{var o=e.name;A[o]=e,n=o}return!i&&n&&(z=n),n||!i&&z},l=function(r,e){if(P(r))return r.clone();var t=typeof e=="object"?e:{};return t.date=r,t.args=arguments,new B(t)},c=Mt;c.l=W,c.i=P,c.w=function(r,e){return l(r,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var B=function(){function r(t){this.$L=W(t.locale,null,!0),this.parse(t)}var e=r.prototype;return e.parse=function(t){this.$d=function(i){var n=i.date,s=i.utc;if(n===null)return new Date(NaN);if(c.u(n))return new Date;if(n instanceof Date)return new Date(n);if(typeof n=="string"&&!/Z$/i.test(n)){var a=n.match(wt);if(a){var o=a[2]-1||0,d=(a[7]||"0").substring(0,3);return s?new Date(Date.UTC(a[1],o,a[3]||1,a[4]||0,a[5]||0,a[6]||0,d)):new Date(a[1],o,a[3]||1,a[4]||0,a[5]||0,a[6]||0,d)}}return new Date(n)}(t),this.$x=t.x||{},this.init()},e.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},e.$utils=function(){return c},e.isValid=function(){return this.$d.toString()!==K},e.isSame=function(t,i){var n=l(t);return this.startOf(i)<=n&&n<=this.endOf(i)},e.isAfter=function(t,i){return l(t){let q="";const D="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for(let p=0;p{const M=$=>{var _,w,k,v;if(!($.source!==window||((_=$.data)==null?void 0:_.channel)!=="from-metaidwallet")){if(((w=$.data)==null?void 0:w.nonce)===H){if(window.removeEventListener("message",M),(v=(k=$.data)==null?void 0:k.res)!=null&&v.error)throw new Error($.data.res.error);m&&typeof m=="function"&&m($.data)}return!0}};window.addEventListener("message",M)};return await new Promise(m=>{T(M=>{m(M.res)})})}async function G(){return await h("Connect")}async function j(){return await h("Disconnect")}async function R(){return await h("IsConnected","query")}async function tt(){return await h("GetNetwork","query")}async function nt(){return await h("SwitchNetwork")}async function et(u){return await h("GetAddress","query",u)}async function rt(u){return await h("GetPublicKey","query",u)}async function it(){return await h("GetXPublicKey","query")}async function F(u){return await h("GetBalance","query",u)}async function at(u){return await h("GetUtxos","query",u)}async function st(u){return await h("EciesEncrypt","authorize",u)}async function ut(u){return await h("EciesDecrypt","authorize",u)}async function ot(u){return await h("SignMessage","authorize",u)}async function ct(u){return await h("VerifySignature","query",u)}async function ft(u){return await h("PreviewTransaction","query",u)}async function ht(u){return await h("SignTransaction","authorize",u)}async function dt(u){return await h("SignTransactions","authorize",u)}async function lt(u){return await h("Transfer","authorize",u)}async function yt(u){return await h("Merge","authorize",u)}async function J(u){return await h("GetTokenBalance","query",u)}const $t={connect:G,isConnected:R,disconnect:j,getNetwork:tt,switchNetwork:nt,getAddress:et,getPublicKey:rt,getXPublicKey:it,getBalance:F,getUtxos:at,transfer:lt,merge:yt,previewTransaction:ft,signTransaction:ht,signTransactions:dt,signMessage:ot,verifySignature:ct,eciesEncrypt:st,eciesDecrypt:ut,token:{getBalance:J},nft:{},requestAccount:G,getAccount:G,exitAccount:j,getMvcBalance:F,getSensibleFtBalance:J};window.metaidwallet=$t})(); +(function(){"use strict";var Z=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{},X={exports:{}};(function(u,q){(function(D,S){u.exports=S()})(Z,function(){var D=1e3,S=6e4,H=36e5,L="millisecond",b="second",m="minute",v="hour",$="day",T="week",w="month",z="quarter",p="year",x="date",K="Invalid Date",wt=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,gt=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,mt={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(i){var e=["th","st","nd","rd"],t=i%100;return"["+i+(e[(t-20)%10]||e[t]||e[0])+"]"}},P=function(i,e,t){var r=String(i);return!r||r.length>=e?i:""+Array(e+1-r.length).join(t)+i},Mt={s:P,z:function(i){var e=-i.utcOffset(),t=Math.abs(e),r=Math.floor(t/60),n=t%60;return(e<=0?"+":"-")+P(r,2,"0")+":"+P(n,2,"0")},m:function i(e,t){if(e.date()1)return i(s[0])}else{var c=e.name;_[c]=e,n=c}return!r&&n&&(C=n),n||!r&&C},d=function(i,e){if(U(i))return i.clone();var t=typeof e=="object"?e:{};return t.date=i,t.args=arguments,new E(t)},o=Mt;o.l=B,o.i=U,o.w=function(i,e){return d(i,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var E=function(){function i(t){this.$L=B(t.locale,null,!0),this.parse(t)}var e=i.prototype;return e.parse=function(t){this.$d=function(r){var n=r.date,a=r.utc;if(n===null)return new Date(NaN);if(o.u(n))return new Date;if(n instanceof Date)return new Date(n);if(typeof n=="string"&&!/Z$/i.test(n)){var s=n.match(wt);if(s){var c=s[2]-1||0,f=(s[7]||"0").substring(0,3);return a?new Date(Date.UTC(s[1],c,s[3]||1,s[4]||0,s[5]||0,s[6]||0,f)):new Date(s[1],c,s[3]||1,s[4]||0,s[5]||0,s[6]||0,f)}}return new Date(n)}(t),this.$x=t.x||{},this.init()},e.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},e.$utils=function(){return o},e.isValid=function(){return this.$d.toString()!==K},e.isSame=function(t,r){var n=d(t);return this.startOf(r)<=n&&n<=this.endOf(r)},e.isAfter=function(t,r){return d(t){let q="";const D="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";for(let S=0;S{const v=$=>{var T,w,z,p;if(!($.source!==window||((T=$.data)==null?void 0:T.channel)!=="from-metaidwallet")){if(((w=$.data)==null?void 0:w.nonce)===H){if(window.removeEventListener("message",v),(p=(z=$.data)==null?void 0:z.res)!=null&&p.error)throw new Error($.data.res.error);m&&typeof m=="function"&&m($.data)}return!0}};window.addEventListener("message",v)};return await new Promise(m=>{b(v=>{m(v.res)})})}async function I(){return await h("Connect")}async function j(){return await h("Disconnect")}async function R(){return await h("IsConnected","query")}async function tt(){return await h("GetNetwork","query")}async function nt(){return await h("SwitchNetwork")}async function et(u){return await h("GetAddress","query",u)}async function rt(u){return await h("GetPublicKey","query",u)}async function it(){return await h("GetXPublicKey","query")}async function F(u){return await h("GetBalance","query",u)}async function at(u){return await h("GetUtxos","query",u)}async function st(u){return await h("EciesEncrypt","authorize",u)}async function ut(u){return await h("EciesDecrypt","authorize",u)}async function ot(u){return await h("SignMessage","authorize",u)}async function ct(u){return await h("VerifySignature","query",u)}async function ft(u){return await h("PreviewTransaction","query",u)}async function ht(u){return await h("SignTransaction","authorize",u)}async function dt(u){return await h("SignTransactions","authorize",u)}async function lt(u){return await h("Transfer","authorize",u)}async function yt(u){return await h("Merge","authorize",u)}async function J(u){return await h("GetTokenBalance","query",u)}const $t={connect:I,isConnected:R,disconnect:j,getNetwork:tt,switchNetwork:nt,getAddress:et,getPublicKey:rt,getXPublicKey:it,getBalance:F,getUtxos:at,transfer:lt,merge:yt,previewTransaction:ft,signTransaction:ht,signTransactions:dt,signMessage:ot,verifySignature:ct,eciesEncrypt:st,eciesDecrypt:ut,token:{getBalance:J},nft:{},requestAccount:I,getAccount:I,exitAccount:j,getMvcBalance:F,getSensibleFtBalance:J};window.metaidwallet=$t})(); diff --git a/src/lib/actions/preview-transaction.ts b/src/lib/actions/preview-transaction.ts index 15cac57..590ca7f 100644 --- a/src/lib/actions/preview-transaction.ts +++ b/src/lib/actions/preview-transaction.ts @@ -1,10 +1,13 @@ import { mvc } from 'meta-contract' import { getCurrentAccount, privateKey } from '../account' import { signTransaction } from '../crypto' +import { getNetwork } from '../network' export async function process(params: any, host: string) { - const wif = await getCurrentAccount().then(() => privateKey.value) - const { txid } = signTransaction(wif, params.transaction, true) + const account = await getCurrentAccount() + const network = await getNetwork() + + const { txid } = signTransaction(account!, network, params.transaction, true) return { txid } } diff --git a/src/lib/actions/sign-transaction.ts b/src/lib/actions/sign-transaction.ts index 6c92c6c..a4daa76 100644 --- a/src/lib/actions/sign-transaction.ts +++ b/src/lib/actions/sign-transaction.ts @@ -1,21 +1,13 @@ import { getAddress, getCurrentAccount, privateKey } from '../account' import connector from '../connector' import { signTransaction } from '../crypto' +import { getNetwork } from '../network' export async function process(params: any, host: string) { - const wif = await getCurrentAccount().then((account) => privateKey.value) + const account = await getCurrentAccount() + const network = await getNetwork() - // let sigList = [] - // for (let i = 0; i < params.list.length; i++) { - // sigList[i] = sign(wif, params.list[i]) - // } - if (params.returnsTransaction) { - const { txHex } = signTransaction(wif, params.transaction, params.returnsTransaction) - - return { txHex } - } - - const signature = signTransaction(wif, params.transaction, params.returnsTransaction) + const signature = signTransaction(account!, network, params.transaction) return { signature } } diff --git a/src/lib/crypto.ts b/src/lib/crypto.ts index 71a23ef..c7db6de 100644 --- a/src/lib/crypto.ts +++ b/src/lib/crypto.ts @@ -76,14 +76,21 @@ type ToSignTransaction = { path?: string } export const signTransaction = ( - wif: string, - { txHex, scriptHex, inputIndex, satoshis, sigtype }: ToSignTransaction, + account: Account, + network: 'testnet' | 'mainnet', + { txHex, scriptHex, inputIndex, satoshis, sigtype, path }: ToSignTransaction, returnsTransaction: boolean = false ) => { + const mneObj = mvc.Mnemonic.fromString(account.mnemonic) + const hdpk = mneObj.toHDPrivateKey('', network) + const accountPath = account.path + // find out priv / pub according to path + const subPath = path || '0/0' + const privateKey = hdpk.deriveChild(`m/44'/${accountPath}'/0'/${subPath}`).privateKey + const publicKey = privateKey.toPublicKey() + if (!sigtype) sigtype = mvc.crypto.Signature.SIGHASH_ALL | mvc.crypto.Signature.SIGHASH_FORKID - const privateKey = mvc.PrivateKey.fromWIF(wif) - const publicKey = privateKey.toPublicKey() const tx = new mvc.Transaction(txHex) let sighash = mvc.Transaction.Sighash.sighash(