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

chore: viem #1130

Merged
merged 54 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
bbeb1c6
chore: bump typescript on packages
0xKheops Oct 25, 2023
8fa5729
chore: extension upgrade to typescript 5
0xKheops Oct 25, 2023
ba79078
chore: changeset
0xKheops Oct 25, 2023
65da393
feat: viem public client for balances libraries
0xKheops Oct 25, 2023
c831456
feat: signAndSend using viem
0xKheops Oct 26, 2023
2c39b9a
chore: handler.tabs to use viem
0xKheops Oct 26, 2023
e149ad8
fix: use viem client in handler.tabs
0xKheops Oct 26, 2023
a6366ed
chore: remove ethers from evm connector
0xKheops Oct 26, 2023
ec0db36
wip: extension publicClient
0xKheops Oct 26, 2023
5961add
wip: migrate typings
0xKheops Oct 27, 2023
da39b0b
wip: adjust types
0xKheops Oct 27, 2023
59839df
wip: requests typings
0xKheops Oct 27, 2023
97d7fae
wip: frontend with viem
0xKheops Oct 27, 2023
2b03fb1
fix: transport errors
0xKheops Oct 30, 2023
2ac0320
feat: use multicall in evm-native module
0xKheops Oct 30, 2023
4922569
chore: viem TransactionRequest
0xKheops Oct 31, 2023
35c14c3
Merge branch 'dev' into chore/bump-typescript
0xKheops Oct 31, 2023
fac930e
Merge branch 'chore/bump-typescript' into chore/viem
0xKheops Oct 31, 2023
2e4ae75
fix: sort http batch response items
0xKheops Oct 31, 2023
d208232
feat: acala evm chains in playground
0xKheops Nov 1, 2023
0bdd9c7
fix: build
0xKheops Nov 1, 2023
33939d2
Merge branch 'dev' into chore/viem
0xKheops Nov 1, 2023
5018440
fix: tests
0xKheops Nov 1, 2023
ca8610c
fix: processing state on approve btn
0xKheops Nov 1, 2023
9c13ca1
fix: eip1559 detection
0xKheops Nov 1, 2023
3a2f5a5
fix: message sign button process
0xKheops Nov 1, 2023
03180f5
chore: typings cleanup
0xKheops Nov 1, 2023
7d7f8cb
fix: bunch of fixes
0xKheops Nov 2, 2023
5600c87
chore: remove viem batch temporary fix
0xKheops Nov 2, 2023
58d157b
wip: replace bignumber usage
0xKheops Nov 2, 2023
7767d2b
chore: translate bignumber to bigint
0xKheops Nov 2, 2023
3a2a605
wip: tx decoding
0xKheops Nov 3, 2023
e8640f6
wip: tx decoding
0xKheops Nov 3, 2023
a682bc3
wip: getContractCallArg
0xKheops Nov 3, 2023
5bf79ea
chore: getContractCallArgs
0xKheops Nov 3, 2023
9ae4190
chore: cleanup
0xKheops Nov 3, 2023
f2b6fdc
chore: cleanup
0xKheops Nov 3, 2023
77ace89
Merge branch 'dev' into chore/viem
0xKheops Nov 3, 2023
c6db575
wip: dcent
0xKheops Nov 3, 2023
82d7700
feat: dcent for viem
0xKheops Nov 3, 2023
6ae34ec
wip: self review
0xKheops Nov 3, 2023
6dc48ce
chore: remove acala provider
0xKheops Nov 6, 2023
310b07f
chore: yeet ethers
0xKheops Nov 6, 2023
8546052
fix: send funds amount check
0xKheops Nov 6, 2023
c3a37f0
fix: pass-through revert data
0xKheops Nov 6, 2023
494bd85
wip: cleanup
0xKheops Nov 6, 2023
9c83b61
fix: remove color transition on button
0xKheops Nov 7, 2023
15d820d
fix: speedup/cancel behavior
0xKheops Nov 7, 2023
b6d14fc
feat: display error as tooltip in custom gas form
0xKheops Nov 7, 2023
c615a36
fix: ledger signature crafting
0xKheops Nov 8, 2023
a63d0ef
fix: unlocks tx if user rejects from ledger
0xKheops Nov 8, 2023
ba0dd65
fix: ledger error drawer behavior
0xKheops Nov 8, 2023
87f2be9
fix: in captures use number type for chain tag
0xKheops Nov 8, 2023
a09510e
chore: cleanup
0xKheops Nov 8, 2023
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
8 changes: 8 additions & 0 deletions .changeset/moody-moons-teach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@talismn/balances-evm-native": patch
"@talismn/chain-connector-evm": patch
"@talismn/balances-evm-erc20": patch
"@talismn/util": patch
---

