Skip to content

Commit

Permalink
refactor: refactor logic to use ethers method
Browse files Browse the repository at this point in the history
  • Loading branch information
VGabriel45 committed Mar 5, 2025
1 parent 6bb5db0 commit f8101d8
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 47 deletions.
57 changes: 25 additions & 32 deletions packages/account/src/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { walletContracts } from '@0xsequence/abi'
import { commons, universal } from '@0xsequence/core'
import { migrator, defaults, version } from '@0xsequence/migration'
import { ChainId, NetworkConfig } from '@0xsequence/network'
import { FeeOption, FeeQuote, isRelayer, Relayer, RpcRelayer } from '@0xsequence/relayer'
import { tracker } from '@0xsequence/sessions'
import { SignatureOrchestrator } from '@0xsequence/signhub'
import { type FeeOption, type FeeQuote, isRelayer, type Relayer, RpcRelayer } from '@0xsequence/relayer'
import type { tracker } from '@0xsequence/sessions'
import type { SignatureOrchestrator } from '@0xsequence/signhub'
import { encodeTypedDataDigest, getFetchRequest } from '@0xsequence/utils'
import { Wallet } from '@0xsequence/wallet'
import { ethers } from 'ethers'
import { ethers, MessagePrefix } from 'ethers'
import { AccountSigner, AccountSignerOptions } from './signer'

