From 37bef066285d6cf0414db25cc0ce0111c8d9d0cd Mon Sep 17 00:00:00 2001 From: Jesse Clark Date: Mon, 6 Dec 2021 00:25:17 +0200 Subject: [PATCH] Convert values coming in from WalletConnect (#70) * Convert incoming WC values from hex or strings to numbers needed for RIF Wallet. * use correct variable. * Requested changes. * Add sample values so it can send. * Rewrite tests to always expect signer and walletAdapters - Spyon the sendTransaction method to get the parameters that are being sent to the provider - Change default values to undefined not zero. --- .../WalletConnectAdapter.test.ts | 84 +++++++++++++++---- .../walletAdapters/WalletConnectAdapter.ts | 17 ++-- 2 files changed, 80 insertions(+), 21 deletions(-) diff --git a/src/lib/walletAdapters/WalletConnectAdapter.test.ts b/src/lib/walletAdapters/WalletConnectAdapter.test.ts index c4e37119a..bd9c917f2 100644 --- a/src/lib/walletAdapters/WalletConnectAdapter.test.ts +++ b/src/lib/walletAdapters/WalletConnectAdapter.test.ts @@ -1,47 +1,99 @@ -import { Signer } from 'ethers' +import { BigNumber, Signer } from 'ethers' import { getSigner } from '../../../testLib/utils' import { WalletConnectAdapter } from './WalletConnectAdapter' -describe('Wallet Connect Adapter', () => { - let adapter: WalletConnectAdapter | null = null - let signer: Signer | null = null - +describe('Wallet Connect Adapter', function (this: { + adapter: WalletConnectAdapter + signer: Signer +}) { beforeEach(async () => { - signer = getSigner(9) - - adapter = new WalletConnectAdapter(signer) + this.signer = getSigner(9) + this.adapter = new WalletConnectAdapter(this.signer) }) test('send tx', async () => { - const from = await signer?.getAddress() + const from = await this.signer.getAddress() const to = await getSigner(0).getAddress() + const chainId = await this.signer.getChainId() const method = 'eth_sendTransaction' const params = [ { - data: '', + data: '0x123456789a', from, to, value: '0x3e8', + gas: '25000', + gasPrice: '60000000', + chainId, }, ] - const result = await adapter?.handleCall(method, params) + const mockIt = jest.fn() - expect(result).toBeDefined() - expect(result).toContain('0x') + jest.spyOn(this.signer, 'sendTransaction').mockImplementation((tx: any) => { + mockIt(tx) + return Promise.resolve(tx) + }) + + await this.adapter.handleCall(method, params) + + expect(mockIt).toBeCalledWith({ + data: params[0].data, + from, + to, + chainId, + nonce: undefined, + gasPrice: BigNumber.from(params[0].gasPrice), + gasLimit: BigNumber.from(params[0].gas), + value: BigNumber.from('0x3e8'), + }) + }) + + test('default parameters are set', async () => { + const method = 'eth_sendTransaction' + + const from = await this.signer.getAddress() + const to = await getSigner(0).getAddress() + + const params = [ + { + to, + from, + }, + ] + + const mockIt = jest.fn() + + jest.spyOn(this.signer, 'sendTransaction').mockImplementation((tx: any) => { + mockIt(tx) + return Promise.resolve(tx) + }) + + await this.adapter.handleCall(method, params) + + expect(mockIt).toBeCalledWith({ + to, + from, + data: '0x', + chainId: undefined, + gasLimit: undefined, + gasPrice: undefined, + nonce: undefined, + value: BigNumber.from(0), + }) }) // method not supported by ganache-cli // eslint-disable-next-line jest/no-disabled-tests test.skip('personal sign', async () => { - const from = await signer?.getAddress() + const from = await this.signer.getAddress() const message = '0x68656c6c6f20776f726c6421' const method = 'personal_sign' const params = [message, from] - const result = await adapter?.handleCall(method, params) + const result = await this.adapter.handleCall(method, params) expect(result).toBeDefined() expect(result).toContain('0x') @@ -56,7 +108,7 @@ describe('Wallet Connect Adapter', () => { '{"domain":{"chainId":31,"name":"Ether Mail","version":"1"},"message":{"contents":"{ from: { name: \'Cow\', wallet: \'0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826\' }, to: { name: \'Bob\', wallet: \'0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB\' }, contents: \'Hello, Bob!\' }","from":"Diego","to":"Cesar"},"primaryType":"Mail","types":{"EIP712Domain":[{"name":"name","type":"string"},{"name":"version","type":"string"},{"name":"chainId","type":"uint256"}],"Mail":[{"name":"from","type":"string"},{"name":"to","type":"string"},{"name":"contents","type":"string"}]}}', ] - const result = await adapter?.handleCall(method, params) + const result = await this.adapter.handleCall(method, params) expect(result).toBeDefined() expect(result).toContain('0x') diff --git a/src/lib/walletAdapters/WalletConnectAdapter.ts b/src/lib/walletAdapters/WalletConnectAdapter.ts index 065037591..797168ae3 100644 --- a/src/lib/walletAdapters/WalletConnectAdapter.ts +++ b/src/lib/walletAdapters/WalletConnectAdapter.ts @@ -1,5 +1,6 @@ import { TransactionResponse } from '@ethersproject/providers' -import { Signer, constants, utils } from 'ethers' +import { TransactionRequest } from '@ethersproject/abstract-provider' +import { Signer, utils, BigNumber } from 'ethers' import { RIFWallet } from '../core' export class WalletConnectAdapter { private resolvers: IResolver[] @@ -41,13 +42,19 @@ class SendTransactionResolver implements IResolver { async resolve(params: any[]) { const payload = params.reduce((prev, curr) => ({ ...prev, ...curr }), {}) - if (payload.data === '') { - // TODO: assign undefined once the RIFWallet changes are applied - payload.data = constants.HashZero + const formattedPayload: TransactionRequest = { + to: payload.to, + from: payload.from, + nonce: payload.nonce, + data: payload.data || '0x', + value: BigNumber.from(payload.value || 0), + chainId: payload.chainId, + gasLimit: payload.gas ? BigNumber.from(payload.gas) : undefined, // WC's gas to gasLimit + gasPrice: payload.gasPrice ? BigNumber.from(payload.gasPrice) : undefined, } return this.signer - .sendTransaction(payload) + .sendTransaction(formattedPayload) .then((tx: TransactionResponse) => tx.hash) } }