Skip to content

Commit

Permalink
Use ethers.utils.hexValue for eth_chainId
Browse files Browse the repository at this point in the history
  • Loading branch information
corbanbrook committed Aug 2, 2023
1 parent bc2ffd7 commit 666be94
Show file tree
Hide file tree
Showing 3 changed files with 539 additions and 455 deletions.
249 changes: 132 additions & 117 deletions packages/0xsequence/tests/browser/wallet-provider/dapp.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const tests = async () => {
const hardhatProvider = new ethers.providers.JsonRpcProvider('http://localhost:8545')

const client = new SequenceClient(transportsConfig, new MemoryItemStore(), 31337)
const wallet = new SequenceProvider(client, (chainId) => {
const wallet = new SequenceProvider(client, chainId => {
if (chainId === 31337) {
return hardhatProvider
}
Expand All @@ -45,7 +45,7 @@ export const tests = async () => {
// requests to the defaultChain
const provider = wallet.getProvider()
const signer = wallet.getSigner()

// clear it in case we're testing in browser session
await wallet.disconnect()

Expand All @@ -64,7 +64,7 @@ export const tests = async () => {
await test('connect', async () => {
const { connected } = await wallet.connect({
app: 'test',
keepWalletOpened: true,
keepWalletOpened: true
})
assert.true(connected, 'is connected')
})
Expand Down Expand Up @@ -123,21 +123,19 @@ export const tests = async () => {
})

await test('multiple networks', async () => {
const toHexString = n => `0x${n.toString(16)}`

// chainId 31337
{
assert.equal(provider.getChainId(), 31337, 'provider chainId is 31337')

const network = await provider.getNetwork()
assert.equal(network.chainId, 31337, 'chain id match')

const netVersion = await provider.send('net_version', [])
assert.equal(netVersion, '31337', 'net_version check')

const chainId = await provider.send('eth_chainId', [])
assert.equal(chainId, toHexString(31337), 'eth_chainId check')
assert.equal(chainId, ethers.utils.hexValue(31337), 'eth_chainId check')

const chainId2 = await signer.getChainId()
assert.equal(chainId2, 31337, 'chainId check')
}
Expand All @@ -149,13 +147,13 @@ export const tests = async () => {

const network = await provider2.getNetwork()
assert.equal(network.chainId, 31338, '2nd chain, chain id match - 3')

const netVersion = await provider2.send('net_version', [])
assert.equal(netVersion, '31338', '2nd chain, net_version check - 4')

const chainId = await provider2.send('eth_chainId', [])
assert.equal(chainId, toHexString(31338), '2nd chain, eth_chainId check - 5')
assert.equal(chainId, ethers.utils.hexValue(31338), '2nd chain, eth_chainId check - 5')

const chainId2 = await provider2.getSigner().getChainId()
assert.equal(chainId2, 31338, '2nd chain, chainId check - 6')
}
Expand All @@ -175,20 +173,22 @@ export const tests = async () => {
const message2 = ethers.utils.toUtf8Bytes('hihi')

// Sign the message
const sigs = await Promise.all([message, message2].map(async m => {
assert.equal(await signer.getChainId(), 31337, 'signer chainId is 31337')

// NOTE: below line is equivalent to `signer.signMessage(m)` call
// const sig = await wallet.utils.signMessage(m)
const sig = await signer.signMessage(m, { eip6492: true })

// Non-deployed wallet (with EIP6492) should return a signature
// that ends with the EIP-6492 magic bytes
const suffix = "6492649264926492649264926492649264926492649264926492649264926492"
assert.true(sig.endsWith(suffix), 'signature ends with EIP-6492 magic bytes')

return sig
}))
const sigs = await Promise.all(
[message, message2].map(async m => {
assert.equal(await signer.getChainId(), 31337, 'signer chainId is 31337')

// NOTE: below line is equivalent to `signer.signMessage(m)` call
// const sig = await wallet.utils.signMessage(m)
const sig = await signer.signMessage(m, { eip6492: true })

// Non-deployed wallet (with EIP6492) should return a signature
// that ends with the EIP-6492 magic bytes
const suffix = '6492649264926492649264926492649264926492649264926492649264926492'
assert.true(sig.endsWith(suffix), 'signature ends with EIP-6492 magic bytes')

return sig
})
)
const sig = sigs[0]

// Verify the signature
Expand All @@ -207,16 +207,16 @@ export const tests = async () => {
verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC'
}

const types: {[key: string] : TypedDataField[]} = {
'Person': [
{name: "name", type: "string"},
{name: "wallet", type: "address"}
const types: { [key: string]: TypedDataField[] } = {
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallet', type: 'address' }
]
}

const message = {
'name': 'Bob',
'wallet': '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
name: 'Bob',
wallet: '0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB'
}

const sig = await signer.signTypedData(domain, types, message)
Expand All @@ -241,14 +241,14 @@ export const tests = async () => {

// confirm that authSigner, the chain-bound provider, derived from the authProvider returns the same signature
const authSigner = authProvider.getSigner()
const sigChk = await authSigner.signMessage(message, { chainId} )
const sigChk = await authSigner.signMessage(message, { chainId })
assert.equal(sigChk, sig, 'authSigner.signMessage returns the same sig')

// Verify the signature
const isValid = await wallet.utils.isValidMessageSignature(address, message, sig, chainId)
assert.true(isValid, 'signAuthMessage, signature is valid')
})

await test('getBalance', async () => {
// technically, the mock-wallet's single signer owner has some ETH..
const balanceSigner1 = await provider.getBalance('0x4e37E14f5d5AAC4DF1151C6E8DF78B7541680853')
Expand All @@ -269,83 +269,89 @@ export const tests = async () => {
assert.true(walletBalanceAfter.sub(walletBalanceBefore).eq(ethAmount), `wallet received ${ethAmount} eth`)
})

const testSendETH = async (title: string, opts: {
gasLimit?: string
} = {}) => test(title, async () => {
// sequence wallet to now send some eth back to another seed account
// via the relayer
{
const walletAddress = wallet.getAddress()
const walletBalanceBefore = await signer.getBalance()


// send eth from sequence smart wallet to another test account
const toAddress = testAccounts[1].address
const toBalanceBefore = await provider.getBalance(toAddress)

const ethAmount = ethers.utils.parseEther('1.4242')

// NOTE: when a wallet is undeployed (counterfactual), and although the txn contents are to send from our
// sequence wallet to the test account, the transaction by the Sequence Wallet instance will be sent `to` the
// `GuestModule` smart contract address of the Sequence context `from` the Sequence Relayer (local) account.
//
// However, when a wallet is deployed on-chain, and the txn object is to send from our sequence wallet to the
// test account, the transaction will be sent `to` the smart wallet contract address of the sender by
// the relayer. The transaction will then be delegated through the Smart Wallet and transfer will occur
// as an internal transaction on-chain.
//
// Also note, the gasLimit and gasPrice can be estimated by the relayer, or optionally may be specified.

//--

// Record wallet deployed state before, so we can check the receipt.to below. We have to do this
// because a wallet will automatically get bundled for deployment when it sends a transaction.
const beforeWalletDeployed = await hardhatProvider.getCode(wallet.getAddress()) !== '0x'

// NOTE/TODO: gasPrice even if set will be set again by the LocalRelayer, we should allow it to be overridden
const tx: ethers.providers.TransactionRequest = {
from: walletAddress,
to: toAddress,
value: ethAmount,
}

// specifying gasLimit manually
if (opts.gasLimit) {
tx.gasLimit = opts.gasLimit
}

const txResp = await signer.sendTransaction(tx)
const txReceipt = await txResp.wait()

assert.true(txReceipt.status === 1, 'txn sent successfully')
assert.true(await hardhatProvider.getCode(wallet.getAddress()) !== '0x', 'wallet must be in deployed state after the txn')

// transaction is sent to the deployed wallet, if the wallet is deployed.. otherwise its sent to guestModule
if (beforeWalletDeployed) {
assert.equal(txReceipt.to, wallet.getAddress(), 'recipient is correct')
} else {
assert.equal(txReceipt.to, walletContext[2].guestModule, 'recipient is correct')
const testSendETH = async (
title: string,
opts: {
gasLimit?: string
} = {}
) =>
test(title, async () => {
// sequence wallet to now send some eth back to another seed account
// via the relayer
{
const walletAddress = wallet.getAddress()
const walletBalanceBefore = await signer.getBalance()

// send eth from sequence smart wallet to another test account
const toAddress = testAccounts[1].address
const toBalanceBefore = await provider.getBalance(toAddress)

const ethAmount = ethers.utils.parseEther('1.4242')

// NOTE: when a wallet is undeployed (counterfactual), and although the txn contents are to send from our
// sequence wallet to the test account, the transaction by the Sequence Wallet instance will be sent `to` the
// `GuestModule` smart contract address of the Sequence context `from` the Sequence Relayer (local) account.
//
// However, when a wallet is deployed on-chain, and the txn object is to send from our sequence wallet to the
// test account, the transaction will be sent `to` the smart wallet contract address of the sender by
// the relayer. The transaction will then be delegated through the Smart Wallet and transfer will occur
// as an internal transaction on-chain.
//
// Also note, the gasLimit and gasPrice can be estimated by the relayer, or optionally may be specified.

//--

// Record wallet deployed state before, so we can check the receipt.to below. We have to do this
// because a wallet will automatically get bundled for deployment when it sends a transaction.
const beforeWalletDeployed = (await hardhatProvider.getCode(wallet.getAddress())) !== '0x'

// NOTE/TODO: gasPrice even if set will be set again by the LocalRelayer, we should allow it to be overridden
const tx: ethers.providers.TransactionRequest = {
from: walletAddress,
to: toAddress,
value: ethAmount
}

// specifying gasLimit manually
if (opts.gasLimit) {
tx.gasLimit = opts.gasLimit
}

const txResp = await signer.sendTransaction(tx)
const txReceipt = await txResp.wait()

assert.true(txReceipt.status === 1, 'txn sent successfully')
assert.true(
(await hardhatProvider.getCode(wallet.getAddress())) !== '0x',
'wallet must be in deployed state after the txn'
)

// transaction is sent to the deployed wallet, if the wallet is deployed.. otherwise its sent to guestModule
if (beforeWalletDeployed) {
assert.equal(txReceipt.to, wallet.getAddress(), 'recipient is correct')
} else {
assert.equal(txReceipt.to, walletContext[2].guestModule, 'recipient is correct')
}

// Ensure fromAddress sent their eth
const walletBalanceAfter = await signer.getBalance()
const sent = walletBalanceAfter.sub(walletBalanceBefore).mul(-1)

assert.true(sent.eq(ethAmount), `wallet sent ${sent} eth while expected ${ethAmount}`)

// Ensure toAddress received their eth
const toBalanceAfter = await provider.getBalance(toAddress)
const received = toBalanceAfter.sub(toBalanceBefore)
assert.true(received.eq(ethAmount), `toAddress received ${received} eth while expected ${ethAmount}`)

// Extra checks
if (opts.gasLimit) {
// In our test, we are passing a high gas limit for an internal transaction, so overall
// transaction must be higher than this value if it used our value correctly
assert.true(txResp.gasLimit.gte(opts.gasLimit), 'sendETH, using higher gasLimit')
}
}

// Ensure fromAddress sent their eth
const walletBalanceAfter = await signer.getBalance()
const sent = walletBalanceAfter.sub(walletBalanceBefore).mul(-1)

assert.true(sent.eq(ethAmount), `wallet sent ${sent} eth while expected ${ethAmount}`)

// Ensure toAddress received their eth
const toBalanceAfter = await provider.getBalance(toAddress)
const received = toBalanceAfter.sub(toBalanceBefore)
assert.true(received.eq(ethAmount), `toAddress received ${received} eth while expected ${ethAmount}`)

// Extra checks
if (opts.gasLimit) {
// In our test, we are passing a high gas limit for an internal transaction, so overall
// transaction must be higher than this value if it used our value correctly
assert.true(txResp.gasLimit.gte(opts.gasLimit), 'sendETH, using higher gasLimit')
}
}
})
})

await testSendETH('sendETH (defaultChain)')

Expand Down Expand Up @@ -376,7 +382,10 @@ export const tests = async () => {
const toBalanceAfter = await provider.getBalance(testAccount.address)
const sent = toBalanceAfter.sub(toBalanceBefore)
const expected = ethAmount1.add(ethAmount2)
assert.true(sent.eq(ethAmount1.add(ethAmount2)), `wallet sent ${sent} eth while expected ${expected} (${ethAmount1} + ${ethAmount2})`)
assert.true(
sent.eq(ethAmount1.add(ethAmount2)),
`wallet sent ${sent} eth while expected ${expected} (${ethAmount1} + ${ethAmount2})`
)
})

await test('sendTransaction batch format 2', async () => {
Expand All @@ -403,7 +412,10 @@ export const tests = async () => {
const toBalanceAfter = await provider.getBalance(testAccount.address)
const sent = toBalanceAfter.sub(toBalanceBefore)
const expected = ethAmount1.add(ethAmount2)
assert.true(sent.eq(ethAmount1.add(ethAmount2)), `wallet sent ${sent} eth while expected ${expected} (${ethAmount1} + ${ethAmount2})`)
assert.true(
sent.eq(ethAmount1.add(ethAmount2)),
`wallet sent ${sent} eth while expected ${expected} (${ethAmount1} + ${ethAmount2})`
)
})

await test('sendTransaction batch format 3', async () => {
Expand All @@ -430,7 +442,10 @@ export const tests = async () => {
const toBalanceAfter = await provider.getBalance(testAccount.address)
const sent = toBalanceAfter.sub(toBalanceBefore)
const expected = ethAmount1.add(ethAmount2)
assert.true(sent.eq(ethAmount1.add(ethAmount2)), `wallet sent ${sent} eth while expected ${expected} (${ethAmount1} + ${ethAmount2})`)
assert.true(
sent.eq(ethAmount1.add(ethAmount2)),
`wallet sent ${sent} eth while expected ${expected} (${ethAmount1} + ${ethAmount2})`
)
})

await test('sendETH from the sequence smart wallet (authChain)', async () => {
Expand Down Expand Up @@ -503,18 +518,18 @@ export const tests = async () => {
// send eth from sequence smart wallet to another test account
const toAddress = testAccounts[1].address
const toBalanceBefore = await provider2.getBalance(toAddress)

const ethAmount = ethers.utils.parseEther('1.1234')

const tx = {
from: walletAddress,
to: toAddress,
value: ethAmount,
value: ethAmount
}
const txReceipt = await (await signer2.sendTransaction(tx)).wait()

assert.true(txReceipt.status === 1, 'txn sent successfully')
assert.true(await hardhatProvider.getCode(walletAddress) !== '0x', 'wallet must be in deployed state after the txn')
assert.true((await hardhatProvider.getCode(walletAddress)) !== '0x', 'wallet must be in deployed state after the txn')

// Ensure fromAddress sent their eth
const walletBalanceAfter = await signer2.getBalance()
Expand Down
Loading

0 comments on commit 666be94

Please sign in to comment.