export type AccountStatus = {
Expand Down Expand Up @@ -789,43 +789,36 @@ export class Account {
}

/**
* Signs a message.
*
* This method will sign the message using the account associated with this signer
* and the specified chain ID. The message is already being prefixed with the EIP-191 prefix.
*
* @param message - The message to sign. Can be a string or BytesLike.
* @returns A Promise that resolves to the signature as a hexadecimal string
*
* @example
* ```typescript
* const message = "Hello, Sequence!";
* const signature = await account.signMessage(message);
* console.log(signature);
* // => "0x123abc..." (hexadecimal signature)
*/
* Signs a message.
*
* This method will sign the message using the account associated with this signer
* and the specified chain ID. If the message is already prefixed with the EIP-191
* prefix, it will be hashed directly. Otherwise, it will be prefixed before hashing.
*
* @param message - The message to sign. Can be a string or BytesLike.
* @param chainId - The chain ID to use for signing
* @param cantValidateBehavior - Behavior when the wallet cannot validate on-chain
* @returns A Promise that resolves to the signature as a hexadecimal string
*/
signMessage(
message: ethers.BytesLike | string,
message: ethers.BytesLike,
chainId: ethers.BigNumberish,
cantValidateBehavior: 'ignore' | 'eip6492' | 'throw' = 'ignore'
): Promise<string> {
const messageBytes = typeof message === 'string' ? ethers.toUtf8Bytes(message) : message
const eip191prefix = ethers.toUtf8Bytes('\x19Ethereum Signed Message:\n')

const messageHex = ethers.hexlify(messageBytes)
const prefixHex = ethers.hexlify(eip191prefix)
const messageHex = ethers.hexlify(message);
const prefixHex = ethers.hexlify(ethers.toUtf8Bytes(MessagePrefix));

let prefixedMessage: Uint8Array
let digest: string;

if (messageHex.startsWith(prefixHex)) {
prefixedMessage = ethers.getBytes(messageBytes)
// We check if the message is already prefixed with EIP-191
// This will avoid breaking changes for codebases where the message is already prefixed
if (messageHex.substring(2).startsWith(prefixHex.substring(2))) {
digest = ethers.keccak256(message);
} else {
prefixedMessage = ethers.getBytes(
ethers.concat([eip191prefix, ethers.toUtf8Bytes(String(messageBytes.length)), messageBytes])
)
digest = ethers.hashMessage(message);
}

return this.signDigest(ethers.keccak256(prefixedMessage), chainId, true, cantValidateBehavior)
return this.signDigest(digest, chainId, true, cantValidateBehavior);
}

async signTransactions(
Expand Down
55 changes: 40 additions & 15 deletions packages/account/tests/account.spec.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { walletContracts } from '@0xsequence/abi'
import { commons, v1, v2 } from '@0xsequence/core'
import { migrator } from '@0xsequence/migration'
import { NetworkConfig } from '@0xsequence/network'
import type { migrator } from '@0xsequence/migration'
import type { NetworkConfig } from '@0xsequence/network'
import { LocalRelayer, Relayer } from '@0xsequence/relayer'
import { tracker, trackers } from '@0xsequence/sessions'
import { Orchestrator } from '@0xsequence/signhub'
import * as utils from '@0xsequence/tests'
import { Wallet } from '@0xsequence/wallet'
import * as chai from 'chai'
import chaiAsPromised from 'chai-as-promised'
import { ethers } from 'ethers'
import { concat, ethers, MessagePrefix, toUtf8Bytes } from 'ethers'
import hardhat from 'hardhat'

import { Account } from '../src/account'
Expand Down Expand Up @@ -284,7 +284,7 @@ describe('Account', () => {

const valid = await commons.EIP1271.isValidEIP1271Signature(
account.address,
ethers.keccak256(msg),
ethers.hashMessage(msg),
sig,
networks[0].provider!
)
Expand All @@ -300,7 +300,7 @@ describe('Account', () => {

const valid = await commons.EIP1271.isValidEIP1271Signature(
accountOuter.address,
ethers.keccak256(msg),
ethers.hashMessage(msg),
sig,
networks[0].provider!
)
Expand Down Expand Up @@ -369,7 +369,7 @@ describe('Account', () => {
const msg = ethers.toUtf8Bytes('Hello World')
const sig = await account.signMessage(msg, networks[0].chainId, 'eip6492')

const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.keccak256(msg), sig)
const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.hashMessage(msg), sig)

expect(valid).to.be.true
})
Expand All @@ -382,7 +382,7 @@ describe('Account', () => {

const valid = await accountOuter
.reader(networks[0].chainId)
.isValidSignature(accountOuter.address, ethers.keccak256(msg), sig)
.isValidSignature(accountOuter.address, ethers.hashMessage(msg), sig)

expect(valid).to.be.true
})
Expand Down Expand Up @@ -423,7 +423,7 @@ describe('Account', () => {

const valid = await accountOuter
.reader(networks[0].chainId)
.isValidSignature(accountOuter.address, ethers.keccak256(msg), sig)
.isValidSignature(accountOuter.address, ethers.hashMessage(msg), sig)

expect(valid).to.be.true
})
Expand Down Expand Up @@ -573,7 +573,32 @@ describe('Account', () => {

const valid = await commons.EIP1271.isValidEIP1271Signature(
account.address,
ethers.keccak256(msg),
ethers.hashMessage(msg),
sig,
networks[0].provider!
)

expect(valid).to.be.true
})

it('Should sign a message, already prefixed with EIP-191', async () => {
const msg = ethers.toUtf8Bytes('Hello World')

const prefixedMessage = concat([
toUtf8Bytes(MessagePrefix),
toUtf8Bytes(String(msg.length)),
msg
])

const sig = await account.signMessage(prefixedMessage, networks[0].chainId)

const canOnchainValidate = await account.status(networks[0].chainId).then(s => s.canOnchainValidate)
expect(canOnchainValidate).to.be.false
await account.doBootstrap(networks[0].chainId)

const valid = await commons.EIP1271.isValidEIP1271Signature(
account.address,
ethers.hashMessage(msg),
sig,
networks[0].provider!
)
Expand Down Expand Up @@ -627,7 +652,7 @@ describe('Account', () => {

const valid = await commons.EIP1271.isValidEIP1271Signature(
account.address,
ethers.keccak256(msg),
ethers.hashMessage(msg),
sig,
networks[0].provider!
)
Expand Down Expand Up @@ -705,7 +730,7 @@ describe('Account', () => {

const valid = await commons.EIP1271.isValidEIP1271Signature(
account.address,
ethers.keccak256(msg),
ethers.hashMessage(msg),
sig,
networks[0].provider!
)
Expand Down Expand Up @@ -1281,7 +1306,7 @@ describe('Account', () => {
const msg = ethers.toUtf8Bytes('I like that you are reading our tests')
const sig = await account.signMessage(msg, networks[0].chainId, 'eip6492')

const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.keccak256(msg), sig)
const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.hashMessage(msg), sig)

expect(valid).to.be.true
})
Expand All @@ -1297,7 +1322,7 @@ describe('Account', () => {
const msg = ethers.toUtf8Bytes('Sending a hug')
const sig = await account.signMessage(msg, networks[0].chainId, 'ignore')

const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.keccak256(msg), sig)
const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.hashMessage(msg), sig)

expect(valid).to.be.false
})
Expand All @@ -1316,7 +1341,7 @@ describe('Account', () => {
const msg = ethers.toUtf8Bytes('Everything seems to be working fine so far')
const sig = await account.signMessage(msg, networks[0].chainId, 'eip6492')

const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.keccak256(msg), sig)
const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.hashMessage(msg), sig)

expect(valid).to.be.true
})
Expand Down Expand Up @@ -1350,7 +1375,7 @@ describe('Account', () => {

const msg = ethers.toUtf8Bytes('Everything seems to be working fine so far')
const sig = await account.signMessage(msg, networks[0].chainId, 'ignore')
const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.keccak256(msg), sig)
const valid = await account.reader(networks[0].chainId).isValidSignature(account.address, ethers.hashMessage(msg), sig)

expect(valid).to.be.false
})
Expand Down

0 comments on commit f8101d8

Please sign in to comment.