From bad0c97477204cac7d7b0b270a25a294e47ac5f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Fri, 13 Aug 2021 19:08:52 +0200 Subject: [PATCH 1/7] add findTokenByAddressInCurrency and deprecate findTokenByAddress --- packages/cryptoassets/src/currencies.test.ts | 32 +++++++++++++++++++- packages/cryptoassets/src/tokens.ts | 22 +++++++++++--- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/packages/cryptoassets/src/currencies.test.ts b/packages/cryptoassets/src/currencies.test.ts index 27af41e34..963e91460 100644 --- a/packages/cryptoassets/src/currencies.test.ts +++ b/packages/cryptoassets/src/currencies.test.ts @@ -3,7 +3,11 @@ import { getFiatCurrencyByTicker, hasFiatCurrencyTicker, } from "./fiats"; -import { listTokens, findTokenById } from "./tokens"; +import { + listTokens, + findTokenById, + findTokenByAddressInCurrency, +} from "./tokens"; import { listCryptoCurrencies, hasCryptoCurrencyId, @@ -150,6 +154,32 @@ test("tokens are correct", () => { } }); +test("findTokenByAddressInCurrency", () => { + expect( + findTokenByAddressInCurrency( + "0x111111111117dC0aa78b770fA6A738034120C302", + "bsc" + ) + ).toMatchObject({ + id: "bsc/bep20/1inch_token", + }); + expect( + findTokenByAddressInCurrency( + "0x111111111117dC0aa78b770fA6A738034120C302", + "ethereum" + ) + ).toMatchObject({ + id: "ethereum/erc20/1inch_token", + }); + expect(findTokenByAddressInCurrency("0x0", "bsc")).toEqual(null); + expect( + findTokenByAddressInCurrency( + "0x111111111117dC0aa78b770fA6A738034120C302", + "tron" + ) + ).toEqual(null); +}); + test("fiats list is sorted by ticker", () => { expect( listFiatCurrencies() diff --git a/packages/cryptoassets/src/tokens.ts b/packages/cryptoassets/src/tokens.ts index 371b8ab81..1044c7154 100644 --- a/packages/cryptoassets/src/tokens.ts +++ b/packages/cryptoassets/src/tokens.ts @@ -13,6 +13,7 @@ const tokensByCryptoCurrencyWithDelisted: Record = {}; const tokensById: Record = {}; const tokensByTicker: Record = {}; const tokensByAddress: Record = {}; +const tokensByCurrencyAddress: Record = {}; addTokens(erc20tokens.map(convertERC20)); addTokens(trc10tokens.map(convertTRONTokens("trc10"))); addTokens(trc20tokens.map(convertTRONTokens("trc20"))); @@ -84,15 +85,26 @@ export function findTokenById(id: string): TokenCurrency | null | undefined { return tokensById[id]; } -/** - * - */ +let deprecatedDisplayed = false; export function findTokenByAddress( address: string ): TokenCurrency | null | undefined { + if (!deprecatedDisplayed) { + deprecatedDisplayed = true; + console.warn( + "findTokenByAddress is deprecated. use findTokenByAddressInCurrency" + ); + } return tokensByAddress[address.toLowerCase()]; } +export function findTokenByAddressInCurrency( + address: string, + currencyId: string +): TokenCurrency | null | undefined { + return tokensByCurrencyAddress[currencyId + ":" + address.toLowerCase()]; +} + /** * */ @@ -141,8 +153,10 @@ function addTokens(list: TokenCurrency[]) { tokensByTicker[token.ticker] = token; } - tokensByAddress[token.contractAddress.toLowerCase()] = token; + const lowCaseContract = token.contractAddress.toLowerCase(); + tokensByAddress[lowCaseContract] = token; const { parentCurrency } = token; + tokensByCurrencyAddress[parentCurrency.id + ":" + lowCaseContract] = token; if (!(parentCurrency.id in tokensByCryptoCurrency)) { tokensByCryptoCurrency[parentCurrency.id] = []; From b59bf632a97fd110ed44a94818416c6bf3567e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Fri, 13 Aug 2021 19:28:34 +0200 Subject: [PATCH 2/7] fixes test --- packages/cryptoassets/src/currencies.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cryptoassets/src/currencies.test.ts b/packages/cryptoassets/src/currencies.test.ts index 963e91460..0ec903af8 100644 --- a/packages/cryptoassets/src/currencies.test.ts +++ b/packages/cryptoassets/src/currencies.test.ts @@ -171,13 +171,13 @@ test("findTokenByAddressInCurrency", () => { ).toMatchObject({ id: "ethereum/erc20/1inch_token", }); - expect(findTokenByAddressInCurrency("0x0", "bsc")).toEqual(null); + expect(findTokenByAddressInCurrency("0x0", "bsc")).toBe(undefined); expect( findTokenByAddressInCurrency( "0x111111111117dC0aa78b770fA6A738034120C302", "tron" ) - ).toEqual(null); + ).toBe(undefined); }); test("fiats list is sorted by ticker", () => { From 837cdb41fbb67d838ff9b55787795341fe8111df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Fri, 13 Aug 2021 19:29:06 +0200 Subject: [PATCH 3/7] erc20 signature to resolve by contract AND chainId --- packages/cryptoassets/README.md | 16 ++------- packages/hw-app-eth/README.md | 5 +-- packages/hw-app-eth/src/Eth.ts | 8 ++--- packages/hw-app-eth/src/erc20.ts | 19 +++++++---- packages/hw-app-eth/tests/Eth.test.ts | 47 ++++++++++++++++----------- 5 files changed, 50 insertions(+), 45 deletions(-) diff --git a/packages/cryptoassets/README.md b/packages/cryptoassets/README.md index efae6f347..fd64f7682 100644 --- a/packages/cryptoassets/README.md +++ b/packages/cryptoassets/README.md @@ -59,14 +59,12 @@ There are two modes of usage of this library. - [Parameters](#parameters-17) - [findTokenById](#findtokenbyid) - [Parameters](#parameters-18) -- [findTokenByAddress](#findtokenbyaddress) - - [Parameters](#parameters-19) - [hasTokenId](#hastokenid) - - [Parameters](#parameters-20) + - [Parameters](#parameters-19) - [getTokenById](#gettokenbyid) - - [Parameters](#parameters-21) + - [Parameters](#parameters-20) - [findCompoundToken](#findcompoundtoken) - - [Parameters](#parameters-22) + - [Parameters](#parameters-21) - [Unit](#unit) - [Properties](#properties) - [CurrencyCommon](#currencycommon) @@ -244,14 +242,6 @@ Returns **([TokenCurrency](#tokencurrency) | null | [undefined](https://develope Returns **([TokenCurrency](#tokencurrency) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** -### findTokenByAddress - -#### Parameters - -- `address` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** - -Returns **([TokenCurrency](#tokencurrency) | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** - ### hasTokenId #### Parameters diff --git a/packages/hw-app-eth/README.md b/packages/hw-app-eth/README.md index b3f8af810..d0c5e4113 100644 --- a/packages/hw-app-eth/README.md +++ b/packages/hw-app-eth/README.md @@ -15,7 +15,7 @@ Ledger Hardware Wallet ETH JavaScript bindings. - [loadInfosForContractMethod](#loadinfosforcontractmethod) - [Parameters](#parameters) -- [byContractAddress](#bycontractaddress) +- [byContractAddressAndChainId](#bycontractaddressandchainid) - [Parameters](#parameters-1) - [list](#list) - [Eth](#eth) @@ -72,13 +72,14 @@ Retrieve the metadatas a given contract address and a method selector Returns **[Promise](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise)<(ContractMethod | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))>** -### byContractAddress +### byContractAddressAndChainId Retrieve the token information by a given contract address if any #### Parameters - `contract` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** +- `chainId` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** Returns **(TokenInfo | null | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** diff --git a/packages/hw-app-eth/src/Eth.ts b/packages/hw-app-eth/src/Eth.ts index 07d7a417a..7ccf4791a 100644 --- a/packages/hw-app-eth/src/Eth.ts +++ b/packages/hw-app-eth/src/Eth.ts @@ -21,7 +21,7 @@ import { EthAppPleaseEnableContractData } from "@ledgerhq/errors"; import type Transport from "@ledgerhq/hw-transport"; import { BigNumber } from "bignumber.js"; import { ethers } from "ethers"; -import { byContractAddress } from "./erc20"; +import { byContractAddressAndChainId } from "./erc20"; import { loadInfosForContractMethod } from "./contracts"; export type StarkQuantizationType = @@ -164,8 +164,8 @@ export default class Eth { * @param {*} info: a blob from "erc20.js" utilities that contains all token information. * * @example - * import { byContractAddress } from "@ledgerhq/hw-app-eth/erc20" - * const zrxInfo = byContractAddress("0xe41d2489571d322189246dafa5ebde1f4699f498") + * import { byContractAddressAndChainId } from "@ledgerhq/hw-app-eth/erc20" + * const zrxInfo = byContractAddressAndChainId("0xe41d2489571d322189246dafa5ebde1f4699f498", chainId) * if (zrxInfo) await appEth.provideERC20TokenInformation(zrxInfo) * const signed = await appEth.signTransaction(path, rawTxHex) */ @@ -290,7 +290,7 @@ export default class Eth { }; } const provideForContract = async (address) => { - const erc20Info = byContractAddress(address); + const erc20Info = byContractAddressAndChainId(address, chainIdTruncated); if (erc20Info) { log( "ethereum", diff --git a/packages/hw-app-eth/src/erc20.ts b/packages/hw-app-eth/src/erc20.ts index 833cd04a8..bc3f48b35 100644 --- a/packages/hw-app-eth/src/erc20.ts +++ b/packages/hw-app-eth/src/erc20.ts @@ -3,10 +3,11 @@ import blob from "@ledgerhq/cryptoassets/data/erc20-signatures"; /** * Retrieve the token information by a given contract address if any */ -export const byContractAddress = ( - contract: string +export const byContractAddressAndChainId = ( + contract: string, + chainId: number ): TokenInfo | null | undefined => - get().byContract(asContractAddress(contract)); + get().byContractAndChainId(asContractAddress(contract), chainId); /** * list all the ERC20 tokens informations @@ -21,7 +22,10 @@ export type TokenInfo = { data: Buffer; }; export type API = { - byContract: (arg0: string) => TokenInfo | null | undefined; + byContractAndChainId: ( + addr: string, + id: number + ) => TokenInfo | null | undefined; list: () => TokenInfo[]; }; @@ -36,7 +40,7 @@ const get: () => API = (() => { return () => { if (cache) return cache; const buf = Buffer.from(blob, "base64"); - const byContract = {}; + const map = {}; const entries: TokenInfo[] = []; let i = 0; @@ -67,13 +71,14 @@ const get: () => API = (() => { data: item, }; entries.push(entry); - byContract[contractAddress] = entry; + map[String(chainId) + ":" + contractAddress] = entry; i += length; } const api = { list: () => entries, - byContract: (contractAddress) => byContract[contractAddress], + byContractAndChainId: (contractAddress, chainId) => + map[String(chainId) + ":" + contractAddress], }; cache = api; return api; diff --git a/packages/hw-app-eth/tests/Eth.test.ts b/packages/hw-app-eth/tests/Eth.test.ts index 7178b12ca..03a631308 100644 --- a/packages/hw-app-eth/tests/Eth.test.ts +++ b/packages/hw-app-eth/tests/Eth.test.ts @@ -5,7 +5,7 @@ import { import Eth from "../src/Eth"; import { TokenInfo } from "../src/erc20"; import { BigNumber } from "bignumber.js"; -import { byContractAddress } from "../src/erc20"; +import { byContractAddressAndChainId } from "../src/erc20"; test("getAppConfiguration", async () => { const transport = await openTransportReplayer( @@ -325,8 +325,9 @@ test("provideERC20TokenInformation", async () => { `) ); const eth = new Eth(transport); - const zrxInfo = byContractAddress( - "0xe41d2489571d322189246dafa5ebde1f4699f498" + const zrxInfo = byContractAddressAndChainId( + "0xe41d2489571d322189246dafa5ebde1f4699f498", + 1 ); const result = await eth.provideERC20TokenInformation(zrxInfo as TokenInfo); expect(result).toEqual(true); @@ -344,8 +345,9 @@ test("signAllowance", async () => { `) ); const eth = new Eth(transport); - const tokenInfo = byContractAddress( - "0xdac17f958d2ee523a2206206994597c13d831ec7" + const tokenInfo = byContractAddressAndChainId( + "0xdac17f958d2ee523a2206206994597c13d831ec7", + 1 ); await eth.provideERC20TokenInformation(tokenInfo as TokenInfo); const result = await eth.signTransaction( @@ -467,12 +469,14 @@ test("starkSignOrderTokens", async () => { `) ); const eth = new Eth(transport); - const tokenInfo1 = byContractAddress( - "0xe41d2489571d322189246dafa5ebde1f4699f498" + const tokenInfo1 = byContractAddressAndChainId( + "0xe41d2489571d322189246dafa5ebde1f4699f498", + 1 ); await eth.provideERC20TokenInformation(tokenInfo1 as TokenInfo); - const tokenInfo2 = byContractAddress( - "0xdac17f958d2ee523a2206206994597c13d831ec7" + const tokenInfo2 = byContractAddressAndChainId( + "0xdac17f958d2ee523a2206206994597c13d831ec7", + 1 ); await eth.provideERC20TokenInformation(tokenInfo2 as TokenInfo); const result = await eth.starkSignOrder( @@ -506,12 +510,14 @@ test("starkSignOrderTokens_v2", async () => { `) ); const eth = new Eth(transport); - const tokenInfo1 = byContractAddress( - "0xe41d2489571d322189246dafa5ebde1f4699f498" + const tokenInfo1 = byContractAddressAndChainId( + "0xe41d2489571d322189246dafa5ebde1f4699f498", + 1 ); await eth.provideERC20TokenInformation(tokenInfo1 as TokenInfo); - const tokenInfo2 = byContractAddress( - "0xdac17f958d2ee523a2206206994597c13d831ec7" + const tokenInfo2 = byContractAddressAndChainId( + "0xdac17f958d2ee523a2206206994597c13d831ec7", + 1 ); await eth.provideERC20TokenInformation(tokenInfo2 as TokenInfo); const result = await eth.starkSignOrder_v2( @@ -652,8 +658,9 @@ test("starkDepositToken", async () => { `) ); const eth = new Eth(transport); - const tokenInfo = byContractAddress( - "0xdac17f958d2ee523a2206206994597c13d831ec7" + const tokenInfo = byContractAddressAndChainId( + "0xdac17f958d2ee523a2206206994597c13d831ec7", + 1 ); await eth.provideERC20TokenInformation(tokenInfo as TokenInfo); await eth.starkProvideQuantum( @@ -703,8 +710,9 @@ test("starkWithdrawToken", async () => { `) ); const eth = new Eth(transport); - const tokenInfo = byContractAddress( - "0xdac17f958d2ee523a2206206994597c13d831ec7" + const tokenInfo = byContractAddressAndChainId( + "0xdac17f958d2ee523a2206206994597c13d831ec7", + 1 ); await eth.provideERC20TokenInformation(tokenInfo as TokenInfo); await eth.starkProvideQuantum( @@ -836,8 +844,9 @@ test("starkEscapeTokens", async () => { `) ); const eth = new Eth(transport); - const tokenInfo = byContractAddress( - "0xdac17f958d2ee523a2206206994597c13d831ec7" + const tokenInfo = byContractAddressAndChainId( + "0xdac17f958d2ee523a2206206994597c13d831ec7", + 1 ); await eth.provideERC20TokenInformation(tokenInfo as TokenInfo); await eth.starkProvideQuantum( From d16902dd5bf858c1a0fe63d441f82572f49b8b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Fri, 13 Aug 2021 19:29:33 +0200 Subject: [PATCH 4/7] remove legacy doc of migrate_eth_app --- docs/migrate_eth_app.md | 59 ----------------------------------------- 1 file changed, 59 deletions(-) delete mode 100644 docs/migrate_eth_app.md diff --git a/docs/migrate_eth_app.md b/docs/migrate_eth_app.md deleted file mode 100644 index e79031448..000000000 --- a/docs/migrate_eth_app.md +++ /dev/null @@ -1,59 +0,0 @@ -# Prepare transition to incoming Ledger ETH app update - -There is going to be some minor changes in how the Ledger ETH Nano app works regarding ERC20. - -## Why - -- We are innovating to reduce the size of ETH app [following our users feedback](https://www.ledger.fr/2019/02/14/righting-our-1-5-5-nano-s-firmware-update/). -- We support more and more ERC20 and hardcoding that data in the app does not scale. - -## How - -Instead of the ETH app to hardcode ERC20 informations (like ticker, decimals, contract address,..) you will have to provide this data verified with Ledger's signature. - -### using LedgerJS - -Make sure to be up to date with [`@ledgerhq/hw-app-eth`](https://github.com/LedgerHQ/ledgerjs/tree/master/packages/hw-app-eth) (must be `>= 4.39`). - -The library now includes `provideERC20TokenInformation`, a new method that you need to call **just before** signing an ERC20 transaction to provide that ERC20 informations. - -> ERC20 data can be retrieved from `@ledgerhq/hw-app-eth/erc20`. - -Example: - -```js -import { byContractAddress } from "@ledgerhq/hw-app-eth/erc20"; -const zrxInfo = byContractAddress("0xe41d2489571d322189246dafa5ebde1f4699f498"); -if (zrxInfo) await appEth.provideERC20TokenInformation(zrxInfo); -const signed = await appEth.signTransaction(path, rawTxHex); -``` - -> If you do so, the JS bundle size will increase by about ~150kb with today's data (compressed in the most possible way). An alternative is for you to host this yourself and query your API (or include it among your data). - -NB: we might update the ERC20 data over the next months to add more tokens,... - -### not using LedgerJS - -You can take a look at [LedgerJS implementation](https://github.com/LedgerHQ/ledgerjs/tree/master/packages/hw-app-eth) as well as taking a look at the [ETH app documentation](https://github.com/LedgerHQ/ledger-app-eth/blob/externalize-erc20/doc/ethapp.asc). - -## Scenarios - -We will now explain the behavior of each case weither you update to `provideERC20TokenInformation` or not and weither the user have an old ETH app or not. - -### old ETH app, old ledger codebase - -no problem. It's what we have today. Since the old ETH app have the ERC20 data, it just works. - -### old ETH app, new ledger codebase - -If you do migrate to the suggested solution BUT user still come back with an old version of their nano app, **there is no impact at all**. The call to `provideERC20TokenInformation` will silently fail to be backward compatible. - -### new ETH app, old ledgerjs codebase - -In this case, the ETH app will still be able to sign ERC20 transactions, however user will not anymore see an amount with a ticker but instead will see a contract address (the ERC20 contract). It is basically like using a non recognized ERC20 as of today. - -**=> solution is to migrate to the suggested code above.** - -### new ETH app, new ledgerjs codebase - -We are all set! From a6251c9b516be9af3a5c8160375be3460e6be493 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Fri, 13 Aug 2021 20:15:45 +0200 Subject: [PATCH 5/7] Remove invalid tests --- packages/hw-app-eth/tests/Eth.test.ts | 51 +-------------------------- 1 file changed, 1 insertion(+), 50 deletions(-) diff --git a/packages/hw-app-eth/tests/Eth.test.ts b/packages/hw-app-eth/tests/Eth.test.ts index 03a631308..d476c9044 100644 --- a/packages/hw-app-eth/tests/Eth.test.ts +++ b/packages/hw-app-eth/tests/Eth.test.ts @@ -103,7 +103,7 @@ test("signTransaction supports EIP2930", async () => { }); }); -test("signTransaction testing provideERC20Informations + setExternalPlugin", async () => { +test.skip("signTransaction testing provideERC20Informations + setExternalPlugin", async () => { const transport = await openTransportReplayer( RecordStore.fromString( ` @@ -333,55 +333,6 @@ test("provideERC20TokenInformation", async () => { expect(result).toEqual(true); }); -test("signAllowance", async () => { - const transport = await openTransportReplayer( - RecordStore.fromString(` - => e00a0000670455534454dac17f958d2ee523a2206206994597c13d831ec700000006000000013044022078c66ccea3e4dedb15a24ec3c783d7b582cd260daf62fd36afe9a8212a344aed0220160ba8c1c4b6a8aa6565bed20632a091aeeeb7bfdac67fc6589a6031acbf511c - <= 9000 - => e00a0000670455534454dac17f958d2ee523a2206206994597c13d831ec700000006000000013044022078c66ccea3e4dedb15a24ec3c783d7b582cd260daf62fd36afe9a8212a344aed0220160ba8c1c4b6a8aa6565bed20632a091aeeeb7bfdac67fc6589a6031acbf511c - <= 9000 - => e004000084058000002c8000003c800000000000000000000000f86d018504e3b2920082520894dac17f958d2ee523a2206206994597c13d831ec7872bd72a24874000b844095ea7b30000000000000000000000000102030405060708090a0b0c0d0e0f101112131400000000000000000000000000000000000000000000000000000000000186a0 - <= 1b0a5a7a8732d95ee05e6dd11b28500c0482fd9ef24028eb5448b5c9c713f13bbb1ef940556853fc8b3883e6ef810d18566f13019e6bea70f340cbfde36947408b9000 - `) - ); - const eth = new Eth(transport); - const tokenInfo = byContractAddressAndChainId( - "0xdac17f958d2ee523a2206206994597c13d831ec7", - 1 - ); - await eth.provideERC20TokenInformation(tokenInfo as TokenInfo); - const result = await eth.signTransaction( - "44'/60'/0'/0/0", - "f86d018504e3b2920082520894dac17f958d2ee523a2206206994597c13d831ec7872bd72a24874000b844095ea7b30000000000000000000000000102030405060708090a0b0c0d0e0f101112131400000000000000000000000000000000000000000000000000000000000186a0" - ); - expect(result).toEqual({ - r: "0a5a7a8732d95ee05e6dd11b28500c0482fd9ef24028eb5448b5c9c713f13bbb", - s: "1ef940556853fc8b3883e6ef810d18566f13019e6bea70f340cbfde36947408b", - v: "1b", - }); -}); - -test("signAllowanceUnlimited", async () => { - const transport = await openTransportReplayer( - RecordStore.fromString(` - => e00a0000670455534454dac17f958d2ee523a2206206994597c13d831ec700000006000000013044022078c66ccea3e4dedb15a24ec3c783d7b582cd260daf62fd36afe9a8212a344aed0220160ba8c1c4b6a8aa6565bed20632a091aeeeb7bfdac67fc6589a6031acbf511c - <= 9000 - => e004000084058000002c8000003c800000000000000000000000f86d018504e3b2920082520894dac17f958d2ee523a2206206994597c13d831ec7872bd72a24874000b844095ea7b30000000000000000000000000102030405060708090a0b0c0d0e0f1011121314ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - <= 1b3fa6a78fb25f87f063fc8db5cb4efc1794e01c973994e26a6fa1603c3ac3db9d3dc98795b5f99ba1eeae84ef01ecbfad188f00446d56b6e9a0eb9ec6f4bae7fe9000 - `) - ); - const eth = new Eth(transport); - const result = await eth.signTransaction( - "44'/60'/0'/0/0", - "f86d018504e3b2920082520894dac17f958d2ee523a2206206994597c13d831ec7872bd72a24874000b844095ea7b30000000000000000000000000102030405060708090a0b0c0d0e0f1011121314ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - ); - expect(result).toEqual({ - r: "3fa6a78fb25f87f063fc8db5cb4efc1794e01c973994e26a6fa1603c3ac3db9d", - s: "3dc98795b5f99ba1eeae84ef01ecbfad188f00446d56b6e9a0eb9ec6f4bae7fe", - v: "1b", - }); -}); - test("starkGetPublicKey", async () => { const transport = await openTransportReplayer( RecordStore.fromString(` From 96681164c7572ec98e78b1876f72ca36d842f7fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Mon, 16 Aug 2021 11:26:40 +0200 Subject: [PATCH 6/7] add a real world test with a paraswap of 1INCH & fixed sig --- packages/hw-app-eth/tests/Eth.test.ts | 58 ++++++++------------------- 1 file changed, 16 insertions(+), 42 deletions(-) diff --git a/packages/hw-app-eth/tests/Eth.test.ts b/packages/hw-app-eth/tests/Eth.test.ts index d476c9044..85c6758af 100644 --- a/packages/hw-app-eth/tests/Eth.test.ts +++ b/packages/hw-app-eth/tests/Eth.test.ts @@ -6,6 +6,7 @@ import Eth from "../src/Eth"; import { TokenInfo } from "../src/erc20"; import { BigNumber } from "bignumber.js"; import { byContractAddressAndChainId } from "../src/erc20"; +import { listen, log } from "@ledgerhq/logs"; test("getAppConfiguration", async () => { const transport = await openTransportReplayer( @@ -103,66 +104,39 @@ test("signTransaction supports EIP2930", async () => { }); }); -test.skip("signTransaction testing provideERC20Informations + setExternalPlugin", async () => { +test("paraswap", async () => { const transport = await openTransportReplayer( RecordStore.fromString( ` - => e0120000680850617261737761701bd435f3c054b6e901b7b108a0ab7617c808677bec1d21dd3045022100ee2b33270cf910f481e64b7781c4693e7bc86e338476d65c30c9f3d41fa4924e022079fc72cc69954f5ab1949e7d2f3023948f10dc94c9455999eb2ef38ac25fe33d + => e0120000670850617261737761701bd435f3c054b6e901b7b108a0ab7617c808677bcfc0afeb304402201c0cbe69aac517825b3a6eb5e7251e8fd57ff93a43bd3df52c7a841818eda81b022001a10cc326efaee2463fc96e7c29739c308fb8179bd2ac37303662bae4f7705c <= 9000 - => e00a0000670354454c467bccd9d29f223bce8043b84e8c8b282827790f00000002000000013045022100ebe6667ee0d706d1fde8a81e9a0e2e2ea334e8cb5fbfd7d1332ad746bcf0dbd502206a8094623414077283b89498b467488ca406f2c18486c50f0933bf11401c9a93 + => e00a0000680531494e4348111111111117dc0aa78b770fa6a738034120c3020000001200000001304402204623e5f1375c54a446157ae8a739204284cf053634b7abd083dc5f5d2675c4e702206ff94b4c84ba9e93f44065c38d7c92506621fa69ba04f767aa58221de8afbf17 <= 9000 - => e004000096058000002c8000003c800000008000000000000000f90b95820a13850c92a69c008309fb5e941bd435f3c054b6e901b7b108a0ab7617c808677b888ac7230489e80000b90b24ec1d21dd0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000 + => e004000096058000002c8000003c800000000000000000000000f903cd82043d8509c765240083042e73941bd435f3c054b6e901b7b108a0ab7617c808677b80b903a4cfc0afeb000000000000000000000000111111111117dc0aa78b770fa6a738034120c302000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000 <= 9000 - => E0048000960000000000000000000000008AC7230489E8000000000000000000000000000000000000000000000000000000000000059012BB00000000000000000000000000000000000000000000000000000000059E752F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000 + => e0048000960000000af10f7eb24f506cfd00000000000000000000000000000000000000000000000002a5b905b3c9fa4c00000000000000000000000000000000000000000000000002baaee8d905020a000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c000000000000000000000 <= 9000 - => E0048000960000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000B70617261737761702E696F000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + => e004800096000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000 <= 9000 - => E00480009600000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000020D000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000 + => e004800096000000000000000000000000000000000000000000000000000000000000000100000000000000000000000086d3579b043585a97532514016dcf0c2d6c4b6a100000000000000000000000000000000000000000000000000000000000000c499585aac00000000000000000000000000000000000000000000000af10f7eb24f506cfd000000000000000000000000000000000000 <= 9000 - => E0048000960000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000467BCCD9D29F223BCE8043B84E8C8B282827790F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000 + => e004800096000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000111111111117dc0aa78b770fa6a738034120c302000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000 <= 9000 - => E00480009600000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001A0000000000000000000000000695725627E04898EF4A126AE71FC30AA935C5FB600000000000000000000000086D3579B043585A97532514016DC + => e00480009600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c400000000000000000000000000000000000000000000000000000000000000010000 <= 9000 - => E004800096F0C2D6C4B6A100000000000000000000000000000000000000000000000000000000000011AC00000000000000000000000000000000000000000000000000000000000000A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A000000000000000000000000000000000 - <= 9000 - => E0048000960000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE000000000000000000000000467BCCD9D29F223BCE8043B84E8C8B282827790F000000000000 - <= 9000 - => E00480009600000000000017312CBD32DF845A3941F1BC80F33AD8F59C84260000000000000000000000006317C5E82A06E1D8BF200D21F4510AC2C038AC81000000000000000000000000000000000000000000000000000000000000156400000000000000000000000000000000000000000000000000000000000000A000000000000000000000000000000000000000000000000000000000 - <= 9000 - => E0048000960000000000000000000000000000000000000000000000000000000000000000000000E00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006CB5C5CB789F - <= 9000 - => E004800096AE62CE5CE280E1FBC5DD3BBDAD810000000000000000000000000000000000000000000000003FD67BA0CECC00000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000000000000000006400000000000000000 - <= 9000 - => E004800096000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000280000000000000000000000000BA100000625A3754423978A60C9317C58A42 - <= 9000 - => E0048000964E3D000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000017312CBD32DF845A - <= 9000 - => E0048000963941F1BC80F33AD8F59C84260000000000000000000000006317C5E82A06E1D8BF200D21F4510AC2C038AC81000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - <= 9000 - => E004800096000000000000000000000000000000000000000000E000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000059A19D8C652FA0284F44113D0FF9ABA70BD46FB4 - <= 9000 - => E00480009600000000000000000000000000000000000000000000000016345785D8A000000000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000467BCCD9D29F223BCE8043B84E8C8B282827790F00000000000000000000000000000000000000000000 - <= 9000 - => E0048000960000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000017312CBD32DF845A3941F1BC80F33AD8F59C8426000000000000000000000000 - <= 9000 - => E0048000966317C5E82A06E1D8BF200D21F4510AC2C038AC81000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000A0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E00000 - <= 9000 - => E004800096000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000003B63A353C996A2C0A7BEADD8A9052A04CA8D7A5C000000000000000000000000000000000000000000000004 - <= 9000 - => E00480008b972411230CD2FD700000000000000000000000000000000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF25A0FFB4409987569488BE7E9E6B94B4B3EAB41477C6ABEC965D73F547F0EB1FE421A00C180ECB60187F13D49B37F290B533671062D8AA1F01A34C34B6EBEDFBC89558 - <= 26e8c2b5b956b34386e68c5cc5bfc76aac158706430fcf1c71c9f6eb7d9dd690c8064005410a778b047fdd4afcb1e712217c297e5b0a2190f88b9e56ac745fae699000 + => e00480006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076c65646765723200000000000000000000000000000000000000000000000000018080 + <= 26d9e62b0b6ae0c18d3d2ecdf20ce7f1c959e0f609b4e73e2d138bbdc3e1e9390012469e2124a8955b5159f670b0333b803a70dd7dc51558a8f7460b27eed77be59000 `.toLowerCase() ) ); - // Original TX: https://etherscan.io/tx/0xf87e29ee49230352f56f099ef2ae9c7144b3ecb2d0085212e2478b267479b4df const eth = new Eth(transport); const result = await eth.signTransaction( - "44'/60'/0'/0'/0", - "f90b95820a13850c92a69c008309fb5e941bd435f3c054b6e901b7b108a0ab7617c808677b888ac7230489e80000b90b24ec1d21dd0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000059012bb00000000000000000000000000000000000000000000000000000000059e752f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000b70617261737761702e696f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000020d0000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000467bccd9d29f223bce8043b84e8c8b282827790f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000695725627e04898ef4a126ae71fc30aa935c5fb600000000000000000000000086d3579b043585a97532514016dcf0c2d6c4b6a100000000000000000000000000000000000000000000000000000000000011ac00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000467bccd9d29f223bce8043b84e8c8b282827790f00000000000000000000000017312cbd32df845a3941f1bc80f33ad8f59c84260000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81000000000000000000000000000000000000000000000000000000000000156400000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000006cb5c5cb789fae62ce5ce280e1fbc5dd3bbdad810000000000000000000000000000000000000000000000003fd67ba0cecc00000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000006400000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000280000000000000000000000000ba100000625a3754423978a60c9317c58a424e3d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000017312cbd32df845a3941f1bc80f33ad8f59c84260000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000059a19d8c652fa0284f44113d0ff9aba70bd46fb400000000000000000000000000000000000000000000000016345785d8a000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000467bccd9d29f223bce8043b84e8c8b282827790f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000017312cbd32df845a3941f1bc80f33ad8f59c84260000000000000000000000006317c5e82a06e1d8bf200d21f4510ac2c038ac81000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000003b63a353c996a2c0a7beadd8a9052a04ca8d7a5c000000000000000000000000000000000000000000000004972411230cd2fd700000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff25a0ffb4409987569488be7e9e6b94b4b3eab41477c6abec965d73f547f0eb1fe421a00c180ecb60187f13d49b37f290b533671062d8aa1f01a34c34b6ebedfbc89558" + "44'/60'/0'/0/0", + "f903cd82043d8509c765240083042e73941bd435f3c054b6e901b7b108a0ab7617c808677b80b903a4cfc0afeb000000000000000000000000111111111117dc0aa78b770fa6a738034120c302000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee00000000000000000000000000000000000000000000000af10f7eb24f506cfd00000000000000000000000000000000000000000000000002a5b905b3c9fa4c00000000000000000000000000000000000000000000000002baaee8d905020a000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002c00000000000000000000000000000000000000000000000000000000000000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000086d3579b043585a97532514016dcf0c2d6c4b6a100000000000000000000000000000000000000000000000000000000000000c499585aac00000000000000000000000000000000000000000000000af10f7eb24f506cfd000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000002000000000000000000000000111111111117dc0aa78b770fa6a738034120c302000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c40000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000076c65646765723200000000000000000000000000000000000000000000000000018080" ); expect(result).toEqual({ - r: "e8c2b5b956b34386e68c5cc5bfc76aac158706430fcf1c71c9f6eb7d9dd690c8", - s: "064005410a778b047fdd4afcb1e712217c297e5b0a2190f88b9e56ac745fae69", + r: "d9e62b0b6ae0c18d3d2ecdf20ce7f1c959e0f609b4e73e2d138bbdc3e1e93900", + s: "12469e2124a8955b5159f670b0333b803a70dd7dc51558a8f7460b27eed77be5", v: "26", }); }); From 071691f844b83b7e433593ab52a7ac602666fa4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABtan=20Renaudeau?= Date: Mon, 16 Aug 2021 11:37:41 +0200 Subject: [PATCH 7/7] update doc --- packages/hw-app-eth/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hw-app-eth/README.md b/packages/hw-app-eth/README.md index d0c5e4113..f18afc761 100644 --- a/packages/hw-app-eth/README.md +++ b/packages/hw-app-eth/README.md @@ -139,8 +139,8 @@ calling this contract address to display the proper token information to the use ##### Examples ```javascript -import { byContractAddress } from "@ledgerhq/hw-app-eth/erc20" -const zrxInfo = byContractAddress("0xe41d2489571d322189246dafa5ebde1f4699f498") +import { byContractAddressAndChainId } from "@ledgerhq/hw-app-eth/erc20" +const zrxInfo = byContractAddressAndChainId("0xe41d2489571d322189246dafa5ebde1f4699f498", chainId) if (zrxInfo) await appEth.provideERC20TokenInformation(zrxInfo) const signed = await appEth.signTransaction(path, rawTxHex) ```