replace ethers by viem
6 changes: 6 additions & 0 deletions .changeset/witty-spiders-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@talismn/chain-connector-evm": minor
"@talismn/on-chain-id": minor
---

replace ethers by viem
4 changes: 2 additions & 2 deletions apps/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@floating-ui/react-dom": "2.0.1",
"@headlessui/react": "1.7.13",
"@hookform/resolvers": "2.9.11",
"@ledgerhq/hw-app-eth": "6.33.3",
"@ledgerhq/hw-app-eth": "6.34.8",
"@ledgerhq/hw-transport-webusb": "6.27.14",
"@metamask/browser-passworder": "4.1.0",
"@metamask/eth-sig-util": "5.1.0",
Expand Down Expand Up @@ -93,7 +93,6 @@
"dotenv-webpack": "^7.1.1",
"downshift": "^6.1.12",
"eth-phishing-detect": "latest",
"ethers": "5.7.2",
"fork-ts-checker-notifier-webpack-plugin": "^6.0.0",
"fork-ts-checker-webpack-plugin": "^7.2.14",
"framer-motion": "10.12.18",
Expand Down Expand Up @@ -138,6 +137,7 @@
"typescript": "^5.2.2",
"url-join": "^5.0.0",
"uuid": "^8.3.2",
"viem": "^1.18.9",
"webextension-polyfill": "0.8.0",
"webpack": "^5.88.1",
"webpack-cli": "^4.10.0",
Expand Down
8 changes: 3 additions & 5 deletions apps/extension/src/@talisman/util/formatEthValue.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import { formatDecimals } from "@talismn/util"
import { BigNumber, BigNumberish } from "ethers"
import { formatUnits } from "ethers/lib/utils"
import { formatDecimals, planckToTokens } from "@talismn/util"

