add keplr support for evmos
This commit is contained in:
parent
5aac799522
commit
db4b27c98e
18
.eslintrc.js
18
.eslintrc.js
@ -6,13 +6,21 @@ module.exports = {
|
||||
extends: [
|
||||
'@vue/airbnb',
|
||||
'plugin:vue/recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:import/typescript',
|
||||
// 'prettier/@typescript-eslint',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
// "plugin:prettier/recommended",
|
||||
// "prettier/@typescript-eslint"
|
||||
],
|
||||
parser: 'vue-eslint-parser',
|
||||
parserOptions: {
|
||||
parser: '@babel/eslint-parser',
|
||||
parser: '@typescript-eslint/parser',
|
||||
ecmaVersion: 6,
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: false,
|
||||
modules: true,
|
||||
experimentalObjectRestSpread: true,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
|
||||
@ -23,10 +31,12 @@ module.exports = {
|
||||
'linebreak-style': 'off',
|
||||
// camelcase: ['error', { properties: 'never', ignoreDestructuring: true, ignoreImports: true }],
|
||||
'arrow-parens': ['error', 'as-needed'],
|
||||
'vue/multiline-html-element-content-newline': 'off',
|
||||
'vue/new-line-between-multi-line-property': 0,
|
||||
'vue/multiline-html-element-content-newline': 0,
|
||||
'vue/multi-word-component-names': 0,
|
||||
'vue/no-mutating-props': 0,
|
||||
'vue/v-slot-style': 0,
|
||||
'@typescript-eslint/no-empty-function': 1,
|
||||
camelcase: 0,
|
||||
'vuejs-accessibility/click-events-have-key-events': 'off',
|
||||
'vuejs-accessibility/mouse-events-have-key-events': 'off',
|
||||
|
@ -11,37 +11,22 @@ import {
|
||||
createIbcAminoConverters,
|
||||
createStakingAminoConverters,
|
||||
} from '@cosmjs/stargate'
|
||||
import {
|
||||
EncodeObject, TxBodyEncodeObject, makeAuthInfoBytes,
|
||||
} from '@cosmjs/proto-signing'
|
||||
import { EncodeObject } from '@cosmjs/proto-signing'
|
||||
import { LedgerSigner } from '@cosmjs/ledger-amino'
|
||||
import TransportWebUSB from '@ledgerhq/hw-transport-webusb'
|
||||
import TransportWebBLE from '@ledgerhq/hw-transport-web-ble'
|
||||
import {
|
||||
StdFee,
|
||||
} from '@cosmjs/amino'
|
||||
import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx'
|
||||
import {
|
||||
generateMessageWithMultipleTransactions,
|
||||
generateTypes,
|
||||
generateFee,
|
||||
createEIP712,
|
||||
} from '@tharsis/eip712'
|
||||
import {
|
||||
createTxRawEIP712, signatureToWeb3Extension, Chain,
|
||||
} from '@tharsis/transactions'
|
||||
import {
|
||||
createTransactionWithMultipleMessages,
|
||||
} from '@tharsis/proto'
|
||||
import {
|
||||
fromBase64, fromBech32, fromHex, toBase64,
|
||||
} from '@cosmjs/encoding'
|
||||
// import { generateEndpointBroadcast, generatePostBodyBroadcast } from '@tharsis/provider'
|
||||
import { SignMode } from 'cosmjs-types/cosmos/tx/signing/v1beta1/signing'
|
||||
import * as eth from '@tharsis/proto/dist/proto/ethermint/crypto/v1/ethsecp256k1/keys' // /ethermint/crypto/v1/ethsecp256k1/keys'
|
||||
import { PubKey } from 'cosmjs-types/cosmos/crypto/secp256k1/keys'
|
||||
import { Int53 } from '@cosmjs/math'
|
||||
import { Any } from 'cosmjs-types/google/protobuf/any'
|
||||
import { createTxRawEIP712, signatureToWeb3Extension, Chain } from '@tharsis/transactions'
|
||||
import { createTransactionWithMultipleMessages } from '@tharsis/proto'
|
||||
import { fromBech32, toBase64 } from '@cosmjs/encoding'
|
||||
import EthereumLedgerSigner from './EthereumLedgerSigner'
|
||||
import { defaultMessageAdapter } from './MessageAdapter'
|
||||
|
||||
@ -152,52 +137,6 @@ export class SigningEthermintClient {
|
||||
return Promise.resolve(rawTx)
|
||||
}
|
||||
}
|
||||
export function encodePubkey(pubkey: string): Any {
|
||||
// const value = new eth.ethermint.crypto.v1.ethsecp256k1.PubKey({ key: fromBase64(pubkey) })
|
||||
// return Any.fromPartial({
|
||||
// typeUrl: '/ethermint.crypto.v1.ethsecp256k1.PubKey',
|
||||
// value: value.serializeBinary(),
|
||||
// })
|
||||
return Any.fromPartial({
|
||||
typeUrl: '/ethermint.crypto.v1.ethsecp256k1.PubKey',
|
||||
value: PubKey.encode({
|
||||
key: fromBase64(pubkey),
|
||||
}).finish(),
|
||||
})
|
||||
}
|
||||
|
||||
function makeRawTx(sender, messages, memo, fee, signature, registry): TxRaw {
|
||||
const pubkey = encodePubkey(sender.pubkey)
|
||||
|
||||
const signedTxBody = {
|
||||
messages,
|
||||
memo,
|
||||
}
|
||||
const signedTxBodyEncodeObject: TxBodyEncodeObject = {
|
||||
typeUrl: '/cosmos.tx.v1beta1.TxBody',
|
||||
value: signedTxBody,
|
||||
}
|
||||
const signedTxBodyBytes = registry.encode(signedTxBodyEncodeObject)
|
||||
const signedGasLimit = Int53.fromString(fee.gas).toNumber()
|
||||
// const signedSequence = sender.sequence
|
||||
const signedAuthInfoBytes = makeAuthInfoBytes(
|
||||
[{ pubkey, sequence: sender.sequence }],
|
||||
fee.amount,
|
||||
signedGasLimit,
|
||||
SignMode.SIGN_MODE_LEGACY_AMINO_JSON,
|
||||
)
|
||||
const rawTx = TxRaw.fromPartial({
|
||||
bodyBytes: signedTxBodyBytes,
|
||||
authInfoBytes: signedAuthInfoBytes,
|
||||
signatures: [fromHex(signature)],
|
||||
})
|
||||
|
||||
return rawTx
|
||||
}
|
||||
|
||||
// export function createAnyMessage(messages: readonly EncodeObject[]) {
|
||||
// return messages.map(x => x.)
|
||||
// }
|
||||
|
||||
export declare type SigningClient = SigningStargateClient | SigningEthermintClient;
|
||||
|
59
src/libs/client/SigningKeplrEthermintClient.ts
Normal file
59
src/libs/client/SigningKeplrEthermintClient.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { fromBase64 } from '@cosmjs/encoding'
|
||||
import { Int53 } from '@cosmjs/math'
|
||||
import {
|
||||
EncodeObject, makeAuthInfoBytes, makeSignDoc, OfflineSigner,
|
||||
} from '@cosmjs/proto-signing'
|
||||
import {
|
||||
SignerData, SigningStargateClient, SigningStargateClientOptions, StdFee,
|
||||
} from '@cosmjs/stargate'
|
||||
import { PubKey } from 'cosmjs-types/cosmos/crypto/secp256k1/keys'
|
||||
import { TxRaw } from 'cosmjs-types/cosmos/tx/v1beta1/tx'
|
||||
import { Any } from 'cosmjs-types/google/protobuf/any'
|
||||
|
||||
export default class SigningKeplerEthermintClient {
|
||||
private signer
|
||||
|
||||
private client
|
||||
|
||||
static async offline(signer: OfflineSigner, options?: SigningStargateClientOptions): Promise<SigningKeplerEthermintClient> {
|
||||
const instance = new SigningKeplerEthermintClient()
|
||||
instance.client = await SigningStargateClient.offline(signer, options)
|
||||
instance.signer = signer
|
||||
return Promise.resolve(instance)
|
||||
}
|
||||
|
||||
async sign(signerAddress: string, messages: readonly EncodeObject[], fee: StdFee, memo: string, explicitSignerData?: SignerData): Promise<Uint8Array> {
|
||||
const account = await this.signer.getAccounts()
|
||||
const acc = account.find(x => x.address === signerAddress)
|
||||
if (!acc) {
|
||||
throw new Error('The signer address dose not exsits in Ledger!')
|
||||
}
|
||||
// Custom typeUrl for EVMOS
|
||||
const pubk = Any.fromPartial({
|
||||
typeUrl: '/ethermint.crypto.v1.ethsecp256k1.PubKey',
|
||||
value: PubKey.encode({
|
||||
key: acc.pubkey,
|
||||
}).finish(),
|
||||
})
|
||||
|
||||
const txBodyEncodeObject = {
|
||||
typeUrl: '/cosmos.tx.v1beta1.TxBody',
|
||||
value: {
|
||||
messages,
|
||||
memo,
|
||||
},
|
||||
}
|
||||
const txBodyBytes = this.client.registry.encode(txBodyEncodeObject)
|
||||
const gasLimit = Int53.fromString(fee.gas).toNumber()
|
||||
const authInfoBytes = makeAuthInfoBytes([{ pubkey: pubk, sequence: explicitSignerData.sequence }], fee.amount, gasLimit)
|
||||
const signDoc = makeSignDoc(txBodyBytes, authInfoBytes, explicitSignerData.chainId, explicitSignerData.accountNumber)
|
||||
const { signature, signed } = await this.signer.signDirect(signerAddress, signDoc)
|
||||
|
||||
// returns txBytes for broadcast
|
||||
return Promise.resolve(TxRaw.encode({
|
||||
bodyBytes: signed.bodyBytes,
|
||||
authInfoBytes: signed.authInfoBytes,
|
||||
signatures: [fromBase64(signature.signature)],
|
||||
}).finish())
|
||||
}
|
||||
}
|
@ -20,8 +20,9 @@ import { $themeColors } from '@themeConfig'
|
||||
// import { SigningStargateClient } from '@cosmjs/stargate'
|
||||
// import PingWalletClient from './data/signing'
|
||||
import { SigningStargateClient } from '@cosmjs/stargate'
|
||||
import { getSigningClient } from './client/PingWalletClient.ts'
|
||||
import { EthereumLedgerSigner } from './client/EthereumLedgerSigner.ts'
|
||||
import { getSigningClient } from './client/SigningEthermintClient.ts'
|
||||
import EthereumLedgerSigner from './client/EthereumLedgerSigner.ts'
|
||||
import SigningKeplerEthermintClient from './client/SigningKeplrEthermintClient'
|
||||
|
||||
dayjs.extend(localeData)
|
||||
dayjs.extend(duration)
|
||||
@ -231,6 +232,34 @@ function getHdPath(address) {
|
||||
return stringToPath(hdPath)
|
||||
}
|
||||
|
||||
function isEvmosBasedChain(chainId) {
|
||||
const re = /[_]{1}[\d]{4}[\\-]{1}[\d]+$/g
|
||||
return re.test(chainId)
|
||||
}
|
||||
|
||||
export async function sign(device, chainId, signerAddress, messages, fee, memo, signerData) {
|
||||
const hdpath = getHdPath(signerAddress)
|
||||
let client
|
||||
if (device.startsWith('ledger')) {
|
||||
client = await getSigningClient(device, hdpath)
|
||||
} else {
|
||||
if (!window.getOfflineSigner || !window.keplr) {
|
||||
throw new Error('Please install keplr extension')
|
||||
}
|
||||
await window.keplr.enable(chainId)
|
||||
const signer = window.getOfflineSigner(chainId)
|
||||
if (isEvmosBasedChain(chainId)) {
|
||||
client = await SigningKeplerEthermintClient.offline(signer)
|
||||
} else {
|
||||
client = await SigningStargateClient.offline(signer)
|
||||
}
|
||||
}
|
||||
const coinType = Number(hdpath[1])
|
||||
const addr = device.startsWith('ledger') && coinType !== 60 ? toSignAddress(signerAddress) : signerAddress
|
||||
return client.sign(addr, messages, fee, memo, signerData)
|
||||
}
|
||||
|
||||
// import address from ledger
|
||||
async function getLedgerAppName(coinType, device, hdpath) {
|
||||
let ledgerAppName = 'Cosmos'
|
||||
switch (coinType) {
|
||||
@ -252,27 +281,6 @@ async function getLedgerAppName(coinType, device, hdpath) {
|
||||
return new LedgerSigner(transport, { hdPaths: [hdpath], ledgerAppName })
|
||||
}
|
||||
|
||||
export async function sign(device, chainId, signerAddress, messages, fee, memo, signerData) {
|
||||
const hdpath = getHdPath(signerAddress)
|
||||
let client
|
||||
if (device.startsWith('ledger')) {
|
||||
client = await getSigningClient(device, hdpath)
|
||||
} else {
|
||||
if (!window.getOfflineSigner || !window.keplr) {
|
||||
throw new Error('Please install keplr extension')
|
||||
}
|
||||
await window.keplr.enable(chainId)
|
||||
const signer = window.getOfflineSignerOnlyAmino(chainId)
|
||||
client = await SigningStargateClient.offline(signer)
|
||||
}
|
||||
// let transport
|
||||
// let signer
|
||||
// const hdpath = getHdPath(signerAddress)
|
||||
const coinType = Number(hdpath[1])
|
||||
const addr = device.startsWith('ledger') && coinType !== 60 ? toSignAddress(signerAddress) : signerAddress
|
||||
return client.sign(addr, messages, fee, memo, signerData)
|
||||
}
|
||||
|
||||
export async function getLedgerAddress(transport = 'blu', hdPath = "m/44'/118/0'/0/0") {
|
||||
const protocol = transport === 'usb' ? await TransportWebUSB.create() : await TransportWebBLE.create()
|
||||
// extract Cointype from from HDPath
|
||||
@ -280,6 +288,7 @@ export async function getLedgerAddress(transport = 'blu', hdPath = "m/44'/118/0'
|
||||
const signer = await getLedgerAppName(coinType, protocol, stringToPath(hdPath))
|
||||
return signer.getAccounts()
|
||||
}
|
||||
/// end import address from ledger
|
||||
|
||||
export function toDuration(value) {
|
||||
return dayjs.duration(value).humanize()
|
||||
|
@ -651,7 +651,7 @@ export default {
|
||||
},
|
||||
created() {
|
||||
this.$http.getAuthAccount(this.address).then(acc => {
|
||||
this.account = acc
|
||||
this.account = acc.account
|
||||
this.initial()
|
||||
this.$http.getTxsBySender(this.address).then(res => {
|
||||
this.transactions = res
|
||||
|
Loading…
Reference in New Issue
Block a user