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

ChainId of TypedDataDomain not serializable during JsonRpcSigner.signTypedData() #3836

Closed
ZirionNeft opened this issue Feb 26, 2023 · 10 comments
Assignees
Labels
bug Verified to be an issue. fixed/complete This Bug is fixed or Enhancement is complete and published. v6 Issues regarding v6

Comments

@ZirionNeft
Copy link

Ethers Version

6.0.8

Search Terms

bigint, chainId, JsonRpcSigner, signTypedData, json, serialize, stringify

Describe the Problem

When trying to jsonRpcSigner.signTypedData(...) I got an error:

TypeError: Do not know how to serialize a BigInt
    at JSON.stringify (<anonymous>)
    at JsonRpcSigner.signTypedData (provider-jsonrpc.ts:324:18)

After debugging I realize that chainId of Domain data type converts to bigInt during TypedDataEncoder.getPayload(...), but after that JSON.stringify() don't know how to work with them without second argument function.

Code Snippet

export const Domain = (address: string, chainId: bigint) => ({
	name: 'EtherAlertsDonations',
	version: '1',
	chainId: '0x' + chainId.toString(), // or variable with any other type - nevermind
	verifyingContract: address
});

export async function getDonationSig<Signer extends AbstractSigner>(
	signer: Signer,
	rawData: TDonationToSign,
	contract: string,
	chainId: bigint
) {
	return signer.signTypedData(Domain(contract, chainId), DonationType, rawData);
}

Contract ABI

No response

Errors

TypeError: Do not know how to serialize a BigInt
    at JSON.stringify (<anonymous>)
    at JsonRpcSigner.signTypedData (provider-jsonrpc.ts:324:18)


### Environment

Ethereum (mainnet/ropsten/rinkeby/goerli), node.js (v12 or newer), Browser (Chrome, Safari, etc), Other (please specify)

### Environment (Other)

Svelte, SvelteKit
@ZirionNeft ZirionNeft added investigate Under investigation and may be a bug. v6 Issues regarding v6 labels Feb 26, 2023
@ricmoo ricmoo added the on-deck This Enhancement or Bug is currently being worked on. label Mar 7, 2023
@Jovonni
Copy link

Jovonni commented Mar 17, 2023

consistently getting this when signing:

 TypeError: Do not know how to serialize a BigInt

should I download until a fix, or is there a current workaround? @ZirionNeft @ricmoo

@insulineru
Copy link

Same problem with ethers@6.1.0

const domain = {
    "name": "Transfer Money",
    "version": "1.0.0",
    "chainId": 137,
    "verifyingContract": "0x91a3129e96e9488a98db463177F9A1312CF22081"
}

const TypesTransfer = {
  TransferCall: [
    { name: 'token', type: 'address' },
    { name: 'to', type: 'address' },
    { name: 'amount', type: 'uint256' },
    { name: 'fee', type: 'uint256' },
    { name: 'nonce', type: 'uint256' }
  ]
}

const config = {
    "token": "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
    "to": "0x777777125C91be606997038d50aD039dD7caa1a3",
    "amount": "4000000",
    "fee": "0",
    "nonce": "12607236389627287883"
}
signer.signTypedData(domain, TypesTransfer, config)

@ZirionNeft
Copy link
Author

ZirionNeft commented Apr 4, 2023

@Jovonni My workaround is just re-implementation of Signer class with true JSON.stringify with replacer callback.

@ricmoo ricmoo added bug Verified to be an issue. and removed investigate Under investigation and may be a bug. labels Apr 5, 2023
@ricmoo
Copy link
Member

ricmoo commented Apr 5, 2023

Thanks! I've confirmed it's a bug.

Quick question @ZirionNeft, if the value is outside the safe integer range, do you encode it as a 0x-prefixed quantity?

@insulineru
Copy link

@ricmoo I think you will find this information useful for the fix.

I made a patch like this to fix the problem

@ricmoo
Copy link
Member

ricmoo commented Apr 5, 2023

@insulineru Thanks! So, passing the chainId as a decimal string works then? The payload will look like: ...{"domain":{"chainId":"1234",...}}?

@insulineru
Copy link

@insulineru Thanks! So, passing the chainId as a decimal string works then? The payload will look like: ...{"domain":{"chainId":"1234",...}}?

No. I tried passing "137" or "0x87" in the chainId parameter, but TypedDataEncoder translates any value into BigInt. So I have to patch the BigInt class

@ricmoo
Copy link
Member

ricmoo commented Apr 5, 2023

Oh, I meant when data is passed directly to MetaMask. Basically, your above fix works?

I have a local copy working too. :)

@insulineru
Copy link

I tried Metamask and Rabby Wallet and my fix worked fine. Before that, with the exact same example, I signed all the messages in ethers@5.7.2, so yeah

Thanks for the heads up, @ricmoo :)

@ricmoo ricmoo added fixed/complete This Bug is fixed or Enhancement is complete and published. and removed on-deck This Enhancement or Bug is currently being worked on. labels Apr 10, 2023
@ricmoo
Copy link
Member

ricmoo commented Apr 10, 2023

Sorry, the fix was mislabelled in the commit (see 50b74b8). This has been fixed in v6.3.0.

Closing now as fixed, but if you run into any problems, please re-open.

Thanks! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Verified to be an issue. fixed/complete This Bug is fixed or Enhancement is complete and published. v6 Issues regarding v6
Projects
None yet
Development

No branches or pull requests

4 participants