export const formatEtherValue = (value: BigNumberish, decimals: number, symbol?: string) => {
return `${formatDecimals(formatUnits(BigNumber.from(value), decimals))}${
export const formatEthValue = (value: bigint, decimals: number, symbol?: string) => {
return `${formatDecimals(planckToTokens(value.toString(), decimals))}${
symbol ? ` ${symbol}` : ""
}`
}
4 changes: 2 additions & 2 deletions apps/extension/src/core/domains/accounts/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,11 +437,11 @@ export default class AccountsHandler extends ExtensionHandler {
const { err, val } = await getPairForAddressSafely(address, async (pair) => {
assert(pair.type === "ethereum", "Private key cannot be exported for this account type")

const pk = getPrivateKey(pair, pw as string)
const pk = getPrivateKey(pair, pw as string, "hex")

talismanAnalytics.capture("account export", { type: pair.type, mode: "pk" })

return pk.toString("hex")
return pk
})

if (err) throw new Error(val as string)
Expand Down
4 changes: 2 additions & 2 deletions apps/extension/src/core/domains/encrypt/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default class EncryptHandler extends ExtensionHandler {
const pw = this.stores.password.getPassword()
assert(pw, "Unable to retreive password from store.")

const pk = getPrivateKey(pair, pw)
const pk = getPrivateKey(pair, pw, "u8a")
const kp = { publicKey: pair.publicKey, secretKey: u8aToU8a(pk) } as Keypair

assert(kp.secretKey.length === 64, "Talisman secretKey is incorrect length")
Expand Down Expand Up @@ -66,7 +66,7 @@ export default class EncryptHandler extends ExtensionHandler {
const pw = this.stores.password.getPassword()
assert(pw, "Unable to retreive password from store.")

const pk = getPrivateKey(pair, pw)
const pk = getPrivateKey(pair, pw, "u8a")

assert(pk.length === 64, "Talisman secretKey is incorrect length")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ethers } from "ethers"
import { parseGwei } from "viem"

import {
getEthDerivationPath,
Expand All @@ -8,78 +8,68 @@ import {
isSafeImageUrl,
} from "../helpers"

const baseFeePerGas = ethers.utils.parseUnits("2", "gwei")
const maxPriorityFeePerGas = ethers.utils.parseUnits("8", "gwei")
const baseFeePerGas = parseGwei("2")
const maxPriorityFeePerGas = parseGwei("8")

describe("Test ethereum helpers", () => {
test("getMaxFeePerGas 0 block", async () => {
const result = getMaxFeePerGas(baseFeePerGas, maxPriorityFeePerGas, 0).toString()
const expected = ethers.utils.parseUnits("10", "gwei").toString()
const result = getMaxFeePerGas(baseFeePerGas, maxPriorityFeePerGas, 0)
const expected = parseGwei("10")

expect(result).toEqual(expected)
})

test("getMaxFeePerGas 8 block", async () => {
const result = getMaxFeePerGas(baseFeePerGas, maxPriorityFeePerGas, 8).toString()
const expected = ethers.utils.parseUnits("13131569026", "wei").toString()
const result = getMaxFeePerGas(baseFeePerGas, maxPriorityFeePerGas, 8)

expect(result).toEqual(expected)
expect(result).toEqual(13131569026n)
})

test("getTotalFeesFromGasSettings - EIP1559 maxFee lower than baseFee", () => {
const { estimatedFee, maxFee } = getTotalFeesFromGasSettings(
{
type: 2,
maxFeePerGas: ethers.utils.parseUnits("1.5", "gwei"),
maxPriorityFeePerGas: ethers.utils.parseUnits("0.5", "gwei"),
gasLimit: 22000,
type: "eip1559",
maxFeePerGas: parseGwei("1.5"),
maxPriorityFeePerGas: parseGwei("0.5"),
gas: 22000n,
},
21000,
21000n,
baseFeePerGas
) //

const expectedEstimatedFee = ethers.utils.parseUnits("42000000000000", "wei").toString()
const expectedMaxFee = ethers.utils.parseUnits("44000000000000", "wei").toString()
)

expect(estimatedFee.toString()).toEqual(expectedEstimatedFee)
expect(maxFee.toString()).toEqual(expectedMaxFee)
expect(estimatedFee).toEqual(42000000000000n)
expect(maxFee).toEqual(44000000000000n)
})

test("getTotalFeesFromGasSettings - EIP1559 classic", () => {
const { estimatedFee, maxFee } = getTotalFeesFromGasSettings(
{
type: 2,
maxFeePerGas: ethers.utils.parseUnits("3.5", "gwei"),
maxPriorityFeePerGas: ethers.utils.parseUnits("0.5", "gwei"),
gasLimit: 22000,
type: "eip1559",
maxFeePerGas: parseGwei("3.5"),
maxPriorityFeePerGas: parseGwei("0.5"),
gas: 22000n,
},
21000,
21000n,
baseFeePerGas
)

const expectedEstimatedFee = ethers.utils.parseUnits("52500000000000", "wei").toString()
const expectedMaxFee = ethers.utils.parseUnits("88000000000000", "wei").toString()

expect(estimatedFee.toString()).toEqual(expectedEstimatedFee)
expect(maxFee.toString()).toEqual(expectedMaxFee)
expect(estimatedFee).toEqual(52500000000000n)
expect(maxFee).toEqual(88000000000000n)
})

test("getTotalFeesFromGasSettings - Legacy", () => {
const { estimatedFee, maxFee } = getTotalFeesFromGasSettings(
{
type: 0,
gasPrice: baseFeePerGas.add(maxPriorityFeePerGas),
gasLimit: 22000,
type: "legacy",
gasPrice: baseFeePerGas + maxPriorityFeePerGas,
gas: 22000n,
},
21000,
21000n,
baseFeePerGas
)

const expectedEstimatedFee = ethers.utils.parseUnits("210000", "gwei").toString()
const expectedMaxFee = ethers.utils.parseUnits("220000", "gwei").toString()

expect(estimatedFee.toString()).toEqual(expectedEstimatedFee)
expect(maxFee.toString()).toEqual(expectedMaxFee)
expect(estimatedFee).toEqual(parseGwei("210000"))
expect(maxFee).toEqual(parseGwei("220000"))
})

test("getEthDerivationPath", () => {
Expand Down
155 changes: 53 additions & 102 deletions apps/extension/src/core/domains/ethereum/errors.ts
Original file line number Diff line number Diff line change
@@ -1,118 +1,69 @@
import { ethers } from "ethers"
import { log } from "@core/log"

export const getEthersErrorLabelFromCode = (code?: string | number) => {
if (typeof code === "string") {
switch (code) {
// operational errors
case ethers.errors.BUFFER_OVERRUN:
return "Buffer overrun"
case ethers.errors.NUMERIC_FAULT:
return "Numeric fault"

// argument errors
case ethers.errors.UNEXPECTED_ARGUMENT:
return "Too many arguments"
case ethers.errors.MISSING_ARGUMENT:
return "Missing argument"
case ethers.errors.INVALID_ARGUMENT:
return "Invalid argument"
case ethers.errors.MISSING_NEW:
return "Missing constructor"

// interactions errors
case ethers.errors.ACTION_REJECTED:
return "Action rejected"

// blockchain errors
case ethers.errors.CALL_EXCEPTION:
return "Contract method failed to execute"
case ethers.errors.INSUFFICIENT_FUNDS:
return "Insufficient balance"
case ethers.errors.NONCE_EXPIRED:
return "Nonce expired"
case ethers.errors.UNPREDICTABLE_GAS_LIMIT:
// TODO could be gas limit to low, parameters making the operation impossible, balance to low to pay for gas, or anything else that makes the operation impossible to succeed.
// TODO need a better copy to explain this, but gas limit issue has to be stated as it can be solved by the user.
return "Transaction may fail because of insufficient balance, incorrect parameters or may require higher gas limit"
case ethers.errors.TRANSACTION_REPLACED:
return "Transaction was replaced with another one with higher gas price"
case ethers.errors.REPLACEMENT_UNDERPRICED:
return "Replacement fee is too low, try again with higher gas price"

// generic errors
case ethers.errors.NETWORK_ERROR:
return "Network error"
case ethers.errors.UNSUPPORTED_OPERATION:
return "Unsupported operation"
case ethers.errors.NOT_IMPLEMENTED:
return "Not implemented"
case ethers.errors.TIMEOUT:
return "Timeout exceeded"
case ethers.errors.SERVER_ERROR:
return "Server error"
case ethers.errors.UNKNOWN_ERROR:
default:
return "Unknown error"
}
}
import { AnyEvmError } from "./types"

export const getErrorLabelFromCode = (code: number) => {
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1474.md
if (typeof code === "number") {
switch (code) {
case -32700:
return "Parse error. Invalid JSON was received by the server"
case -32600:
return "Invalid request, it could not be understood by the server"
case -32601:
return "Method does not exist"
case -32602:
return "Invalid method parameters"
case -32603:
return "Internal JSON-RPC error"
case -32000:
return "Missing or invalid parameters"
case -32001:
return "Requested resource not found"
case -32002:
return "Requested resource is not available"
case -32003:
return "Transaction rejected"
case -32004:
return "Method is not implemented"
case -32005:
return "Request exceeds defined limit"
case -32006:
return "Transaction not yet known"
default:
return "Unknown error"
switch (code) {
case -32700:
return "Parse error. Invalid JSON was received by the server"
case -32600:
return "Invalid request, it could not be understood by the server"
case -32601:
return "Method does not exist"
case -32602:
return "Invalid method parameters"
case -32603:
return "Internal JSON-RPC error"
case -32000:
return "Missing or invalid parameters"
case -32001:
return "Requested resource not found"
case -32002:
return "Requested resource is not available"
case -32003:
return "Transaction rejected"
case -32004:
return "Method is not implemented"
case -32005:
return "Request exceeds defined limit"
case -32006:
return "Transaction not yet known"
default: {
log.warn("Unknown error code", { code })
return "Unknown error"
}
}
}

return undefined
export const getEvmErrorCause = (err: unknown): AnyEvmError => {
const error = err as AnyEvmError
return error?.cause ? getEvmErrorCause(error.cause) : error
}

// turns errors into short and human readable message.
// main use case is teling the user why a transaction failed without going into details and clutter the UI
export const getHumanReadableErrorMessage = (error: unknown) => {
const {
code,
reason,
error: serverError,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} = error as { code?: string; reason?: string; error?: any }
if (!error) return undefined

if (serverError) {
const message = serverError.error?.message ?? serverError.reason ?? serverError.message
return message
.replace("VM Exception while processing transaction: reverted with reason string ", "")
.replace("VM Exception while processing transaction: revert", "")
.replace("VM Exception while processing transaction:", "")
.trim()
}
const { message, shortMessage, details, code } = error as AnyEvmError

if (details) return details

if (shortMessage) return shortMessage

if (reason === "processing response error") return "Invalid transaction"
if (code) return getErrorLabelFromCode(code)

if (reason) return reason
if (message) return message

return undefined
}

return getEthersErrorLabelFromCode(code)
export const cleanupEvmErrorMessage = (message: string) => {
if (!message) return "Unknown error"
return message
.replace("VM Exception while processing transaction: reverted with reason string ", "")
.replace("VM Exception while processing transaction: revert", "")
.replace("VM Exception while processing transaction:", "")
.trim()
}
Loading