forked from LaconicNetwork/cosmos-explorer
add keplr support for evmos
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
+32
-23
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user