Skip to content

Commit 7b2e455

Browse files
committed
Relayer supports chain switching
1 parent d563266 commit 7b2e455

2 files changed

Lines changed: 45 additions & 12 deletions

File tree

packages/wallet/core/src/relayer/local.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import { FeeOption, FeeQuote, OperationStatus, Relayer } from './relayer.js'
55
type GenericProviderTransactionReceipt = 'success' | 'failed' | 'unknown'
66

77
export interface GenericProvider {
8-
sendTransaction(args: { to: string; data: string }): Promise<string>
9-
getTransactionReceipt(txHash: string): Promise<GenericProviderTransactionReceipt>
8+
sendTransaction(args: { to: string; data: string }, chainId: bigint): Promise<string>
9+
getTransactionReceipt(txHash: string, chainId: bigint): Promise<GenericProviderTransactionReceipt>
1010
}
1111

1212
export class LocalRelayer implements Relayer {
@@ -21,15 +21,33 @@ export class LocalRelayer implements Relayer {
2121
return undefined
2222
}
2323

24+
const trySwitchChain = async (chainId: bigint) => {
25+
try {
26+
await eth.request({
27+
method: 'wallet_switchEthereumChain',
28+
params: [
29+
{
30+
chainId: `0x${chainId.toString(16)}`,
31+
},
32+
],
33+
})
34+
} catch (error) {
35+
// Log and continue
36+
console.error('Error switching chain', error)
37+
}
38+
}
39+
2440
return new LocalRelayer({
25-
sendTransaction: async (args) => {
41+
sendTransaction: async (args, chainId) => {
2642
const accounts: string[] = await eth.request({ method: 'eth_requestAccounts' })
2743
const from = accounts[0]
2844
if (!from) {
2945
console.warn('No account selected, skipping local relayer')
3046
return undefined
3147
}
3248

49+
await trySwitchChain(chainId)
50+
3351
const tx = await eth.request({
3452
method: 'eth_sendTransaction',
3553
params: [
@@ -42,7 +60,9 @@ export class LocalRelayer implements Relayer {
4260
})
4361
return tx
4462
},
45-
getTransactionReceipt: async (txHash) => {
63+
getTransactionReceipt: async (txHash, chainId) => {
64+
await trySwitchChain(chainId)
65+
4666
const rpcReceipt = await eth.request({ method: 'eth_getTransactionReceipt', params: [txHash] })
4767
if (rpcReceipt) {
4868
const receipt = TransactionReceipt.fromRpc(rpcReceipt)
@@ -80,17 +100,20 @@ export class LocalRelayer implements Relayer {
80100
}
81101

82102
async relay(to: Address.Address, data: Hex.Hex, chainId: bigint, _?: FeeQuote): Promise<{ opHash: Hex.Hex }> {
83-
const txHash = await this.provider.sendTransaction({
84-
to,
85-
data,
86-
})
103+
const txHash = await this.provider.sendTransaction(
104+
{
105+
to,
106+
data,
107+
},
108+
chainId,
109+
)
87110
Hex.assert(txHash)
88111

89112
return { opHash: txHash }
90113
}
91114

92115
async status(opHash: Hex.Hex, chainId: bigint): Promise<OperationStatus> {
93-
const receipt = await this.provider.getTransactionReceipt(opHash)
116+
const receipt = await this.provider.getTransactionReceipt(opHash, chainId)
94117
if (receipt === 'unknown') {
95118
// Could be pending but we don't know
96119
return { status: 'unknown' }

packages/wallet/core/src/relayer/pk-relayer.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ export class PkRelayer implements Relayer {
1313
) {
1414
const relayerAddress = Address.fromPublicKey(Secp256k1.getPublicKey({ privateKey }))
1515
this.relayer = new LocalRelayer({
16-
sendTransaction: async (args) => {
16+
sendTransaction: async (args, chainId) => {
17+
const providerChainId = BigInt(await this.provider.request({ method: 'eth_chainId' }))
18+
if (providerChainId !== chainId) {
19+
throw new Error('Provider chain id does not match relayer chain id')
20+
}
21+
1722
const oxArgs = { ...args, to: args.to as `0x${string}`, data: args.data as `0x${string}` }
1823
// Estimate gas with a safety buffer
1924
const estimatedGas = BigInt(await this.provider.request({ method: 'eth_estimateGas', params: [oxArgs] }))
@@ -40,7 +45,6 @@ export class PkRelayer implements Relayer {
4045
)
4146

4247
// Build the relay envelope
43-
const chainId = BigInt(await this.provider.request({ method: 'eth_chainId' }))
4448
const relayEnvelope = TransactionEnvelopeEip1559.from({
4549
chainId: Number(chainId),
4650
type: 'eip1559',
@@ -66,8 +70,14 @@ export class PkRelayer implements Relayer {
6670
})
6771
return tx
6872
},
69-
getTransactionReceipt: async (txHash: string) => {
73+
getTransactionReceipt: async (txHash: string, chainId: bigint) => {
7074
Hex.assert(txHash)
75+
76+
const providerChainId = BigInt(await this.provider.request({ method: 'eth_chainId' }))
77+
if (providerChainId !== chainId) {
78+
throw new Error('Provider chain id does not match relayer chain id')
79+
}
80+
7181
const rpcReceipt = await this.provider.request({ method: 'eth_getTransactionReceipt', params: [txHash] })
7282
if (!rpcReceipt) {
7383
return 'unknown'

0 commit comments

Comments
 (0)