wevm / viem Goto Github PK
View Code? Open in Web Editor NEWTypeScript Interface for Ethereum
Home Page: https://viem.sh
License: Other
TypeScript Interface for Ethereum
Home Page: https://viem.sh
License: Other
I'm now trying out different things to integrate Viem and Hardhat Network, and in particular how errors are shown.
This is how errors are currently shown when using a custom transport.
I think Internal Error
looks a bit overwhelming, and it's duplicating the cause
in the stack trace. Also, cause
lets each Error
customize how they are shown. cause
is available in Node 16+, which will mean all of the node versions in May.
^0.1.7
Type 'TopicFilter' is not assignable to type '[signature:
0x${string}
, ...args: LogTopic[]]'.
Source provides no match for required element at position 0 in target.ts(2322)
No type error
const logs = await client.getLogs();
logs.forEach((log) => {
const eventData = decodeEventLog({
abi: [],
data: log.data,
topics: log.topics,
});
});
https://stackblitz.com/edit/viem-getting-started-vqwqeb?file=index.ts
No response
0.1.9
the following script should either fails or alternatively be lenient about the log data passed in (it can for example attempt to parse the data field when the topics length do not matches the indexed arguments)
import { decodeEventLog } from "viem";
const abi = [
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "from",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "to",
type: "address",
},
{
indexed: true,
internalType: "uint256",
name: "id",
type: "uint256",
},
],
name: "Transfer",
type: "event",
},
];
const parsed = decodeEventLog({
abi,
data: "0x0000000000000000000000000000000000000000000000000000000023c34600",
topics: [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"0x00000000000000000000000070e8a65d014918798ba424110d5df658cde1cc58",
],
});
console.log(parsed);
The script above output the following
{
eventName: 'Transfer',
args: {
from: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
to: '0x70E8a65d014918798BA424110d5Df658cdE1cC58'
}
}
See missing third argument ?
decodeEventLog
expected to parse 3 indexed argument but did not fails when it only parsed 2 of them
Note this event comes form an ERC20 contract who do not have the amount as indexed param
The abi passed in the function is an ERC721 which expect all argument to be indexed.
The function should fails when not all indexed argument are found
Alternatively it could attempt to parse the non-present indexed arguments in the data field
import { decodeEventLog } from "viem";
const abi = [
{
anonymous: false,
inputs: [
{
indexed: true,
internalType: "address",
name: "from",
type: "address",
},
{
indexed: true,
internalType: "address",
name: "to",
type: "address",
},
{
indexed: true,
internalType: "uint256",
name: "id",
type: "uint256",
},
],
name: "Transfer",
type: "event",
},
];
const parsed = decodeEventLog({
abi,
data: "0x0000000000000000000000000000000000000000000000000000000023c34600",
topics: [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266",
"0x00000000000000000000000070e8a65d014918798ba424110d5df658cde1cc58",
],
});
console.log(parsed);
https://stackblitz.com/edit/viem-getting-started-oryrtm?file=index.ts
No response
0.1.1
It looks like encodeAbiParameters
doesn't encode certain emojis properly. I picked these: π¨βπ¨βπ¦βπ¦π΄ββ οΈ
to test because these emojis consist of multiple Unicode code points but I'm not sure what exactly triggers the issue.
All Unicode characters should be encoded properly.
Encode the string:
import { AbiCoder } from 'ethers';
import { encodeAbiParameters, parseAbiParameters } from 'viem';
const ethersCoder = new AbiCoder();
const types = ['string'];
const objects = ['π¨βπ¨βπ¦βπ¦π΄ββ οΈ'];
const ethersResult = ethersCoder.encode(types, objects);
console.log(ethersResult);
// 0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000026f09f91a8e2808df09f91a8e2808df09f91a6e2808df09f91a6f09f8fb4e2808de298a0efb88f0000000000000000000000000000000000000000000000000000
const viemResult = encodeAbiParameters(parseAbiParameters(types), objects);
console.log(viemResult);
// 0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010d83ddc68200dd83ddc68200dd83ddc66200dd83ddc66d83cdff4200d2620fe0f
Then check it in the web browser DevTools console:
function decodeUTF8(hex) {
return new TextDecoder().decode(Uint8Array.from(hex.substring(2).match(/.{2}/g), v => parseInt(v, 16)));
}
// From ethersResult
decodeUTF8('26f09f91a8e2808df09f91a8e2808df09f91a6e2808df09f91a6f09f8fb4e2808de298a0efb88f');
// 'π¨βπ¨βπ¦βπ¦π΄ββ οΈ'
// From viemResult
decodeUTF8('10d83ddc68200dd83ddc68200dd83ddc66200dd83ddc66d83cdff4200d2620fe0f');
// 'οΏ½=οΏ½h \rοΏ½=οΏ½h \rοΏ½=οΏ½f \rοΏ½=οΏ½fοΏ½<οΏ½οΏ½ \r& οΏ½\x0F'
https://github.com/ardislu/eth-abi-coder-comparison
No response
0.3.0
When I'm trying to use a Velas RPC to get the balance of an account, it throws the following error:
Cannot convert undefined to a BigInt
For what I could see, the RPC call returns undefined
. Then, the client tries to convert to BigInt, which causes the error. The weird thing is that Ethers works fine with the same RPC:
/// This doesn't fail, and returns a valid amount
const balance = await new JsonRpcProvider('https://evmexplorer.velas.com/rpc')
.getBalance('0x000000000000000000000000000000000000dead')
getBalance
should not revert and it would return the actual balance
const balance = await createPublicClient({ transport: http('https://evmexplorer.velas.com/rpc') })
.getBalance({ address: '0x000000000000000000000000000000000000dead' })
No response
No response
In this commit: https://github.com/roninjin10/viem/commit/6e10cebb473b24f9bec637f013807e6fcd98b40e
I make watchBlocks more typesafe.
includeTransaction will include transactions
Not passing in includeTransaction will not include transactions
0.1.16
When trying to follow this ethers -> viem migration example, I run into a type error for getAccount:
Argument of type 'Wallet' is not assignable to parameter of type 'EthersWallet'.
Property 'signTypedData' is missing in type 'Wallet' but required in type 'EthersWallet'.
'EthersWallet' should fit the properties of type 'Wallet'.
import { getAccount } from 'viem/ethers';
import { goerli } from 'viem/chains'
import { Wallet } from 'ethers';
import "dotenv/config"
const client = createPublicClient({
chain: goerli,
transport: http('"https://eth-goerli.g.alchemy.com/v2/[API_KEY]"')
})
const account = getAccount(new Wallet(process.env.KEY as string))```
### Link to Minimal Reproducible Example (StackBlitz, CodeSandbox, GitHub repo etc.)
_No response_
### Anything else?
_No response_
I'm getting this error when trying to install viem:
pato@lucille:v% npm i viem@alpha
npm ERR! code 1
npm ERR! path /private/tmp/v/node_modules/viem
npm ERR! command failed
npm ERR! command sh -c /var/folders/h5/ttj4pqs548n1mqqfw6t5n8080000gn/T/postinstall675277696774.sh
npm ERR! WARNβ Unsupported engine: wanted: {"node":">=18"} (current: {"node":"v16.15.0","pnpm":"7.1.9"})
npm ERR!
npm ERR! > [email protected] dev /private/tmp/v/node_modules/viem
npm ERR! > DEV=true tsup
npm ERR!
npm ERR! βELIFECYCLEβ Command failed.
npm ERR! βWARNβ Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! sh: tsup: command not found
npm ERR! A complete log of this run can be found in:
npm ERR! /Users/pato/.npm/_logs/2023-02-01T18_54_55_356Z-debug-0.log
Info about my system:
pato@lucille:v% pnpm --version
7.1.9
pato@lucille:v% npm --version
8.13.2
pato@lucille:v% node --version
v18.13.0
Workaround:
npm i --ignore-scripts viem@alpha
A list of stuff that needs to be done before public release.
createClient
: Base ClientcreatePublicClient
: Public ClientcreateWalletClient
: Wallet ClientcreateTestClient
: Test Clienthttp
: HTTPwebSocket
: WebSocketcustom
: Custom EIP-1193fallback
: Fallback
ipc
: IPCtimeout
config optionretryCount
config optiongetBalance
getTransactionCount
getBlock
getBlockNumber
getBlockTransactionCount
watchBlockNumber
eth_subscribe
+ watchHeads
watchBlocks
eth_subscribe
+ watchHeads
getChainId
estimateGas
getFeeHistory
getGasPrice
watchGasPrice
createBlockFilter
createEventFilter
args
createPendingTransactionFilter
getFilterChanges
getFilterLogs
getLogs
@0xOliaswatchEvents
fromBlock
eth_newFilter
eth_subscribe
+ logs
uninstallFilter
call
getTransaction
getTransactionConfirmations
getTransactionReceipt
sendRawTransaction
waitForTransactionReceipt
watchPendingTransactions
full
arg w/ getTransaction
eth_subscribe
+ newPendingTransactions
getAccounts
requestAccounts
watchAsset
addChain
switchChain
signMessage
signTypedData
@jxomgetPermissions
requestPermissions
sendTransaction
signTransaction
impersonateAccount
setBalance
setCode
setNonce
setStorageAt
stopImpersonatingAccount
getAutomine
increaseTime
mine
removeBlockTimestampInterval
setAutomine
setIntervalMining
setBlockTimestampInterval
setBlockGasLimit
setNextBlockBaseFeePerGas
setNextBlockTimestamp
setCoinbase
setMinGasPrice
reset
setLoggingEnabled
setRpcUrl
revert
snapshot
dropTransaction
getTxpoolContent
getTxpoolStatus
inspectTxpool
sendUnsignedTransaction
fallback()
& receive()
function supportdeployContract
createContractEventFilter
estimateContractGas
getBytecode
getStorageAt
multicall
readContract
simulateContract
writeContract
watchContractEvents
topics
decodeDeployData
decodeErrorResult
decodeEventTopics
decodeFunctionData
decodeFunctionResult
encodeDeployData
encodeErrorResult
encodeEventTopics
encodeFunctionData
encodeFunctionResult
decodeAbiParameters
encodeAbiParameters
getAbiItem
parseAbi
& ParseAbi
(human readable -> json) @tmmparseAbiItem
& ParseAbiItem
@tmm
parseAbiParameter
& ParseAbiParameter
@tmmparseAbiParameters
& ParseAbiParameters
@tmmgetAddress
getContractAddress
isAddress
isAddressEqual
concat
isBytes
isHex
pad
slice
size
trim
fromBase58
fromBase64
fromBytes
fromHex
fromRlp
toBase58
toBase64
toBytes
toHex
toPacked
toRlp
getEventSignature
getFunctionSignature
keccak256
formatEther
formatGwei
formatUnit
parseEther
parseGwei
parseUnit
verifyMessage
verifyTypedData
encodeAbi
/decodeAbi
"Usage" snippets with a "real life" oneencodeAbi
, encodeFunctionData
etc)readContract
uses encodeFunctionData
and decodeFunctionResult
.window.ethereum
, WalletConnect v2, Coinbase SDK)fetch
)viem/public
viem/wallet
viem/test
viem/utils
0.1.6
Event logs returned by viem have a topics property typed like this:
type TopicFilter = (null | string | string[])[]
type Log = {
/** List of order-dependent topics */
topics: TopicFilter
}
While the topics
property of the filter argument to RPC methods like eth_getLogs
and eth_newFilter
can contain elements that are an array of strings or null, I'm fairly certain that the topics
property for any given Log
object returned by these RPC methods will only ever contain strings (Solidity docs reference).
type Topics = string[]
type Log = {
/** List of order-dependent topics */
topics: Topics
}
It may be possible to narrow the type further like this:
type Hex = `0x${string}`
type Topics = [Hex, Hex | undefined, Hex | undefined, Hex | undefined]
but I'm not certain that the first topic must be defined (can an anonymous event have 0 indexed arguments?).
No response
No response
No response
0.2.9
Given the following events:
[
{
address: '0xa6efae0c9293b4ee340de31022900ba747eaa92d',
topics: [
'0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f',
'0x0000000000000000000000003e48298a5fe88e4d62985dff65dee39a25914975'
],
data: '0x0000000000000000000000000000000000000000000000001c07b57c93e04da9000000000000000000000000000000000000000000000000000000000072b4a7',
blockNumber: '0x4a1d17a',
transactionHash: '0xff5a6fa427e1fdc7bec5a453f266cdd7c1bddc66492199548419e0172d07bcc5',
transactionIndex: '0x1',
blockHash: '0x4319ea349a8c82015e8e4b62202d0a7c3349f83a95dfcc3924acf930ca4d0d7d',
logIndex: '0x12',
removed: false
},
{
address: '0xa6efae0c9293b4ee340de31022900ba747eaa92d',
topics: [
'0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f',
'0x0000000000000000000000003e48298a5fe88e4d62985dff65dee39a25914975'
],
data: '0x0000000000000000000000000000000000000000000000000040ba631dd532ce00000000000000000000000000000000000000000000000000000000000108e1',
blockNumber: '0x4a1d17a',
transactionHash: '0xff5a6fa427e1fdc7bec5a453f266cdd7c1bddc66492199548419e0172d07bcc5',
transactionIndex: '0x1',
blockHash: '0x4319ea349a8c82015e8e4b62202d0a7c3349f83a95dfcc3924acf930ca4d0d7d',
logIndex: '0x2c',
removed: false
},
{
address: '0xd5e31fc5f4a009a49312c20742df187b35975528',
topics: [
'0x4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f',
'0x000000000000000000000000e8b67ebf4825fec2ab6c010a01064f5fa54672a5',
'0x0000000000000000000000000000000000000000000000000000000000000195'
],
data: '0x0000000000000000000000000000000000000000000000003a3a7bb04ddfa000',
blockNumber: '0x4a1d188',
transactionHash: '0x60ac417de5d876ddf121d37476e62e46675cae81d724a34f3f76d64d9bb62fc6',
transactionIndex: '0x5',
blockHash: '0xbbf0b40bc00c8e0979a2348ba5e37623db192f03731eb831d166cf757a1a95ed',
logIndex: '0x14',
removed: false
}
]
The following getLogs
will raise an exception:
// Arbitrum Chain
const mintLogs = await rpc.getLogs({
event: {
type: "event",
name: "Mint",
inputs: [
{ type: "address", indexed: true, name: "sender" },
{ type: "uint256", indexed: false, name: "amount0" },
{ type: "uint256", indexed: false, name: "amount1" },
],
},
fromBlock: 77713750n,
toBlock: 77713811n,
});
viem should not raise an exception and returns the first two logs
To get the content of the logs:
const fromBlock = 77713750n;
const toBlock = 77713811n;
const selector = getEventSelector("Mint(address,uint256,uint256)");
console.log("DEBUG: selector", selector);
const result = await fetch(
"ARBITRUM_RPC",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
method: "eth_getLogs",
params: [
{
fromBlock: numberToHex(fromBlock),
toBlock: numberToHex(toBlock),
topics: [selector],
},
],
id: 1,
jsonrpc: "2.0",
}),
}
);
const data = await result.json();
to get the exception:
import { createPublicClient, http } from 'viem';
import { arbitrum } from 'viem/chains';
const client = createPublicClient({
chain: arbitrum,
transport: http(),
});
const mintLogs = await client.getLogs({
event: {
type: 'event',
name: 'Mint',
inputs: [
{ type: 'address', indexed: true, name: 'sender' },
{ type: 'uint256', indexed: false, name: 'amount0' },
{ type: 'uint256', indexed: false, name: 'amount1' },
],
},
fromBlock: 77713750n,
toBlock: 77713811n,
});
console.log('DEBUG: mintLogs', mintLogs);
export default `Block number: ${blockNumber}`;
https://stackblitz.com/edit/viem-getting-started-fpo973?file=index.ts
No response
0.1.6
For a specific abi and event log, decodeEventLog
throws:
Slice starting at offset "192" is out-of-bounds (size: 192).
at assertStartOffset (/Users/olias/workspace/ponder/node_modules/.pnpm/[email protected]_p5jgycp7euppyerdfacwyih2x4/node_modules/viem/dist/chunk-6CICSWSU.js:1536:11)
at sliceHex (/Users/olias/workspace/ponder/node_modules/.pnpm/[email protected]_p5jgycp7euppyerdfacwyih2x4/node_modules/viem/dist/chunk-6CICSWSU.js:1547:3)
at slice (/Users/olias/workspace/ponder/node_modules/.pnpm/[email protected]_p5jgycp7euppyerdfacwyih2x4/node_modules/viem/dist/chunk-6CICSWSU.js:1531:12)
at decodeString (/Users/olias/workspace/ponder/node_modules/.pnpm/[email protected]_p5jgycp7euppyerdfacwyih2x4/node_modules/viem/dist/chunk-6CICSWSU.js:2296:10)
at decodeParam (/Users/olias/workspace/ponder/node_modules/.pnpm/[email protected]_p5jgycp7euppyerdfacwyih2x4/node_modules/viem/dist/chunk-6CICSWSU.js:2194:12)
at decodeParams (/Users/olias/workspace/ponder/node_modules/.pnpm/[email protected]_p5jgycp7euppyerdfacwyih2x4/node_modules/viem/dist/chunk-6CICSWSU.js:2170:33)
at decodeAbiParameters (/Users/olias/workspace/ponder/node_modules/.pnpm/[email protected]_p5jgycp7euppyerdfacwyih2x4/node_modules/viem/dist/chunk-6CICSWSU.js:2157:10)
at decodeEventLog (/Users/olias/workspace/ponder/node_modules/.pnpm/[email protected]_p5jgycp7euppyerdfacwyih2x4/node_modules/viem/dist/chunk-6CICSWSU.js:2422:25)
Event log should be successfully decoded
See stackblitz link for full explanation / repro
https://stackblitz.com/edit/viem-getting-started-cdbsys?file=index.ts
No response
0.1.7
Hey guys loving viem so far! π
I have written a pretty basic setup to watch pending transactions in the mempool.
client.watchPendingTransactions({
onTransactions: async (tx) => {
tx.forEach( async (hash) => {
try {
console.log(await client.getTransaction({ hash: hash}))
} catch (e) {
console.log(e);
}
});
},
batch: true,
pollingInterval: 2,
onError: error => console.error(error)
});
I have noticed there are many hashes being provided that have been hanging in the mempool for +hours and throws an error when I try to get transaction details.
Here is the error:
TransactionNotFoundError: Transaction with hash "0xb8ff910f624155d4d3fa01200749db478b331ba8457db1715b2a0263062ce889" could not be found.
Version: [email protected]
at getTransaction (/Users/sku/Documents/Coding/viem/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/dist/chunk-CVKYFX2W.js:3945:11)
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
details: undefined,
docsPath: undefined,
metaMessages: undefined,
shortMessage: 'Transaction with hash "0xb8ff910f624155d4d3fa01200749db478b331ba8457db1715b2a0263062ce889" could not be found.'
}
This one for example has been hanging for 3 days at the time of writing this:
https://etherscan.io/tx/0xb8ff910f624155d4d3fa01200749db478b331ba8457db1715b2a0263062ce889
Would be great to provide solely pending transactions entering the mempool.
Create a client and simply try to pull transaction details using getTransaction
, there are many that will pop up.
No response
No response
0.2.12
The code does not compile because of a type error.
The code should compile and return a contract instance.
Code snippet to reproduce the bug :
import { createPublicClient, webSocket, getContract} from "viem";
import { mainnet } from 'viem/chains'
import { univ3PoolAbi } from './pool-abi';
const client = createPublicClient({
chain: mainnet,
transport: webSocket(),
});
const contract = getContract({
address: '0x61fFE014bA17989E743c5F6cB21bF9697530B21e',
abi: univ3PoolAbi,
publicClient: client
})
The abi to put in a file called pool-abi.ts
:
export const univ3PoolAbi = [{ "inputs": [], "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "int24", "name": "tickLower", "type": "int24" }, { "indexed": true, "internalType": "int24", "name": "tickUpper", "type": "int24" }, { "indexed": false, "internalType": "uint128", "name": "amount", "type": "uint128" }, { "indexed": false, "internalType": "uint256", "name": "amount0", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "amount1", "type": "uint256" }], "name": "Burn", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": false, "internalType": "address", "name": "recipient", "type": "address" }, { "indexed": true, "internalType": "int24", "name": "tickLower", "type": "int24" }, { "indexed": true, "internalType": "int24", "name": "tickUpper", "type": "int24" }, { "indexed": false, "internalType": "uint128", "name": "amount0", "type": "uint128" }, { "indexed": false, "internalType": "uint128", "name": "amount1", "type": "uint128" }], "name": "Collect", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, { "indexed": true, "internalType": "address", "name": "recipient", "type": "address" }, { "indexed": false, "internalType": "uint128", "name": "amount0", "type": "uint128" }, { "indexed": false, "internalType": "uint128", "name": "amount1", "type": "uint128" }], "name": "CollectProtocol", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, { "indexed": true, "internalType": "address", "name": "recipient", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount0", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "amount1", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "paid0", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "paid1", "type": "uint256" }], "name": "Flash", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint16", "name": "observationCardinalityNextOld", "type": "uint16" }, { "indexed": false, "internalType": "uint16", "name": "observationCardinalityNextNew", "type": "uint16" }], "name": "IncreaseObservationCardinalityNext", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" }, { "indexed": false, "internalType": "int24", "name": "tick", "type": "int24" }], "name": "Initialize", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "address", "name": "sender", "type": "address" }, { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "int24", "name": "tickLower", "type": "int24" }, { "indexed": true, "internalType": "int24", "name": "tickUpper", "type": "int24" }, { "indexed": false, "internalType": "uint128", "name": "amount", "type": "uint128" }, { "indexed": false, "internalType": "uint256", "name": "amount0", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "amount1", "type": "uint256" }], "name": "Mint", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": false, "internalType": "uint8", "name": "feeProtocol0Old", "type": "uint8" }, { "indexed": false, "internalType": "uint8", "name": "feeProtocol1Old", "type": "uint8" }, { "indexed": false, "internalType": "uint8", "name": "feeProtocol0New", "type": "uint8" }, { "indexed": false, "internalType": "uint8", "name": "feeProtocol1New", "type": "uint8" }], "name": "SetFeeProtocol", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "sender", "type": "address" }, { "indexed": true, "internalType": "address", "name": "recipient", "type": "address" }, { "indexed": false, "internalType": "int256", "name": "amount0", "type": "int256" }, { "indexed": false, "internalType": "int256", "name": "amount1", "type": "int256" }, { "indexed": false, "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" }, { "indexed": false, "internalType": "uint128", "name": "liquidity", "type": "uint128" }, { "indexed": false, "internalType": "int24", "name": "tick", "type": "int24" }], "name": "Swap", "type": "event" }, { "inputs": [{ "internalType": "int24", "name": "tickLower", "type": "int24" }, { "internalType": "int24", "name": "tickUpper", "type": "int24" }, { "internalType": "uint128", "name": "amount", "type": "uint128" }], "name": "burn", "outputs": [{ "internalType": "uint256", "name": "amount0", "type": "uint256" }, { "internalType": "uint256", "name": "amount1", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "int24", "name": "tickLower", "type": "int24" }, { "internalType": "int24", "name": "tickUpper", "type": "int24" }, { "internalType": "uint128", "name": "amount0Requested", "type": "uint128" }, { "internalType": "uint128", "name": "amount1Requested", "type": "uint128" }], "name": "collect", "outputs": [{ "internalType": "uint128", "name": "amount0", "type": "uint128" }, { "internalType": "uint128", "name": "amount1", "type": "uint128" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint128", "name": "amount0Requested", "type": "uint128" }, { "internalType": "uint128", "name": "amount1Requested", "type": "uint128" }], "name": "collectProtocol", "outputs": [{ "internalType": "uint128", "name": "amount0", "type": "uint128" }, { "internalType": "uint128", "name": "amount1", "type": "uint128" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "factory", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "fee", "outputs": [{ "internalType": "uint24", "name": "", "type": "uint24" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "feeGrowthGlobal0X128", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "feeGrowthGlobal1X128", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount0", "type": "uint256" }, { "internalType": "uint256", "name": "amount1", "type": "uint256" }, { "internalType": "bytes", "name": "data", "type": "bytes" }], "name": "flash", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint16", "name": "observationCardinalityNext", "type": "uint16" }], "name": "increaseObservationCardinalityNext", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" }], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "liquidity", "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "maxLiquidityPerTick", "outputs": [{ "internalType": "uint128", "name": "", "type": "uint128" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "int24", "name": "tickLower", "type": "int24" }, { "internalType": "int24", "name": "tickUpper", "type": "int24" }, { "internalType": "uint128", "name": "amount", "type": "uint128" }, { "internalType": "bytes", "name": "data", "type": "bytes" }], "name": "mint", "outputs": [{ "internalType": "uint256", "name": "amount0", "type": "uint256" }, { "internalType": "uint256", "name": "amount1", "type": "uint256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "name": "observations", "outputs": [{ "internalType": "uint32", "name": "blockTimestamp", "type": "uint32" }, { "internalType": "int56", "name": "tickCumulative", "type": "int56" }, { "internalType": "uint160", "name": "secondsPerLiquidityCumulativeX128", "type": "uint160" }, { "internalType": "bool", "name": "initialized", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint32[]", "name": "secondsAgos", "type": "uint32[]" }], "name": "observe", "outputs": [{ "internalType": "int56[]", "name": "tickCumulatives", "type": "int56[]" }, { "internalType": "uint160[]", "name": "secondsPerLiquidityCumulativeX128s", "type": "uint160[]" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], "name": "positions", "outputs": [{ "internalType": "uint128", "name": "liquidity", "type": "uint128" }, { "internalType": "uint256", "name": "feeGrowthInside0LastX128", "type": "uint256" }, { "internalType": "uint256", "name": "feeGrowthInside1LastX128", "type": "uint256" }, { "internalType": "uint128", "name": "tokensOwed0", "type": "uint128" }, { "internalType": "uint128", "name": "tokensOwed1", "type": "uint128" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "protocolFees", "outputs": [{ "internalType": "uint128", "name": "token0", "type": "uint128" }, { "internalType": "uint128", "name": "token1", "type": "uint128" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "uint8", "name": "feeProtocol0", "type": "uint8" }, { "internalType": "uint8", "name": "feeProtocol1", "type": "uint8" }], "name": "setFeeProtocol", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "slot0", "outputs": [{ "internalType": "uint160", "name": "sqrtPriceX96", "type": "uint160" }, { "internalType": "int24", "name": "tick", "type": "int24" }, { "internalType": "uint16", "name": "observationIndex", "type": "uint16" }, { "internalType": "uint16", "name": "observationCardinality", "type": "uint16" }, { "internalType": "uint16", "name": "observationCardinalityNext", "type": "uint16" }, { "internalType": "uint8", "name": "feeProtocol", "type": "uint8" }, { "internalType": "bool", "name": "unlocked", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "int24", "name": "tickLower", "type": "int24" }, { "internalType": "int24", "name": "tickUpper", "type": "int24" }], "name": "snapshotCumulativesInside", "outputs": [{ "internalType": "int56", "name": "tickCumulativeInside", "type": "int56" }, { "internalType": "uint160", "name": "secondsPerLiquidityInsideX128", "type": "uint160" }, { "internalType": "uint32", "name": "secondsInside", "type": "uint32" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "bool", "name": "zeroForOne", "type": "bool" }, { "internalType": "int256", "name": "amountSpecified", "type": "int256" }, { "internalType": "uint160", "name": "sqrtPriceLimitX96", "type": "uint160" }, { "internalType": "bytes", "name": "data", "type": "bytes" }], "name": "swap", "outputs": [{ "internalType": "int256", "name": "amount0", "type": "int256" }, { "internalType": "int256", "name": "amount1", "type": "int256" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "int16", "name": "", "type": "int16" }], "name": "tickBitmap", "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "tickSpacing", "outputs": [{ "internalType": "int24", "name": "", "type": "int24" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "int24", "name": "", "type": "int24" }], "name": "ticks", "outputs": [{ "internalType": "uint128", "name": "liquidityGross", "type": "uint128" }, { "internalType": "int128", "name": "liquidityNet", "type": "int128" }, { "internalType": "uint256", "name": "feeGrowthOutside0X128", "type": "uint256" }, { "internalType": "uint256", "name": "feeGrowthOutside1X128", "type": "uint256" }, { "internalType": "int56", "name": "tickCumulativeOutside", "type": "int56" }, { "internalType": "uint160", "name": "secondsPerLiquidityOutsideX128", "type": "uint160" }, { "internalType": "uint32", "name": "secondsOutside", "type": "uint32" }, { "internalType": "bool", "name": "initialized", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "token0", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "token1", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }]
No response
No response
0.2.7
When using viem with react and typescript, i get a type error when creating a WalletClient with const walletClient = createWalletClient({ chain: mainnet, transport: custom(window.ethereum) })
Argument of type 'WindowProvider | undefined' is not assignable to parameter of type 'EthereumProvider'.`
This might be related to an issue i saw here https://github.com/wagmi-dev/viem/issues/244 about type inference
No type error when creating a Wallet Client
No response
No response
No response
0.1.1
parseAbiParameters
doesn't seem to accept the tuple
keyword. Example:
import { encodeAbiParameters, parseAbiParameters } from 'viem';
const types = ['tuple(uint256, uint256)'];
const objects = [[1, 2]];
encodeAbiParameters(parseAbiParameters(types), objects);
// BaseError [AbiTypeError]: Invalid ABI parameter.
It should accept the tuple
keyword, like how ethers
does:
import { AbiCoder } from 'ethers';
const ethersCoder = new AbiCoder();
const types = ['tuple(uint256, uint256)'];
const objects = [[1, 2]];
const ethersResult = ethersCoder.encode(types, objects);
console.log(ethersResult);
// 0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002
I'm not sure how commonly used this syntax is though. I saw it from this blog post: https://blog.ricmoo.com/human-readable-contract-abis-in-ethers-js-141902f4d917
Full combined example code:
import { AbiCoder } from 'ethers';
import { encodeAbiParameters, parseAbiParameters } from 'viem';
const ethersCoder = new AbiCoder();
const types = ['tuple(uint256, uint256)'];
// Workaround: omit the 'tuple' keyword:
// const types = ['(uint256, uint256)'];
const objects = [[1, 2]];
const ethersResult = ethersCoder.encode(types, objects);
console.log(ethersResult);
// 0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002
const viemResult = encodeAbiParameters(parseAbiParameters(types), objects);
console.log(viemResult);
// BaseError [AbiTypeError]: Invalid ABI parameter.
https://github.com/ardislu/eth-abi-coder-comparison
As a workaround, you can simply omit the tuple
keyword:
import { encodeAbiParameters, parseAbiParameters } from 'viem';
// Workaround: omit the 'tuple' keyword:
const types = ['(uint256, uint256)'];
const objects = [[1, 2]];
encodeAbiParameters(parseAbiParameters(types), objects);
// 0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002
0.1.12
https://viem.sh/docs/utilities/concat.html
(It'd be nice if all concat modules were exported.)
No response
No response
No response
0.1.1
Transaction objects returned by public client methods like getBlock
and getTransaction
do not always match their type. Specifically, Transaction["to"]
is sometimes undefined (for contract creation transactions) despite being typed as Address | null
.
Verified on Alchemy (explorer response here), unsure about other RPC providers.
Objects returned by public client methods should always match their type. Ideas:
to?: Address | null
)null
(prefer this!)const transaction = await publicClient.getTransation({
hash: "0x96d2d92c7d3e87c6cdbdcafa2836e6b936426d0828ed2b569baac440fbc48cbf",
})
console.log(transaction.to === undefined)
No response
No response
when using encodeAbi()
, bytes params are limited to 64 bytes.
pretty sure this is because padHex()
has a default size value of 32, and in encodeBytes()
the size of the dynamic byte array isn't precalculated.
0.1.6
decodeEventLog
throws this error if passed an ABI that contains a constructor:
InvalidDefinitionTypeError: "constructor" is not a valid definition type.
Valid types: "function", "event", "error"
Should not throw. The constructor should be irrelevant to decoding the log, so it shouldn't matter whether or not the provided ABI contains an item for the constructor.
This would likely repro.
decodeEventLog({
abi: [
{
inputs: [],
stateMutability: 'nonpayable',
type: 'constructor'
}
],
data: "0x",
topics: ["0x"]
})
No response
No response
0.3.2
When using a newly created privateKey with funds directly sent to it using a faucet, I'm unable to send any transaction due to the following error:
Request Arguments:
from: [...]
to: 0xD8Ea779b8FFC1096CA422D40588C4c0641709890
value: 0.001 ETH
Details: rlp: non-canonical integer (leading zero bytes) for uint64, decoding into (types.DynamicFeeTx).Nonce
Version: [email protected]
Tested only polygon mumbai
We should be able to send a transaction to the chain even if it's the wallet first transaction
https://stackblitz.com/edit/viem-getting-started-xatmau?file=index.ts
Forcing the transaction to have a different nonce will result in successfully retrieving a hash. The transaction will never make it to the blockchain as it's awaiting a transaction with a 0
as nonce value first if I'm right.
Thank you for the great library !
0.1.17
I instantiated a publicClient
according to the docs:
import {createPublicClient, http} from "viem";
import {avalanche} from "viem/chains";
const transport = http("https://api.avax.network/ext/bc/C/rpc");
const publicClient = createPublicClient({
chain: avalanche,
transport,
});
When running the command next build
, the following error is thrown:
Failed to compile.
./node_modules/viem/dist/createPublicClient-0021fc35.d.ts:408:328
Type error: '?' expected.
406 | functionName: TFunctionName;
407 | };
> 408 | type MulticallContracts<TContracts extends Contract[], TProperties extends Record<string, any> = object, Result extends any[] = [], Depth extends ReadonlyArray<number> = []> = Depth['length'] extends MAXIMUM_DEPTH ? (ContractConfig & TProperties)[] : TContracts extends [] ? [] : TContracts extends [infer Head extends Contract] ? [
| ^
409 | ...Result,
410 | ContractConfig<Head['abi'], Head['functionName']> & TProperties
411 | ] : TContracts extends [
It seems to believe that the ?
ternary operator after [infer Head extends Contract]
does not exist, or that another ?
is needed. The amount of nested ternaries in the type makes it quite hard for me to parse, so I'm unable to identify if this is a false positive.
I expected no compilation errors when using createPublicClient
.
Relevant Env:
"engines": {
"node": ">=16.10.0",
"npm": ">=7.24.0"
},
"dependencies": {
"next": "12.1.0",
"typescript": "4.6.2",
"viem": "0.1.17",
}
publicClient
instance as specified abovenext build
Thank you π
No response
No response
0.2.0
I was super excited to see mnemonicToAccount
implemented, but it seems like its not being exported? I wish my Typescript was better Id love to make a PR!
No response
No response
No response
No response
0.3.16
The public RPC for Metis Goerli chain doesn't expect a second argument in eth_estimateGas
calls, resulting in estimates failing with a too many arguments, want at most 1
error.
The single-argument eth_estimateGas
is conforming to the older Ethereum JSON-RPC specs.
Contract gas estimates should work
Do an estimate on https://goerli.gateway.metisdevops.link RPC
https://stackblitz.com/edit/viem-getting-started-nteohf?file=index.ts
No response
0.3.1
tsc --noEmit
fails with:
$ tsc --noEmit
Error: node_modules/viem/src/clients/transports/webSocket.ts(1,15): error TS2595: 'WebSocket' can only be imported by using a default import.
Error: node_modules/viem/src/clients/transports/webSocket.ts(1,32): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.
Error: node_modules/viem/src/utils/rpc.ts(2,15): error TS2305: Module '"isomorphic-ws"' has no exported member 'MessageEvent'.
Error: node_modules/viem/src/utils/rpc.ts(2,35): error TS2497: This module can only be referenced with ECMAScript imports/exports by turning on the 'allowSyntheticDefaultImports' flag and referencing its default export.
No response
No response
https://github.com/iron-wallet/iron/actions/runs/4687550919/jobs/8306987577
No response
I just noticed that I need Node >= 18 to use viem. Was this intentionally chosen?
I think it would be ideal if viem supported the currently maintained Node.js version, as that means easier adoption. We do that with hardhat, and quickly drop support after their EOL.
viem can't be used in a CJS module. I'd say that this is important for its adoption, as it's the default on node.
If you try to do it you get this error:
pato@lucille:v% node -e 'require("viem")'
node:internal/modules/cjs/loader:1269
throw err;
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /private/tmp/v/node_modules/viem/dist/index.js from /private/tmp/v/[eval] not supported.
Instead change the require of index.js in /private/tmp/v/[eval] to a dynamic import() which is available in all CommonJS modules.
at [eval]:1:1
at Script.runInThisContext (node:vm:129:12)
at Object.runInThisContext (node:vm:307:38)
at [eval]-wrapper:6:22 {
code: 'ERR_REQUIRE_ESM'
}
Node.js v18.13.0
I think ideally viem should use package.json#exports
to support both ESM and CJS.
0.2.4
File: ./src/index.ts
// Imports
// ========================================================
import { privateKeyToAccount } from 'viem/accounts';
// Config
// ========================================================
dotenv.config();
const account = privateKeyToAccount(`0x${process.env.WALLET_PRIVATE_KEY}`);
console.log({ address: account.address });
# FROM ./
./node_modules/.bin/ts-node src/index.ts;
# Output:
# /Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/accounts/wordlists/czech.ts:2
# export const czech = pkg.wordlist
# ^
# TypeError: Cannot read properties of undefined (reading 'wordlist')
# at Object.<anonymous> # (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/accounts/wordlists/czech.ts:2:26)
# at Module._compile (node:internal/modules/cjs/loader:1254:14)
# at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
# at Object.require.extensions.<computed> [as .js] (/Users/username/path/to/node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/ts-node/src/index.ts:1608:43)
# at Module.load (node:internal/modules/cjs/loader:1117:32)
# at Function.Module._load (node:internal/modules/cjs/loader:958:12)
# at Module.require (node:internal/modules/cjs/loader:1141:19)
# at require (node:internal/modules/cjs/helpers:110:18)
# at Object.<anonymous> (/Users/username/path/to/src/index.ts:5:1)
# at Module._compile (node:internal/modules/cjs/loader:1254:14)
# βELIFECYCLEβ Command failed with exit code 1.
Return the wallet address from the private key
Code & steps provided in current behavior
No response
No response
0.2.5
File: ./src/index.ts
// Imports
// ========================================================
import { privateKeyToAccount } from 'viem/accounts';
import { http, createWalletClient } from 'viem';
import { polygonZkEvmTestnet } from 'viem/chains';
// Config
// ========================================================
dotenv.config();
const account = privateKeyToAccount(`0x${process.env.WALLET_PRIVATE_KEY}`);
console.log({ address: account.address });
const walletClient = createWalletClient({
account,
chain: polygonZkEvmTestnet,
transport: http(),
});
# FROM ./
./node_modules/.bin/ts-node src/index.ts;
# Output:
# { address: '0xSomeWalletAddress' }
# /Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/clients/createWalletClient.ts:73
# transport: () => transport({ retryCount: 0 }),
# ^
# UrlRequiredError [ViemError]: No URL was provided to the Transport. Please provide a valid RPC URL to the Transport.
#
# Docs: https://viem.sh/docs/clients/intro.html
# Version: [email protected]
# at /Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/clients/transports/http.ts:50:22
# at transport (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/clients/createWalletClient.ts:73:24)
# at createClient (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/clients/createClient.ts:65:38)
# at createWalletClient (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/clients/createWalletClient.ts:68:8)
# at Object.<anonymous> (/Users/username/path/to/src/index.ts:20:40)
# at Module._compile (node:internal/modules/cjs/loader:1254:14)
# at Module.m._compile (/Users/username/path/to/node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/ts-node/src/index.ts:1618:23)
# at Module._extensions..js (node:internal/modules/cjs/loader:1308:10)
# at Object.require.extensions.<computed> [as .ts] (/Users/username/path/to/node_modules/.pnpm/[email protected]_@[email protected][email protected]/node_modules/ts-node/src/index.ts:1621:12)
# at Module.load (node:internal/modules/cjs/loader:1117:32) {
# details: undefined,
# docsPath: '/docs/clients/intro',
# metaMessages: undefined,
# shortMessage: 'No URL was provided to the Transport. Please provide a valid RPC URL to the Transport.'
# }
# βELIFECYCLEβ Command failed with exit code 1.
No error and that it would take the default rpc url from:
const walletClient = createWalletClient({
account,
chain: polygonZkEvmTestnet,
transport: http(polygonZkEvmTestnet.rpcUrls.default.http[0]),
});
See current behavior section
No response
No response
0.2.0
pnpm anvil
works everywhere
pnpm anvil
fails in shells like fish
I think it'd be good to replace the source
command there with sth. like dotenv-cli
(https://www.npmjs.com/package/dotenv-cli) to make it work seemlessly with alternative shells like fish
, etc.
No response
No response
No response
0.1.21
Multicall works fine with ethereum, but I haven't been able to get it to work with arbitrum. I haven't tried any other chains.
I tried calling the multicall3 contract directly and got the same issue. Does multicall3 behave different on arb?
Big ol' error message:
return new ContractFunctionExecutionError(cause, {
^
ContractFunctionExecutionError: RPC Request failed.
URL: https://rpc.ankr.com/arbitrum
Request body: {"method":"eth_call","params":[{"data":"0x82ad56cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd000000000000000000000000000000000000000000000000000000000000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd00000000000000000000000000000000000000000000000000000000","to":"0xca11bde05977b3631167028862be2a173976ca11"},"latest"]}
Raw Call Arguments:
to: 0xca11bde05977b3631167028862be2a173976ca11
data: 0x82ad56cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd000000000000000000000000000000000000000000000000000000000000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd00000000000000000000000000000000000000000000000000000000
Contract Call:
address: 0xca11bde05977b3631167028862be2a173976ca11
function: aggregate3((address target, bool allowFailure, bytes callData)[])
args: ([{"allowFailure":true,"callData":"0x18160ddd","target":"0x6325439389e0797ab35752b4f43a14c004f22a9c"},{"allowFailure":true,"callData":"0x18160ddd","target":"0x6325439389e0797ab35752b4f43a14c004f22a9c"}])
Docs: https://viem.sh/docs/contract/readContract.html
Details: we can't execute this request
Version: [email protected]
at getContractError (/Users/mac/robo/web3-backtest/node_modules/viem/src/utils/errors/getContractError.ts:57:10)
at readContract (/Users/mac/robo/web3-backtest/node_modules/viem/src/actions/public/readContract.ts:57:11)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async multicall (/Users/mac/robo/web3-backtest/node_modules/viem/src/actions/public/multicall.ts:100:19)
at async main (file:///Users/mac/robo/web3-backtest/src/core/example.ts:21:18) {
details: "we can't execute this request",
docsPath: '/docs/contract/readContract',
metaMessages: [
'URL: https://rpc.ankr.com/arbitrum',
'Request body: {"method":"eth_call","params":[{"data":"0x82ad56cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd000000000000000000000000000000000000000000000000000000000000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd00000000000000000000000000000000000000000000000000000000","to":"0xca11bde05977b3631167028862be2a173976ca11"},"latest"]}',
' ',
'Raw Call Arguments:',
' to: 0xca11bde05977b3631167028862be2a173976ca11\n' +
' data: 0x82ad56cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd000000000000000000000000000000000000000000000000000000000000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd00000000000000000000000000000000000000000000000000000000',
' ',
'Contract Call:',
' address: 0xca11bde05977b3631167028862be2a173976ca11\n' +
' function: aggregate3((address target, bool allowFailure, bytes callData)[])\n' +
' args: ([{"allowFailure":true,"callData":"0x18160ddd","target":"0x6325439389e0797ab35752b4f43a14c004f22a9c"},{"allowFailure":true,"callData":"0x18160ddd","target":"0x6325439389e0797ab35752b4f43a14c004f22a9c"}])'
],
shortMessage: 'RPC Request failed.',
cause: CallExecutionError: RPC Request failed.
URL: https://rpc.ankr.com/arbitrum
Request body: {"method":"eth_call","params":[{"data":"0x82ad56cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd000000000000000000000000000000000000000000000000000000000000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd00000000000000000000000000000000000000000000000000000000","to":"0xca11bde05977b3631167028862be2a173976ca11"},"latest"]}
Raw Call Arguments:
to: 0xca11bde05977b3631167028862be2a173976ca11
data: 0x82ad56cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd000000000000000000000000000000000000000000000000000000000000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd00000000000000000000000000000000000000000000000000000000
Details: we can't execute this request
Version: [email protected]
at getCallError (/Users/mac/robo/web3-backtest/node_modules/viem/src/utils/errors/getCallError.ts:18:10)
at call (/Users/mac/robo/web3-backtest/node_modules/viem/src/actions/public/call.ts:100:11)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async readContract (/Users/mac/robo/web3-backtest/node_modules/viem/src/actions/public/readContract.ts:45:22)
at async multicall (/Users/mac/robo/web3-backtest/node_modules/viem/src/actions/public/multicall.ts:100:19)
at async main (file:///Users/mac/robo/web3-backtest/src/core/example.ts:21:18) {
details: "we can't execute this request",
docsPath: undefined,
metaMessages: [
'URL: https://rpc.ankr.com/arbitrum',
'Request body: {"method":"eth_call","params":[{"data":"0x82ad56cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd000000000000000000000000000000000000000000000000000000000000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd00000000000000000000000000000000000000000000000000000000","to":"0xca11bde05977b3631167028862be2a173976ca11"},"latest"]}',
' ',
'Raw Call Arguments:',
' to: 0xca11bde05977b3631167028862be2a173976ca11\n' +
' data: 0x82ad56cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd000000000000000000000000000000000000000000000000000000000000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd00000000000000000000000000000000000000000000000000000000'
],
shortMessage: 'RPC Request failed.',
cause: RpcError: RPC Request failed.
URL: https://rpc.ankr.com/arbitrum
Request body: {"method":"eth_call","params":[{"data":"0x82ad56cb00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd000000000000000000000000000000000000000000000000000000000000000000000000000000006325439389e0797ab35752b4f43a14c004f22a9c00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000418160ddd00000000000000000000000000000000000000000000000000000000","to":"0xca11bde05977b3631167028862be2a173976ca11"},"latest"]}
Details: we can't execute this request
Version: [email protected]
at Object.http (/Users/mac/robo/web3-backtest/node_modules/viem/src/utils/rpc.ts:109:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at async request (/Users/mac/robo/web3-backtest/node_modules/viem/src/clients/transports/http.ts:56:30)
at async withRetry.delay.count.count (/Users/mac/robo/web3-backtest/node_modules/viem/src/utils/buildRequest.ts:54:18)
at async attemptRetry (/Users/mac/robo/web3-backtest/node_modules/viem/src/utils/promise/withRetry.ts:34:22) {
details: "we can't execute this request",
docsPath: undefined,
metaMessages: [Array],
shortMessage: 'RPC Request failed.',
cause: [Object],
code: 0
}
},
abi: [
{
inputs: [Array],
name: 'aggregate3',
outputs: [Array],
stateMutability: 'view',
type: 'function'
}
],
args: [ [ [Object], [Object] ] ],
contractAddress: '0xca11bde05977b3631167028862be2a173976ca11',
formattedArgs: undefined,
functionName: 'aggregate3',
sender: undefined
}
No response
Copied from the example code in the docs, calling totalSupply() twice on NFT contracts on eth and arbitrum.
export const publicClient = createPublicClient({
chain: mainnet,
transport: http('https://rpc.ankr.com/eth'),
// transport: http('https://rpc.ankr.com/arbitrum'),
})
const main = async () => {
const wagmiContract = {
address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // eth NFT
// address: '0x6325439389e0797ab35752b4f43a14c004f22a9c', // arb NFT
abi: nftAbi
} as const
const results = await publicClient.multicall({
contracts: [
{
...wagmiContract,
functionName: 'totalSupply',
},
{
...wagmiContract,
functionName: 'totalSupply',
},
]
})
console.log(results)
}
main()
No response
No response
0.3.7
The type of the multicall result status is defined as 'success' | 'error'
.
The type of the multicall result status should be defined as 'success' | 'failure'
.
No response
No response
No response
0.2.14
When i call
import { decodeFunctionResult } from 'viem'
const wagmiAbi = [{
inputs: [],
name: "latestRoundData",
outputs: [
{ internalType: "uint80", name: "roundId", type: "uint80" },
{ internalType: "int256", name: "answer", type: "int256" },
{ internalType: "uint256", name: "startedAt", type: "uint256" },
{ internalType: "uint256", name: "updatedAt", type: "uint256" },
{ internalType: "uint80", name: "answeredInRound", type: "uint80" },
],
stateMutability: "view",
type: "function",
}]
const value = decodeFunctionResult({
abi: wagmiAbi,
functionName: 'latestRoundData',
data: '0x00000000000000000000000000000000000000000000000100000000000027ba000000000000000000000000000000000000000000000000000002940e47c580000000000000000000000000000000000000000000000000000000006433e11f000000000000000000000000000000000000000000000000000000006433e11f00000000000000000000000000000000000000000000000100000000000027ba'
})
console.log(value);
It return
[ 18446744073709561786n, 2834918000000n, 1681121567n, 1681121567n, 18446744073709561786n ]
It will return object
{roundId: 18446744073709561786n, answer: 2834918000000n startedAt: 1681121567n, updatedAt: 1681121567n, answeredInRound: 18446744073709561786n }
No response
No response
No response
0.1.24
TypeError: Cannot destructure property 'id' of 'chain' as it is undefined.
at addChain (addChain.ts:13:11)
at Object.addChain (wallet.ts:81:23)
at Proxy.connectWallet (index.js?t=1680200284864:123:26)
at Proxy.<anonymous> (pinia.mjs:1364:30)
at _createElementVNode.onClick._cache.<computed>._cache.<computed> (HomeView.vue:11:31)
at callWithErrorHandling (runtime-core.esm-bundler.js:173:22)
at callWithAsyncErrorHandling (runtime-core.esm-bundler.js:182:21)
at HTMLButtonElement.invoker (runtime-dom.esm-bundler.js:345:9)
id - 137
Add new chain
import {
createWalletClient,
custom
} from "viem";
import { polygon } from "viem/chains";
// ...
const walletClient = createWalletClient({
chain: polygon,
transport: custom(window.ethereum),
});
await walletClient.addChain(polygon);
No response
No response
0.2.12
Type '
0x${string}
' is not assignable to type 'never'.ts(2322)
Should not receive a type error
const [address] = await walletClient.getAddresses();
const { request } = await publicClient.simulateContract({
account: address,
address: contract,
abi: ERC721_ABI,
functionName: 'setApprovalForAll',
args: ['0x...', true],
});
No response
No response
0.1.7
Making steps from CONTRIBUTING.md
. Getting error trying to pnpm install
without installing forge
.
postinstall
script contains wagmi generate
, which requires forge
to be installed
Installing foundry
should be described before pnpm install
pnpm install
No response
No response
0.3.7
Does not retrieve the blocknumber using wss protocol
Excepts to retrieve the blocknumber using the wss protocol
Try using the http protocol with achemy or infura apikey ==> It does work
Try using the wss protocol with achemy or infura apikey ==> It does NOT work
https://stackblitz.com/edit/viem-getting-started-on7saa?file=index.ts
No response
Originally posted by mhmulford0 April 17, 2023
I have this bit of code spitting out all of the logs for a given ERC20 contract. Based on the docs for decodeEventLog
, I should get a return type that looks like this:
/**
* {
* eventName: 'Transfer',
* args: {
* from: '0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266',
* to: '0x70997970c51812dc3a010c7d01b50e0d17dc79c8'
* value: 1n
* }
* }
*/
However, what I actually get is
This causes the required type assertion in the included code. After debugging a bit I could not get anything other than the empty object as the inferred type. Any help would be wonderful. Package version 0.3.2
import { createPublicClient, decodeEventLog, http, parseAbiItem } from "viem";
import { mainnet } from "viem/chains";
import { erc20ABI } from "@wagmi/core";
type TransferLogArgs = {
from: string;
to: string;
value: BigInt;
};
const transport = http(
"https://eth-mainnet.g.alchemy.com/v2/my-correct-api-key"
);
const client = createPublicClient({
chain: mainnet,
transport,
});
async function main() {
const BLOCK_INTERVAL = 250;
let startBlock = 15390081;
setInterval(async () => {
console.log({ startBlock });
const changes = await client.getLogs({
address: "0xb24cd494faE4C180A89975F1328Eab2a7D5d8f11",
event: parseAbiItem(
"event Transfer(address indexed from, address indexed to, uint256 value)"
),
fromBlock: BigInt(startBlock),
toBlock: BigInt(startBlock + BLOCK_INTERVAL),
});
startBlock += BLOCK_INTERVAL;
for (const change of changes) {
const log = decodeEventLog({
abi: erc20ABI,
data: change.data,
topics: change.topics,
eventName: change.eventName,
});
if (typeof log.args === "undefined") {
return new Error("incorrect data");
}
const info = log.args as TransferLogArgs;
console.log(info);
}
}, 1500);
}
main().catch((err) => {
console.log(err);
process.exit(1);
});
0.1.10
In the example from the documentation on connecting a local account, I have to make a wallet using the getAccount
utility imported from viem/ethers
. But there is nothing in this path in the library.
I expected to see the import of the required utility to connect ethers
or a description in the documentation about the fact that the work with the wallet through ethers
is not yet available.
[email protected]
import { getAccount } from 'viem/ethers'
https://stackblitz.com/edit/viem-getting-started-qvtbmg?file=index.ts
No response
0.2.12
The following code does not compile :
import { createPublicClient, PublicClient, webSocket } from "viem";
import { mainnet } from 'viem/chains'
const client: PublicClient = createPublicClient({
chain: mainnet,
transport: webSocket(),
});
Because apparently createPublicClient
's return value is not assignable to type PublicClient
.
I obviously expect the code above to compile and run.
import { createPublicClient, PublicClient, webSocket } from "viem";
import { mainnet } from 'viem/chains'
const client: PublicClient = createPublicClient({
chain: mainnet,
transport: webSocket(),
});
No response
This problem does not appear when using http as transport.
Additionally, it used to work on version 0.1.22.
Can we ship the sources and sourcemaps? It'd make the npm package larger, but it shouldn't affect production bundles.
Currently I'm getting stack traces like this, which could be better:
at Object.request (/private/tmp/v/node_modules/viem/dist/chunk-QMLDI5JU.js:2032:13)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at sendTransaction (/private/tmp/v/node_modules/viem/dist/chunk-KGXH5DYI.js:92:16)
at main (/private/tmp/v/index.js:26:14)
0.2.9
/Users/songkeys/GitHub/playground/node_modules/viem/dist/chunk-XMKUHSC7.js:3321
return new TransactionExecutionError(cause, {
^
TransactionExecutionError: An error occurred.
Request Arguments:
from: 0x00000081d48bA02DAa6C13D55C2916aD0570B652
to: 0xa6f969045641Cf486a747A2688F3a5A6d43cd0D8
data: 0xcd69fe61000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000081d48ba02daa6c13d55c2916ad0570b65200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000001a612d72616e646f6d2d68616e646c652d797265746a3374323538000000000000000000000000000000000000000000000000000000000000000000000000003c697066733a2f2f516d544d4436734c41374d346965674b446862644d50425a34484c6935666a57323777324a3136677163354362372f312e6a736f6e0000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000
Details: invalid object key - account (argument="transaction:account", value="[object Object]", code=INVALID_ARGUMENT, version=properties/5.7.0)
Version: [email protected]
at getTransactionError (/Users/songkeys/GitHub/playground/node_modules/viem/dist/chunk-XMKUHSC7.js:3321:10)
at sendTransaction (/Users/songkeys/GitHub/playground/node_modules/viem/dist/chunk-XMKUHSC7.js:5090:11)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async writeContract (/Users/songkeys/GitHub/playground/node_modules/viem/dist/chunk-XMKUHSC7.js:5224:17)
Sent tx successfully.
I posted this here a month ago. Now, I tried again. it's the same error in 0.2.x.
I follow this guide to writeContract, and this guide to convert ethers wallet to viem.
Code to reproduce:
import { Wallet } from 'ethers'; // v5
import { createWalletClient, createPublicClient, http } from 'viem';
import { ethersWalletToAccount } from 'viem/ethers';
import { crossbell } from 'viem/chains';
const walletClient = createWalletClient({
chain: crossbell,
transport: http('https://rpc.crossbell.io'),
});
const publicClient = createPublicClient({
chain: crossbell,
transport: http('https://rpc.crossbell.io'),
});
const wallet = new Wallet(
privateKey, // you may need to claim the gas from https://faucet.crossbell.io
);
const account = ethersWalletToAccount(wallet);
const { request } = await publicClient.simulateContract({
account,
address: '0xa6f969045641Cf486a747A2688F3a5A6d43cd0D8',
abi: [
{
inputs: [
{
components: [
{
internalType: 'address',
name: 'to',
type: 'address',
},
{
internalType: 'string',
name: 'handle',
type: 'string',
},
{
internalType: 'string',
name: 'uri',
type: 'string',
},
{
internalType: 'address',
name: 'linkModule',
type: 'address',
},
{
internalType: 'bytes',
name: 'linkModuleInitData',
type: 'bytes',
},
],
internalType: 'struct DataTypes.CreateCharacterData',
name: 'vars',
type: 'tuple',
},
],
name: 'createCharacter',
outputs: [
{
internalType: 'uint256',
name: 'characterId',
type: 'uint256',
},
],
stateMutability: 'nonpayable',
type: 'function',
},
],
functionName: 'createCharacter',
args: [
{
to: wallet.address,
handle: genRandomHandle(),
uri: 'fake-url',
linkModule: '0x0000000000000000000000000000000000000000',
linkModuleInitData: '0x0000000000000000000000000000000000000000',
},
],
});
const hash = await walletClient.writeContract(request);
export { hash };
// util
function genRandomHandle() {
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
let handle = '';
for (let i = 0; i < 10; i++) {
handle += chars.charAt(Math.floor(Math.random() * chars.length));
}
return 'a-random-handle-' + handle;
}
https://stackblitz.com/edit/viem-getting-started-rjwzad?file=index.ts
If you need anything else (like gas to test or additional private info), you may contact me on discord Songkeys#0001
or telegram.
0.2.8 and 0.3.12
I expect this piece of code to work accordingly to types defined.
As it stands first call in multicall should return type [bigint, bigint]. Unfortunately, after upgrading to 0.3.12 in order to fix incorrect peer deps in wagmi@next, this piece of code throws an error. Bumping back to 0.2.8 fixes it.
const [[lockedAmount, lockedEnd], lockValue, voted] =
await viemClient.multicall({
allowFailure: false,
multicallAddress: CONTRACTS.MULTICALL_ADDRESS,
contracts: [
{
...vestingContract,
functionName: "locked",
args: [tokenIndex],
},
{
...vestingContract,
functionName: "balanceOfNFT",
args: [tokenIndex],
},
{
...vestingContract,
functionName: "voted",
args: [tokenIndex],
},
],
});
Here's the error message:
TypeError: Invalid attempt to destructure non-iterable instance. In order to be iterable, non-array objects must have a Symbol.iterator method.
I expect the piece of code mentioned above return proper multicall results.
I reckon you can reproduce by making a multicall in which one of calls returns an array of fixed number of elements
No response
I think it's related to #398
I can do a minimal example, but in the nearest future
0.2.5
File: ./src/index.ts
// Imports
// ========================================================
import { ZKThonContact } from './contract'; // Contract Address: 0x3aC587078b344a3d27e56632dFf236F1Aff04D56
import { createPublicClient, http, createWalletClient } from 'viem';
import { privateKeyToAccount } from 'viem/accounts' ;
import { polygonZkEvmTestnet } from 'viem/chains';
import dotenv from 'dotenv';
// Config
// ========================================================
dotenv.config();
const client = createPublicClient({
chain: polygonZkEvmTestnet,
transport: http(),
});
const account = privateKeyToAccount(`0x${process.env.WALLET_PRIVATE_KEY}`);
console.log({ address: account.address });
const walletClient = createWalletClient({
account,
chain: polygonZkEvmTestnet,
transport: http(polygonZkEvmTestnet.rpcUrls.default.http[0]),
});
// Main Function
// ========================================================
(async () => {
console.group('Main function');
// Read from contract
const getCurrentSubmission = await client.readContract({
...ZKThonContact,
functionName: 'getCurrentSubmission'
});
console.log({ getCurrentSubmission });
// Write to contract
const { request } = await client.simulateContract({
...ZKThonContact,
functionName: 'submitUsername',
account,
args: ['codingwithmanny']
});
const hash = await walletClient.writeContract(request);
console.log({ hash });
console.groupEnd();
})();
# FROM ./
./node_modules/.bin/ts-node src/index.ts;
# Output:
# { address: '0xSomeWalletAddress' }
# Main function
# { getCurrentSubmission: 'samirmerhar' }
# /Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/utils/errors/getTransactionError.ts:19
# return new TransactionExecutionError(cause, {
# ^
# TransactionExecutionError: `gasPrice` is not a valid EIP-1559 Transaction attribute.
#
# Request Arguments:
# from: 0xSomeWalletAddress
# to: 0x3aC587078b344a3d27e56632dFf236F1Aff04D56
# data: 0x70020c040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000f636f64696e67776974686d616e6e790000000000000000000000000000000000
#
# Version: [email protected]
# at getTransactionError (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/utils/errors/getTransactionError.ts:19:10)
# at sendTransaction (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/actions/wallet/sendTransaction.ts:139:11)
# at processTicksAndRejections (node:internal/process/task_queues:95:5)
# at async writeContract (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/actions/wallet/writeContract.ts:61:16) {
# details: undefined,
# docsPath: undefined,
# metaMessages: [
# 'Request Arguments:',
# ' from: 0xSomeWalletAddress\n' +
# ' to: 0x3aC587078b344a3d27e56632dFf236F1Aff04D56\n' +
# ' data: 0x70020c040000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000f636f64696e67776974686d616e6e790000000000000000000000000000000000'
# ],
# shortMessage: '`gasPrice` is not a valid EIP-1559 Transaction attribute.',
# cause: BaseError [ViemError]: `gasPrice` is not a valid EIP-1559 Transaction attribute.
#
# Version: [email protected]
# at assertTransactionEIP1559 (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/utils/transaction/assertTransaction.ts:23:11)
# at serializeTransactionEIP1559 (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/utils/transaction/serializeTransaction.ts:78:3)
# at serializeTransaction (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/utils/transaction/serializeTransaction.ts:45:12)
# at signTransaction (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/accounts/utils/signTransaction.ts:34:54)
# at Object.signTransaction (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/accounts/privateKeyToAccount.ts:29:14)
# at sendTransaction (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/actions/wallet/sendTransaction.ts:104:44)
# at processTicksAndRejections (node:internal/process/task_queues:95:5)
# at async writeContract (/Users/username/path/to/node_modules/.pnpm/[email protected][email protected]/node_modules/viem/src/actions/wallet/writeContract.ts:61:16) {
# details: undefined,
# docsPath: undefined,
# metaMessages: undefined,
# shortMessage: '`gasPrice` is not a valid EIP-1559 Transaction attribute.'
# }
# }
# βELIFECYCLEβ Command failed with exit code 1.
No errors and a successful transaction hash returned.
See Current Behavior for steps.
No response
No response
Curves have been recently audited; recent secp audit was in 2021. The security has been improved.
Curves depend on hashes, so you can de-duplicate deps with using hashes 1.3.0+.
0.1.15
client.multicall({ allowFailure: false })
returns type [{ result: __type__, status: "success" }]
client.multicall({ allowFailure: false })
has a defined return type of[ __type__ ]
client.multicall({ allowFailure: false })
https://github.com/kyscott18/numoen-example-arbitrage/blob/master/src/numoen.ts#L10-L40
No response
0.1.15
When sending transactions that use Celo precompiles, Celo Native Token is an example of this, viem transaction simulation simulates a revert for valid transaction. Foundry has the same issue and its easier to replicate there. Not saying this is something viem needs to fix but more warnings or a better error message would be helpful because its pretty difficult to tell that this is what is actually happening at first glance.
Ethers is able to handle this somehow.
No response
https://github.com/kyscott18/celo-foundry-bug-example/blob/master/test/CeloTest.sol
No response
0.1.24
When calling decodeFunctionData
with a (full contract) abi that includes the constructor of the contract it throws an error because formatAbiItem
does not support constructors.
decodeFunctionData
should support constructors.
No response
No response
I was going to submit a fix for this but noticed that there's already a test for formatAbiItem
that actually tests exactly this. So I'm wondering why and whether this is intended?
What would be the right fix? Should formatAbiItem support formatting of constructor abi items or should we adjust decodeFunctionData
to e.g. run the provided abi through a filter first to remove all types that are not supported?
0.1.22
I haven't looked into this further yet but wanted to drop this issue here before I call it a night ...:
When using NodeNext
moduleResolution, building with tsc
& declaration / declarationMap enabled errors for just about every inferred type that one may try to re-export from viem
:
E.g. for something like
export const client = createClient({ ... });
You'd get:
The inferred type of 'client' cannot be named without a reference to '../node_modules/viem/dist/createClient-a28317a9.js'. This is likely not portable. A type annotation is necessary.
Viem also works with NodeNext module resolution
I can set up a reproduction tomorrow and dive deeper & fix this issue, but here are the steps anyways:
viem
, e.g. a client object (createClient(...)
)tsc
for compilation. Do not use esbuild
or swc
or any other derived tools like tsup
as they generally do not process & honor declaration
and declarationMap
build output to the same extent (or at all) as tsc
declaration
and declarationMap
output in tsconfig.jsonmoduleResolution
to NodeNext
tsc
with build output (this is important as this issue doesn't appear with --noEmit
or if declaration
or declarationMap
output is disabledYou'll now see the aforementioned error ...
Will share tomorrow (or attempt to submit a fix)
I love the work you are doing to modernize the JS/TS ecosystem in this space. It's long overdue! :-)
Not quite related, but ... I'd really like for viem
to also generate (& publish) declarationMap
output for better IDE navigation capabilities (same for abitype & wagmi). I understand why tsup
has gained this much adoption and I've (and am) using it a lot for side projects too but it can't replace tsc
entirely imho, especially for libraries like these!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.