fix: fallback to eth_sign for permit approval (#5847)

* fix: fallback to eth_sign for permit approval

* chore: clean up comments/logs

* refactor: mirror ethers impl

* chore: add comment re: impl
This commit is contained in:
Zach Pomerantz 2023-01-18 12:14:55 -08:00 committed by GitHub
parent 96f24d5a9b
commit 94544de74b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 0 deletions

@ -1,3 +1,5 @@
import 'utils/signTypedData'
import { AllowanceTransfer, MaxAllowanceTransferAmount, PERMIT2_ADDRESS, PermitSingle } from '@uniswap/permit2-sdk'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'

@ -0,0 +1,30 @@
import { _TypedDataEncoder } from '@ethersproject/hash'
import { JsonRpcSigner } from '@ethersproject/providers'
/**
* Overrides the _signTypedData method to add support for wallets without EIP-712 support (eg Zerion) by adding a fallback to eth_sign.
* The implementation is copied from ethers (and linted), except for the catch statement, which removes the logger and adds the fallback.
* @see https://github.com/ethers-io/ethers.js/blob/c80fcddf50a9023486e9f9acb1848aba4c19f7b6/packages/providers/src.ts/json-rpc-provider.ts#L334
*/
JsonRpcSigner.prototype._signTypedData = async function signTypedDataWithFallbacks(this, domain, types, value) {
// Populate any ENS names (in-place)
const populated = await _TypedDataEncoder.resolveNames(domain, types, value, (name: string) => {
return this.provider.resolveName(name) as Promise<string>
})
const address = await this.getAddress()
try {
return await this.provider.send('eth_signTypedData_v4', [
address.toLowerCase(),
JSON.stringify(_TypedDataEncoder.getPayload(populated.domain, types, populated.value)),
])
} catch (error) {
if (typeof error.message === 'string' && error.message.match(/not found/i)) {
console.warn('eth_signTypedData_v4 failed, falling back to eth_sign:', error)
const hash = _TypedDataEncoder.hash(populated.domain, types, populated.value)
return await this.provider.send('eth_sign', [address, hash])
}
throw error
}
}