Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Ethereum Signatures #12

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions examples/createOracle.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,36 @@ const SDK = require('../.')
const { wallet, api } = SDK
const { Wallet } = wallet

async function createOracle() {
const newAccount = wallet.newAccount()
console.log('newAccount', newAccount.pubKeyBech32)
async function run() {
// eth address: 0x4fe49680ab2f24a74fca3e8d80da37bd8c4895a0
// eth public key: 0x0460d242bda2fbc75bfad9d40257e3aea7728b18dd76f8854657fc5803b2790362f18e90d19f40acb88911a5723dbb3ce62eeb26b5915d77292fe1d7648097ed02
const mnemonic = 'until nature color hospital marriage crime mask pluck romance globe hedgehog bench'
const accountWallet = await Wallet.connect(mnemonic)

const swthAccount = await accountWallet.getSwthAccountFromEthKey()
console.log('swthAccount', swthAccount)

const tokenReq = {
address: newAccount.pubKeyBech32,
address: swthAccount.address,
amount: '1000',
denom: 'swth',
}
const mintResult = await api.mintTokens(tokenReq)
console.log('mintResult', mintResult)

const accountWallet = await Wallet.connect(newAccount.mnemonic)
// pubkey 022abc240c21a6f2f964d7bed04cc030fdbf280de43b441fea2cf530ae8afd7c71
const msg = {
ID: 'BTC_USD_xD',
ID: 'BTC_USD_2',
Description: 'Calculated based on an average of price feeds from Binance and Coinbase, ... more info ...',
MinTurnoutPercentage: '67',
MaxResultAge: '100',
SecurityType: 'SecuredByValidators',
ResultStrategy: 'median',
Resolution: '10',
Spec: '{}',
Originator: wallet.pubKeyBech32
Originator: swthAccount.address
}
api.createOracle(accountWallet, msg).then(console.log)
}

createOracle()
run()
56 changes: 45 additions & 11 deletions src/lib/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { ethers } from 'ethers'
import { CONFIG, NETWORK, Network } from './config'
import { Fee, StdSignDoc, Transaction } from './containers'
import { marshalJSON } from './utils/encoder'
import { getPath, PrivKeySecp256k1, PubKeySecp256k1 } from './utils/wallet'
import { getPath, PrivKeySecp256k1, PubKeySecp256k1, /* Address */ } from './utils/wallet'
import { ConcreteMsg } from './containers/Transaction'
import { HDWallet } from './utils/hdwallet'
import BALANCE_READER_ABI from './eth/abis/balanceReader.json'
Expand Down Expand Up @@ -114,6 +114,44 @@ export class Wallet {
}
}

public async getSwthAccountFromEthKey() {
const ethPrivateKey = this.hdWallet[Blockchain.Ethereum]
const etherWallet = new ethers.Wallet(ethPrivateKey)
const message = 'Login to TradeHub'
const ethSig = await etherWallet.signMessage(message)
const digest = ethers.utils.hashMessage(message)
const ethPubKey = ethers.utils.recoverPublicKey(digest, ethSig)
const swthPubKey = ethPubKey.substr(ethPubKey.length - 66)

const pubKeyBuffer = Buffer.from(swthPubKey, 'hex')
const pubKeyObj = new PubKeySecp256k1(pubKeyBuffer)

return {
ethPubKey: ethPubKey,
pubKeyHex: pubKeyBuffer.toString('hex'),
pubKey: pubKeyBuffer.toString('base64'),
address: pubKeyObj.toAddress().toBech32('swth')
}
}

public async signWithEthKey(message) {
const swthAccount = await this.getSwthAccountFromEthKey()

const ethPrivateKey = this.hdWallet[Blockchain.Ethereum]
const etherWallet = new ethers.Wallet(ethPrivateKey)

const messageBytes = ethers.utils.arrayify('0x' + message.toString('hex'))
const signature = await etherWallet.signMessage(messageBytes)

return {
pub_key: {
type: 'tendermint/PubKeySecp256k1',
value: swthAccount.pubKey,
},
signature: Buffer.from(signature.substring(2), 'hex').toString('base64')
}
}

public sign(message) {
const privKey = this.privKey
const data = privKey.sign(message)
Expand All @@ -137,8 +175,9 @@ export class Wallet {
.then(res => res.json()) // expecting a json response
}

public getAccount() {
return fetch(`${this.network.REST_URL}/get_account?account=${this.pubKeyBech32}`)
public async getAccount() {
const swthAccount = await this.getSwthAccountFromEthKey()
return fetch(`${this.network.REST_URL}/get_account?account=${swthAccount.address}`)
.then(res => res.json()) // expecting a json response
}

Expand Down Expand Up @@ -481,13 +520,8 @@ export class Wallet {
sequence = result.value.sequence
}

if (this.accountNumber === "0" || this.accountNumber === undefined || this.accountNumber === null) {
const { result } = await this.getAccount()
this.accountNumber = result.value.account_number.toString()
if (this.accountNumber === "0") {
throw new Error("Account number still 0 after refetching.")
}
}
const { result } = await this.getAccount()
this.accountNumber = result.value.account_number.toString()

const memo = options.memo || ''
const stdSignMsg = new StdSignDoc({
Expand All @@ -498,7 +532,7 @@ export class Wallet {
msgs,
sequence: sequence.toString(),
})
return this.sign(marshalJSON(stdSignMsg))
return await this.signWithEthKey(marshalJSON(stdSignMsg))
}

public async signAndBroadcast(msgs: object[], types: string[], options) {
Expand Down