Commit 3af9c7a9 authored by smartcontracts's avatar smartcontracts Committed by GitHub

feat(sdk): remove ICrossChainMessenger (#3244)

Removes the ICrossChainMessenger interface. We don't have a strong
reason to maintain this interface and it introduces complexity to the
process of developing the SDK. With the interface, we are required to
make changes to multiple files when we simply want to change the
CrossChainMessenger class. We are also not maintaing multiple
implementations of the CrossChainMessenger that would make the interface
useful.
Co-authored-by: default avatarmergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent 9f784756
---
'@eth-optimism/sdk': minor
---
Removes the ICrossChainMessenger interface to speed up SDK development.
/* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable @typescript-eslint/no-unused-vars */
import { ethers, Contract, Overrides, BigNumber } from 'ethers' import { ethers, Overrides, BigNumber } from 'ethers'
import { TransactionRequest, BlockTag } from '@ethersproject/abstract-provider' import { TransactionRequest, BlockTag } from '@ethersproject/abstract-provider'
import { predeploys, getContractInterface } from '@eth-optimism/contracts' import { predeploys } from '@eth-optimism/contracts'
import { hexStringEquals } from '@eth-optimism/core-utils' import { hexStringEquals } from '@eth-optimism/core-utils'
import { import {
......
...@@ -16,9 +16,9 @@ import { predeploys } from '@eth-optimism/contracts' ...@@ -16,9 +16,9 @@ import { predeploys } from '@eth-optimism/contracts'
import { getContractInterface } from '@eth-optimism/contracts-bedrock' import { getContractInterface } from '@eth-optimism/contracts-bedrock'
import { hexStringEquals } from '@eth-optimism/core-utils' import { hexStringEquals } from '@eth-optimism/core-utils'
import { CrossChainMessenger } from '../cross-chain-messenger'
import { import {
IBridgeAdapter, IBridgeAdapter,
ICrossChainMessenger,
NumberLike, NumberLike,
AddressLike, AddressLike,
TokenBridgeMessage, TokenBridgeMessage,
...@@ -30,7 +30,7 @@ import { toAddress } from '../utils' ...@@ -30,7 +30,7 @@ import { toAddress } from '../utils'
* Bridge adapter for any token bridge that uses the standard token bridge interface. * Bridge adapter for any token bridge that uses the standard token bridge interface.
*/ */
export class StandardBridgeAdapter implements IBridgeAdapter { export class StandardBridgeAdapter implements IBridgeAdapter {
public messenger: ICrossChainMessenger public messenger: CrossChainMessenger
public l1Bridge: Contract public l1Bridge: Contract
public l2Bridge: Contract public l2Bridge: Contract
...@@ -43,7 +43,7 @@ export class StandardBridgeAdapter implements IBridgeAdapter { ...@@ -43,7 +43,7 @@ export class StandardBridgeAdapter implements IBridgeAdapter {
* @param opts.l2Bridge L2 bridge contract. * @param opts.l2Bridge L2 bridge contract.
*/ */
constructor(opts: { constructor(opts: {
messenger: ICrossChainMessenger messenger: CrossChainMessenger
l1Bridge: AddressLike l1Bridge: AddressLike
l2Bridge: AddressLike l2Bridge: AddressLike
}) { }) {
......
...@@ -31,7 +31,6 @@ import * as rlp from 'rlp' ...@@ -31,7 +31,6 @@ import * as rlp from 'rlp'
import { import {
CoreCrossChainMessage, CoreCrossChainMessage,
ICrossChainMessenger,
OEContracts, OEContracts,
OEContractsLike, OEContractsLike,
MessageLike, MessageLike,
...@@ -67,17 +66,55 @@ import { ...@@ -67,17 +66,55 @@ import {
CHAIN_BLOCK_TIMES, CHAIN_BLOCK_TIMES,
} from './utils' } from './utils'
export class CrossChainMessenger implements ICrossChainMessenger { export class CrossChainMessenger {
/**
* Provider connected to the L1 chain.
*/
public l1SignerOrProvider: Signer | Provider public l1SignerOrProvider: Signer | Provider
/**
* Provider connected to the L2 chain.
*/
public l2SignerOrProvider: Signer | Provider public l2SignerOrProvider: Signer | Provider
/**
* Chain ID for the L1 network.
*/
public l1ChainId: number public l1ChainId: number
/**
* Chain ID for the L2 network.
*/
public l2ChainId: number public l2ChainId: number
/**
* Contract objects attached to their respective providers and addresses.
*/
public contracts: OEContracts public contracts: OEContracts
/**
* List of custom bridges for the given network.
*/
public bridges: BridgeAdapters public bridges: BridgeAdapters
/**
* Number of blocks before a deposit is considered confirmed.
*/
public depositConfirmationBlocks: number public depositConfirmationBlocks: number
/**
* Estimated average L1 block time in seconds.
*/
public l1BlockTimeSeconds: number public l1BlockTimeSeconds: number
/**
* Whether or not Bedrock compatibility is enabled.
*/
public bedrock: boolean public bedrock: boolean
/**
* Parameters for the L2OutputOracle contract.
*/
private _l2OutputOracleParameters: L2OutputOracleParameters private _l2OutputOracleParameters: L2OutputOracleParameters
/** /**
...@@ -142,6 +179,9 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -142,6 +179,9 @@ export class CrossChainMessenger implements ICrossChainMessenger {
}) })
} }
/**
* Provider connected to the L1 chain.
*/
get l1Provider(): Provider { get l1Provider(): Provider {
if (Provider.isProvider(this.l1SignerOrProvider)) { if (Provider.isProvider(this.l1SignerOrProvider)) {
return this.l1SignerOrProvider return this.l1SignerOrProvider
...@@ -150,6 +190,9 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -150,6 +190,9 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Provider connected to the L2 chain.
*/
get l2Provider(): Provider { get l2Provider(): Provider {
if (Provider.isProvider(this.l2SignerOrProvider)) { if (Provider.isProvider(this.l2SignerOrProvider)) {
return this.l2SignerOrProvider return this.l2SignerOrProvider
...@@ -158,6 +201,9 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -158,6 +201,9 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Signer connected to the L1 chain.
*/
get l1Signer(): Signer { get l1Signer(): Signer {
if (Provider.isProvider(this.l1SignerOrProvider)) { if (Provider.isProvider(this.l1SignerOrProvider)) {
throw new Error(`messenger has no L1 signer`) throw new Error(`messenger has no L1 signer`)
...@@ -166,6 +212,9 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -166,6 +212,9 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Signer connected to the L2 chain.
*/
get l2Signer(): Signer { get l2Signer(): Signer {
if (Provider.isProvider(this.l2SignerOrProvider)) { if (Provider.isProvider(this.l2SignerOrProvider)) {
throw new Error(`messenger has no L2 signer`) throw new Error(`messenger has no L2 signer`)
...@@ -174,6 +223,11 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -174,6 +223,11 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Accesses the L2OutputOracle parameters, with caching to avoid unnecessary requests.
*
* @returns The L2OutputOracle parameters.
*/
public async getL2OutputOracleParameters(): Promise<L2OutputOracleParameters> { public async getL2OutputOracleParameters(): Promise<L2OutputOracleParameters> {
if (this._l2OutputOracleParameters) { if (this._l2OutputOracleParameters) {
return this._l2OutputOracleParameters return this._l2OutputOracleParameters
...@@ -194,6 +248,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -194,6 +248,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return this._l2OutputOracleParameters return this._l2OutputOracleParameters
} }
/**
* Retrieves all cross chain messages sent within a given transaction.
*
* @param transaction Transaction hash or receipt to find messages from.
* @param opts Options object.
* @param opts.direction Direction to search for messages in. If not provided, will attempt to
* automatically search both directions under the assumption that a transaction hash will only
* exist on one chain. If the hash exists on both chains, will throw an error.
* @returns All cross chain messages sent within the transaction.
*/
public async getMessagesByTransaction( public async getMessagesByTransaction(
transaction: TransactionLike, transaction: TransactionLike,
opts: { opts: {
...@@ -295,6 +359,14 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -295,6 +359,14 @@ export class CrossChainMessenger implements ICrossChainMessenger {
// `) // `)
// } // }
/**
* Finds the appropriate bridge adapter for a given L1<>L2 token pair. Will throw if no bridges
* support the token pair or if more than one bridge supports the token pair.
*
* @param l1Token L1 token address.
* @param l2Token L2 token address.
* @returns The appropriate bridge adapter for the given token pair.
*/
public async getBridgeForTokenPair( public async getBridgeForTokenPair(
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike l2Token: AddressLike
...@@ -317,6 +389,17 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -317,6 +389,17 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return bridges[0] return bridges[0]
} }
/**
* Gets all deposits for a given address.
*
* @param address Address to search for messages from.
* @param opts Options object.
* @param opts.fromBlock Block to start searching for messages from. If not provided, will start
* from the first block (block #0).
* @param opts.toBlock Block to stop searching for messages at. If not provided, will stop at the
* latest known block ("latest").
* @returns All deposit token bridge messages sent by the given address.
*/
public async getDepositsByAddress( public async getDepositsByAddress(
address: AddressLike, address: AddressLike,
opts: { opts: {
...@@ -340,6 +423,17 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -340,6 +423,17 @@ export class CrossChainMessenger implements ICrossChainMessenger {
}) })
} }
/**
* Gets all withdrawals for a given address.
*
* @param address Address to search for messages from.
* @param opts Options object.
* @param opts.fromBlock Block to start searching for messages from. If not provided, will start
* from the first block (block #0).
* @param opts.toBlock Block to stop searching for messages at. If not provided, will stop at the
* latest known block ("latest").
* @returns All withdrawal token bridge messages sent by the given address.
*/
public async getWithdrawalsByAddress( public async getWithdrawalsByAddress(
address: AddressLike, address: AddressLike,
opts: { opts: {
...@@ -363,6 +457,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -363,6 +457,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
}) })
} }
/**
* Resolves a MessageLike into a CrossChainMessage object.
* Unlike other coercion functions, this function is stateful and requires making additional
* requests. For now I'm going to keep this function here, but we could consider putting a
* similar function inside of utils/coercion.ts if people want to use this without having to
* create an entire CrossChainProvider object.
*
* @param message MessageLike to resolve into a CrossChainMessage.
* @returns Message coerced into a CrossChainMessage.
*/
public async toCrossChainMessage( public async toCrossChainMessage(
message: MessageLike message: MessageLike
): Promise<CrossChainMessage> { ): Promise<CrossChainMessage> {
...@@ -416,6 +520,12 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -416,6 +520,12 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Retrieves the status of a particular message as an enum.
*
* @param message Cross chain message to check the status of.
* @returns Status of the message.
*/
public async getMessageStatus(message: MessageLike): Promise<MessageStatus> { public async getMessageStatus(message: MessageLike): Promise<MessageStatus> {
const resolved = await this.toCrossChainMessage(message) const resolved = await this.toCrossChainMessage(message)
const receipt = await this.getMessageReceipt(resolved) const receipt = await this.getMessageReceipt(resolved)
...@@ -469,6 +579,13 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -469,6 +579,13 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Finds the receipt of the transaction that executed a particular cross chain message.
*
* @param message Message to find the receipt of.
* @returns CrossChainMessage receipt including receipt of the transaction that relayed the
* given message.
*/
public async getMessageReceipt( public async getMessageReceipt(
message: MessageLike message: MessageLike
): Promise<MessageReceipt> { ): Promise<MessageReceipt> {
...@@ -534,6 +651,18 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -534,6 +651,18 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return null return null
} }
/**
* Waits for a message to be executed and returns the receipt of the transaction that executed
* the given message.
*
* @param message Message to wait for.
* @param opts Options to pass to the waiting function.
* @param opts.confirmations Number of transaction confirmations to wait for before returning.
* @param opts.pollIntervalMs Number of milliseconds to wait between polling for the receipt.
* @param opts.timeoutMs Milliseconds to wait before timing out.
* @returns CrossChainMessage receipt including receipt of the transaction that relayed the
* given message.
*/
public async waitForMessageReceipt( public async waitForMessageReceipt(
message: MessageLike, message: MessageLike,
opts: { opts: {
...@@ -560,6 +689,18 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -560,6 +689,18 @@ export class CrossChainMessenger implements ICrossChainMessenger {
throw new Error(`timed out waiting for message receipt`) throw new Error(`timed out waiting for message receipt`)
} }
/**
* Waits until the status of a given message changes to the expected status. Note that if the
* status of the given message changes to a status that implies the expected status, this will
* still return. If the status of the message changes to a status that exclues the expected
* status, this will throw an error.
*
* @param message Message to wait for.
* @param status Expected status of the message.
* @param opts Options to pass to the waiting function.
* @param opts.pollIntervalMs Number of milliseconds to wait when polling.
* @param opts.timeoutMs Milliseconds to wait before timing out.
*/
public async waitForMessageStatus( public async waitForMessageStatus(
message: MessageLike, message: MessageLike,
status: MessageStatus, status: MessageStatus,
...@@ -627,6 +768,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -627,6 +768,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
throw new Error(`timed out waiting for message status change`) throw new Error(`timed out waiting for message status change`)
} }
/**
* Estimates the amount of gas required to fully execute a given message on L2. Only applies to
* L1 => L2 messages. You would supply this gas limit when sending the message to L2.
*
* @param message Message get a gas estimate for.
* @param opts Options object.
* @param opts.bufferPercent Percentage of gas to add to the estimate. Defaults to 20.
* @param opts.from Address to use as the sender.
* @returns Estimates L2 gas limit.
*/
public async estimateL2MessageGasLimit( public async estimateL2MessageGasLimit(
message: MessageRequestLike, message: MessageRequestLike,
opts?: { opts?: {
...@@ -660,6 +811,15 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -660,6 +811,15 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return estimate.mul(100 + bufferPercent).div(100) return estimate.mul(100 + bufferPercent).div(100)
} }
/**
* Returns the estimated amount of time before the message can be executed. When this is a
* message being sent to L1, this will return the estimated time until the message will complete
* its challenge period. When this is a message being sent to L2, this will return the estimated
* amount of time until the message will be picked up and executed on L2.
*
* @param message Message to estimate the time remaining for.
* @returns Estimated amount of time remaining (in seconds) before the message can be executed.
*/
public async estimateMessageWaitTimeSeconds( public async estimateMessageWaitTimeSeconds(
message: MessageLike message: MessageLike
): Promise<number> { ): Promise<number> {
...@@ -719,6 +879,11 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -719,6 +879,11 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Queries the current challenge period in seconds from the StateCommitmentChain.
*
* @returns Current challenge period in seconds.
*/
public async getChallengePeriodSeconds(): Promise<number> { public async getChallengePeriodSeconds(): Promise<number> {
const challengePeriod = this.bedrock const challengePeriod = this.bedrock
? await this.contracts.l1.OptimismPortal.FINALIZATION_PERIOD_SECONDS() ? await this.contracts.l1.OptimismPortal.FINALIZATION_PERIOD_SECONDS()
...@@ -726,6 +891,12 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -726,6 +891,12 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return challengePeriod.toNumber() return challengePeriod.toNumber()
} }
/**
* Returns the Bedrock output root that corresponds to the given message.
*
* @param message Message to get the Bedrock output root for.
* @returns Bedrock output root.
*/
public async getMessageBedrockOutput( public async getMessageBedrockOutput(
message: MessageLike message: MessageLike
): Promise<BedrockOutputData | null> { ): Promise<BedrockOutputData | null> {
...@@ -770,6 +941,14 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -770,6 +941,14 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Returns the state root that corresponds to a given message. This is the state root for the
* block in which the transaction was included, as published to the StateCommitmentChain. If the
* state root for the given message has not been published yet, this function returns null.
*
* @param message Message to find a state root for.
* @returns State root for the block in which the message was created.
*/
public async getMessageStateRoot( public async getMessageStateRoot(
message: MessageLike message: MessageLike
): Promise<StateRoot | null> { ): Promise<StateRoot | null> {
...@@ -821,6 +1000,13 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -821,6 +1000,13 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Returns the StateBatchAppended event that was emitted when the batch with a given index was
* created. Returns null if no such event exists (the batch has not been submitted).
*
* @param batchIndex Index of the batch to find an event for.
* @returns StateBatchAppended event for the batch, or null if no such batch exists.
*/
public async getStateBatchAppendedEventByBatchIndex( public async getStateBatchAppendedEventByBatchIndex(
batchIndex: number batchIndex: number
): Promise<ethers.Event | null> { ): Promise<ethers.Event | null> {
...@@ -840,6 +1026,13 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -840,6 +1026,13 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Returns the StateBatchAppended event for the batch that includes the transaction with the
* given index. Returns null if no such event exists.
*
* @param transactionIndex Index of the L2 transaction to find an event for.
* @returns StateBatchAppended event for the batch that includes the given transaction by index.
*/
public async getStateBatchAppendedEventByTransactionIndex( public async getStateBatchAppendedEventByTransactionIndex(
transactionIndex: number transactionIndex: number
): Promise<ethers.Event | null> { ): Promise<ethers.Event | null> {
...@@ -899,6 +1092,13 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -899,6 +1092,13 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return batchEvent return batchEvent
} }
/**
* Returns information about the state root batch that included the state root for the given
* transaction by index. Returns null if no such state root has been published yet.
*
* @param transactionIndex Index of the L2 transaction to find a state root batch for.
* @returns State root batch for the given transaction index, or null if none exists yet.
*/
public async getStateRootBatchByTransactionIndex( public async getStateRootBatchByTransactionIndex(
transactionIndex: number transactionIndex: number
): Promise<StateRootBatch | null> { ): Promise<StateRootBatch | null> {
...@@ -928,6 +1128,12 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -928,6 +1128,12 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Generates the proof required to finalize an L2 to L1 message.
*
* @param message Message to generate a proof for.
* @returns Proof that can be used to finalize the message.
*/
public async getMessageProof( public async getMessageProof(
message: MessageLike message: MessageLike
): Promise<CrossChainMessageProof> { ): Promise<CrossChainMessageProof> {
...@@ -980,6 +1186,12 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -980,6 +1186,12 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Generates the bedrock proof required to finalize an L2 to L1 message.
*
* @param message Message to generate a proof for.
* @returns Proof that can be used to finalize the message.
*/
public async getBedrockMessageProof( public async getBedrockMessageProof(
message: MessageLike message: MessageLike
): Promise< ): Promise<
...@@ -1112,6 +1324,17 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1112,6 +1324,17 @@ export class CrossChainMessenger implements ICrossChainMessenger {
] ]
} }
/**
* Sends a given cross chain message. Where the message is sent depends on the direction attached
* to the message itself.
*
* @param message Cross chain message to send.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the message sending transaction.
*/
public async sendMessage( public async sendMessage(
message: CrossChainMessageRequest, message: CrossChainMessageRequest,
opts?: { opts?: {
...@@ -1128,6 +1351,17 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1128,6 +1351,17 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
} }
/**
* Resends a given cross chain message with a different gas limit. Only applies to L1 to L2
* messages. If provided an L2 to L1 message, this function will throw an error.
*
* @param message Cross chain message to resend.
* @param messageGasLimit New gas limit to use for the message.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the message resending transaction.
*/
public async resendMessage( public async resendMessage(
message: MessageLike, message: MessageLike,
messageGasLimit: NumberLike, messageGasLimit: NumberLike,
...@@ -1145,6 +1379,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1145,6 +1379,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
} }
/**
* Finalizes a cross chain message that was sent from L2 to L1. Only applicable for L2 to L1
* messages. Will throw an error if the message has not completed its challenge period yet.
*
* @param message Message to finalize.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the finalization transaction.
*/
public async finalizeMessage( public async finalizeMessage(
message: MessageLike, message: MessageLike,
opts?: { opts?: {
...@@ -1157,6 +1401,17 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1157,6 +1401,17 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
} }
/**
* Deposits some ETH into the L2 chain.
*
* @param amount Amount of ETH to deposit (in wei).
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the deposit transaction.
*/
public async depositETH( public async depositETH(
amount: NumberLike, amount: NumberLike,
opts?: { opts?: {
...@@ -1171,6 +1426,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1171,6 +1426,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
} }
/**
* Withdraws some ETH back to the L1 chain.
*
* @param amount Amount of ETH to withdraw.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the withdraw transaction.
*/
public async withdrawETH( public async withdrawETH(
amount: NumberLike, amount: NumberLike,
opts?: { opts?: {
...@@ -1184,6 +1449,15 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1184,6 +1449,15 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
} }
/**
* Queries the account's approval amount for a given L1 token.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param opts Additional options.
* @param opts.signer Optional signer to get the approval for.
* @returns Amount of tokens approved for deposits from the account.
*/
public async approval( public async approval(
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
...@@ -1195,6 +1469,17 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1195,6 +1469,17 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return bridge.approval(l1Token, l2Token, opts?.signer || this.l1Signer) return bridge.approval(l1Token, l2Token, opts?.signer || this.l1Signer)
} }
/**
* Approves a deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
public async approveERC20( public async approveERC20(
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
...@@ -1214,6 +1499,19 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1214,6 +1499,19 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
} }
/**
* Deposits some ERC20 tokens into the L2 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to deposit.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the deposit transaction.
*/
public async depositERC20( public async depositERC20(
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
...@@ -1235,6 +1533,18 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1235,6 +1533,18 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
} }
/**
* Withdraws some ERC20 tokens back to the L1 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to withdraw.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the withdraw transaction.
*/
public async withdrawERC20( public async withdrawERC20(
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
...@@ -1255,7 +1565,21 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1255,7 +1565,21 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
} }
/**
* Object that holds the functions that generate transactions to be signed by the user.
* Follows the pattern used by ethers.js.
*/
populateTransaction = { populateTransaction = {
/**
* Generates a transaction that sends a given cross chain message. This transaction can be signed
* and executed by a signer.
*
* @param message Cross chain message to send.
* @param opts Additional options.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to send the message.
*/
sendMessage: async ( sendMessage: async (
message: CrossChainMessageRequest, message: CrossChainMessageRequest,
opts?: { opts?: {
...@@ -1280,6 +1604,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1280,6 +1604,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
}, },
/**
* Generates a transaction that resends a given cross chain message. Only applies to L1 to L2
* messages. This transaction can be signed and executed by a signer.
*
* @param message Cross chain message to resend.
* @param messageGasLimit New gas limit to use for the message.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to resend the message.
*/
resendMessage: async ( resendMessage: async (
message: MessageLike, message: MessageLike,
messageGasLimit: NumberLike, messageGasLimit: NumberLike,
...@@ -1318,6 +1652,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1318,6 +1652,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
}, },
/**
* Generates a message finalization transaction that can be signed and executed. Only
* applicable for L2 to L1 messages. Will throw an error if the message has not completed
* its challenge period yet.
*
* @param message Message to generate the finalization transaction for.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to finalize the message.
*/
finalizeMessage: async ( finalizeMessage: async (
message: MessageLike, message: MessageLike,
opts?: { opts?: {
...@@ -1374,6 +1718,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1374,6 +1718,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
}, },
/**
* Generates a transaction for depositing some ETH into the L2 chain.
*
* @param amount Amount of ETH to deposit.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to deposit the ETH.
*/
depositETH: async ( depositETH: async (
amount: NumberLike, amount: NumberLike,
opts?: { opts?: {
...@@ -1390,6 +1744,15 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1390,6 +1744,15 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
}, },
/**
* Generates a transaction for withdrawing some ETH back to the L1 chain.
*
* @param amount Amount of ETH to withdraw.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to withdraw the ETH.
*/
withdrawETH: async ( withdrawETH: async (
amount: NumberLike, amount: NumberLike,
opts?: { opts?: {
...@@ -1405,6 +1768,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1405,6 +1768,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
}, },
/**
* Generates a transaction for approving some tokens to deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approveERC20: async ( approveERC20: async (
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
...@@ -1417,6 +1790,18 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1417,6 +1790,18 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return bridge.populateTransaction.approve(l1Token, l2Token, amount, opts) return bridge.populateTransaction.approve(l1Token, l2Token, amount, opts)
}, },
/**
* Generates a transaction for depositing some ERC20 tokens into the L2 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to deposit.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to deposit the tokens.
*/
depositERC20: async ( depositERC20: async (
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
...@@ -1431,6 +1816,17 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1431,6 +1816,17 @@ export class CrossChainMessenger implements ICrossChainMessenger {
return bridge.populateTransaction.deposit(l1Token, l2Token, amount, opts) return bridge.populateTransaction.deposit(l1Token, l2Token, amount, opts)
}, },
/**
* Generates a transaction for withdrawing some ERC20 tokens back to the L1 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to withdraw.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to withdraw the tokens.
*/
withdrawERC20: async ( withdrawERC20: async (
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
...@@ -1445,7 +1841,20 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1445,7 +1841,20 @@ export class CrossChainMessenger implements ICrossChainMessenger {
}, },
} }
/**
* Object that holds the functions that estimates the gas required for a given transaction.
* Follows the pattern used by ethers.js.
*/
estimateGas = { estimateGas = {
/**
* Estimates gas required to send a cross chain message.
*
* @param message Cross chain message to send.
* @param opts Additional options.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
sendMessage: async ( sendMessage: async (
message: CrossChainMessageRequest, message: CrossChainMessageRequest,
opts?: { opts?: {
...@@ -1461,6 +1870,15 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1461,6 +1870,15 @@ export class CrossChainMessenger implements ICrossChainMessenger {
} }
}, },
/**
* Estimates gas required to resend a cross chain message. Only applies to L1 to L2 messages.
*
* @param message Cross chain message to resend.
* @param messageGasLimit New gas limit to use for the message.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
resendMessage: async ( resendMessage: async (
message: MessageLike, message: MessageLike,
messageGasLimit: NumberLike, messageGasLimit: NumberLike,
...@@ -1477,6 +1895,14 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1477,6 +1895,14 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
}, },
/**
* Estimates gas required to finalize a cross chain message. Only applies to L2 to L1 messages.
*
* @param message Message to generate the finalization transaction for.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
finalizeMessage: async ( finalizeMessage: async (
message: MessageLike, message: MessageLike,
opts?: { opts?: {
...@@ -1488,6 +1914,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1488,6 +1914,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
}, },
/**
* Estimates gas required to deposit some ETH into the L2 chain.
*
* @param amount Amount of ETH to deposit.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
depositETH: async ( depositETH: async (
amount: NumberLike, amount: NumberLike,
opts?: { opts?: {
...@@ -1501,6 +1937,15 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1501,6 +1937,15 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
}, },
/**
* Estimates gas required to withdraw some ETH back to the L1 chain.
*
* @param amount Amount of ETH to withdraw.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
withdrawETH: async ( withdrawETH: async (
amount: NumberLike, amount: NumberLike,
opts?: { opts?: {
...@@ -1513,6 +1958,16 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1513,6 +1958,16 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
}, },
/**
* Estimates gas required to approve some tokens to deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approveERC20: async ( approveERC20: async (
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
...@@ -1531,6 +1986,18 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1531,6 +1986,18 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
}, },
/**
* Estimates gas required to deposit some ERC20 tokens into the L2 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to deposit.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
depositERC20: async ( depositERC20: async (
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
...@@ -1551,6 +2018,17 @@ export class CrossChainMessenger implements ICrossChainMessenger { ...@@ -1551,6 +2018,17 @@ export class CrossChainMessenger implements ICrossChainMessenger {
) )
}, },
/**
* Estimates gas required to withdraw some ERC20 tokens back to the L1 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to withdraw.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
withdrawERC20: async ( withdrawERC20: async (
l1Token: AddressLike, l1Token: AddressLike,
l2Token: AddressLike, l2Token: AddressLike,
......
...@@ -13,7 +13,7 @@ import { ...@@ -13,7 +13,7 @@ import {
} from '@ethersproject/abstract-provider' } from '@ethersproject/abstract-provider'
import { NumberLike, AddressLike, TokenBridgeMessage } from './types' import { NumberLike, AddressLike, TokenBridgeMessage } from './types'
import { ICrossChainMessenger } from './cross-chain-messenger' import { CrossChainMessenger } from '../cross-chain-messenger'
/** /**
* Represents an adapter for an L1<>L2 token bridge. Each custom bridge currently needs its own * Represents an adapter for an L1<>L2 token bridge. Each custom bridge currently needs its own
...@@ -23,7 +23,7 @@ export interface IBridgeAdapter { ...@@ -23,7 +23,7 @@ export interface IBridgeAdapter {
/** /**
* Provider used to make queries related to cross-chain interactions. * Provider used to make queries related to cross-chain interactions.
*/ */
messenger: ICrossChainMessenger messenger: CrossChainMessenger
/** /**
* L1 bridge contract. * L1 bridge contract.
......
import { Event, BigNumber, Overrides, CallOverrides } from 'ethers'
import {
Provider,
BlockTag,
TransactionRequest,
TransactionResponse,
} from '@ethersproject/abstract-provider'
import { Signer } from '@ethersproject/abstract-signer'
import {
BedrockCrossChainMessageProof,
BedrockOutputData,
} from '@eth-optimism/core-utils'
import {
CoreCrossChainMessage,
MessageLike,
MessageRequestLike,
TransactionLike,
AddressLike,
NumberLike,
CrossChainMessage,
CrossChainMessageRequest,
CrossChainMessageProof,
MessageDirection,
MessageStatus,
TokenBridgeMessage,
OEContracts,
MessageReceipt,
StateRoot,
StateRootBatch,
BridgeAdapters,
} from './types'
import { IBridgeAdapter } from './bridge-adapter'
/**
* Handles L1/L2 interactions.
*/
export interface ICrossChainMessenger {
/**
* Provider connected to the L1 chain.
*/
l1SignerOrProvider: Signer | Provider
/**
* Provider connected to the L2 chain.
*/
l2SignerOrProvider: Signer | Provider
/**
* Chain ID for the L1 network.
*/
l1ChainId: number
/**
* Chain ID for the L2 network.
*/
l2ChainId: number
/**
* Contract objects attached to their respective providers and addresses.
*/
contracts: OEContracts
/**
* List of custom bridges for the given network.
*/
bridges: BridgeAdapters
/**
* Provider connected to the L1 chain.
*/
l1Provider: Provider
/**
* Provider connected to the L2 chain.
*/
l2Provider: Provider
/**
* Signer connected to the L1 chain.
*/
l1Signer: Signer
/**
* Signer connected to the L2 chain.
*/
l2Signer: Signer
/**
* Number of blocks before a deposit is considered confirmed.
*/
depositConfirmationBlocks: number
/**
* Estimated average L1 block time in seconds.
*/
l1BlockTimeSeconds: number
/**
* Whether or not Bedrock compatibility is enabled.
*/
bedrock: boolean
/**
* Retrieves all cross chain messages sent within a given transaction.
*
* @param transaction Transaction hash or receipt to find messages from.
* @param opts Options object.
* @param opts.direction Direction to search for messages in. If not provided, will attempt to
* automatically search both directions under the assumption that a transaction hash will only
* exist on one chain. If the hash exists on both chains, will throw an error.
* @returns All cross chain messages sent within the transaction.
*/
getMessagesByTransaction(
transaction: TransactionLike,
opts?: {
direction?: MessageDirection
}
): Promise<CrossChainMessage[]>
// TODO: Make this function work. Likely requires indexer or the function will be prohibitively
// slow to query all of the necessary data.
//
// /**
// * Retrieves all cross chain messages sent by a particular address.
// *
// * @param address Address to search for messages from.
// * @param opts Options object.
// * @param opts.direction Direction to search for messages in. If not provided, will attempt to
// * find all messages in both directions.
// * @param opts.fromBlock Block to start searching for messages from. If not provided, will start
// * from the first block (block #0).
// * @param opts.toBlock Block to stop searching for messages at. If not provided, will stop at the
// * latest known block ("latest").
// * @returns All cross chain messages sent by the particular address.
// */
// getMessagesByAddress(
// address: AddressLike,
// opts?: {
// direction?: MessageDirection
// fromBlock?: NumberLike
// toBlock?: NumberLike
// }
// ): Promise<CrossChainMessage[]>
/**
* Finds the appropriate bridge adapter for a given L1<>L2 token pair. Will throw if no bridges
* support the token pair or if more than one bridge supports the token pair.
*
* @param l1Token L1 token address.
* @param l2Token L2 token address.
* @returns The appropriate bridge adapter for the given token pair.
*/
getBridgeForTokenPair(
l1Token: AddressLike,
l2Token: AddressLike
): Promise<IBridgeAdapter>
/**
* Gets all deposits for a given address.
*
* @param address Address to search for messages from.
* @param opts Options object.
* @param opts.fromBlock Block to start searching for messages from. If not provided, will start
* from the first block (block #0).
* @param opts.toBlock Block to stop searching for messages at. If not provided, will stop at the
* latest known block ("latest").
* @returns All deposit token bridge messages sent by the given address.
*/
getDepositsByAddress(
address: AddressLike,
opts?: {
fromBlock?: BlockTag
toBlock?: BlockTag
}
): Promise<TokenBridgeMessage[]>
/**
* Gets all withdrawals for a given address.
*
* @param address Address to search for messages from.
* @param opts Options object.
* @param opts.fromBlock Block to start searching for messages from. If not provided, will start
* from the first block (block #0).
* @param opts.toBlock Block to stop searching for messages at. If not provided, will stop at the
* latest known block ("latest").
* @returns All withdrawal token bridge messages sent by the given address.
*/
getWithdrawalsByAddress(
address: AddressLike,
opts?: {
fromBlock?: BlockTag
toBlock?: BlockTag
}
): Promise<TokenBridgeMessage[]>
/**
* Resolves a MessageLike into a CrossChainMessage object.
* Unlike other coercion functions, this function is stateful and requires making additional
* requests. For now I'm going to keep this function here, but we could consider putting a
* similar function inside of utils/coercion.ts if people want to use this without having to
* create an entire CrossChainProvider object.
*
* @param message MessageLike to resolve into a CrossChainMessage.
* @returns Message coerced into a CrossChainMessage.
*/
toCrossChainMessage(message: MessageLike): Promise<CrossChainMessage>
/**
* Retrieves the status of a particular message as an enum.
*
* @param message Cross chain message to check the status of.
* @returns Status of the message.
*/
getMessageStatus(message: MessageLike): Promise<MessageStatus>
/**
* Finds the receipt of the transaction that executed a particular cross chain message.
*
* @param message Message to find the receipt of.
* @returns CrossChainMessage receipt including receipt of the transaction that relayed the
* given message.
*/
getMessageReceipt(message: MessageLike): Promise<MessageReceipt>
/**
* Waits for a message to be executed and returns the receipt of the transaction that executed
* the given message.
*
* @param message Message to wait for.
* @param opts Options to pass to the waiting function.
* @param opts.confirmations Number of transaction confirmations to wait for before returning.
* @param opts.pollIntervalMs Number of milliseconds to wait between polling for the receipt.
* @param opts.timeoutMs Milliseconds to wait before timing out.
* @returns CrossChainMessage receipt including receipt of the transaction that relayed the
* given message.
*/
waitForMessageReceipt(
message: MessageLike,
opts?: {
confirmations?: number
pollIntervalMs?: number
timeoutMs?: number
}
): Promise<MessageReceipt>
/**
* Waits until the status of a given message changes to the expected status. Note that if the
* status of the given message changes to a status that implies the expected status, this will
* still return. If the status of the message changes to a status that exclues the expected
* status, this will throw an error.
*
* @param message Message to wait for.
* @param status Expected status of the message.
* @param opts Options to pass to the waiting function.
* @param opts.pollIntervalMs Number of milliseconds to wait when polling.
* @param opts.timeoutMs Milliseconds to wait before timing out.
*/
waitForMessageStatus(
message: MessageLike,
status: MessageStatus,
opts?: {
pollIntervalMs?: number
timeoutMs?: number
}
): Promise<void>
/**
* Estimates the amount of gas required to fully execute a given message on L2. Only applies to
* L1 => L2 messages. You would supply this gas limit when sending the message to L2.
*
* @param message Message get a gas estimate for.
* @param opts Options object.
* @param opts.bufferPercent Percentage of gas to add to the estimate. Defaults to 20.
* @param opts.from Address to use as the sender.
* @returns Estimates L2 gas limit.
*/
estimateL2MessageGasLimit(
message: MessageRequestLike,
opts?: {
bufferPercent?: number
from?: string
}
): Promise<BigNumber>
/**
* Returns the estimated amount of time before the message can be executed. When this is a
* message being sent to L1, this will return the estimated time until the message will complete
* its challenge period. When this is a message being sent to L2, this will return the estimated
* amount of time until the message will be picked up and executed on L2.
*
* @param message Message to estimate the time remaining for.
* @returns Estimated amount of time remaining (in seconds) before the message can be executed.
*/
estimateMessageWaitTimeSeconds(message: MessageLike): Promise<number>
/**
* Queries the current challenge period in seconds from the StateCommitmentChain.
*
* @returns Current challenge period in seconds.
*/
getChallengePeriodSeconds(): Promise<number>
/**
* Returns the Bedrock output root that corresponds to the given message.
*
* @param message Message to get the Bedrock output root for.
* @returns Bedrock output root.
*/
getMessageBedrockOutput(
message: MessageLike
): Promise<BedrockOutputData | null>
/**
* Returns the state root that corresponds to a given message. This is the state root for the
* block in which the transaction was included, as published to the StateCommitmentChain. If the
* state root for the given message has not been published yet, this function returns null.
*
* @param message Message to find a state root for.
* @returns State root for the block in which the message was created.
*/
getMessageStateRoot(message: MessageLike): Promise<StateRoot | null>
/**
* Returns the StateBatchAppended event that was emitted when the batch with a given index was
* created. Returns null if no such event exists (the batch has not been submitted).
*
* @param batchIndex Index of the batch to find an event for.
* @returns StateBatchAppended event for the batch, or null if no such batch exists.
*/
getStateBatchAppendedEventByBatchIndex(
batchIndex: number
): Promise<Event | null>
/**
* Returns the StateBatchAppended event for the batch that includes the transaction with the
* given index. Returns null if no such event exists.
*
* @param transactionIndex Index of the L2 transaction to find an event for.
* @returns StateBatchAppended event for the batch that includes the given transaction by index.
*/
getStateBatchAppendedEventByTransactionIndex(
transactionIndex: number
): Promise<Event | null>
/**
* Returns information about the state root batch that included the state root for the given
* transaction by index. Returns null if no such state root has been published yet.
*
* @param transactionIndex Index of the L2 transaction to find a state root batch for.
* @returns State root batch for the given transaction index, or null if none exists yet.
*/
getStateRootBatchByTransactionIndex(
transactionIndex: number
): Promise<StateRootBatch | null>
/**
* Generates the proof required to finalize an L2 to L1 message.
*
* @param message Message to generate a proof for.
* @returns Proof that can be used to finalize the message.
*/
getMessageProof(message: MessageLike): Promise<CrossChainMessageProof>
/**
* Generates the bedrock proof required to finalize an L2 to L1 message.
*
* @param message Message to generate a proof for.
* @returns Proof that can be used to finalize the message.
*/
getBedrockMessageProof(
message: MessageLike
): Promise<
[BedrockCrossChainMessageProof, BedrockOutputData, CoreCrossChainMessage]
>
/**
* Sends a given cross chain message. Where the message is sent depends on the direction attached
* to the message itself.
*
* @param message Cross chain message to send.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the message sending transaction.
*/
sendMessage(
message: CrossChainMessageRequest,
opts?: {
signer?: Signer
l2GasLimit?: NumberLike
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Resends a given cross chain message with a different gas limit. Only applies to L1 to L2
* messages. If provided an L2 to L1 message, this function will throw an error.
*
* @param message Cross chain message to resend.
* @param messageGasLimit New gas limit to use for the message.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the message resending transaction.
*/
resendMessage(
message: MessageLike,
messageGasLimit: NumberLike,
opts?: {
signer?: Signer
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Finalizes a cross chain message that was sent from L2 to L1. Only applicable for L2 to L1
* messages. Will throw an error if the message has not completed its challenge period yet.
*
* @param message Message to finalize.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the finalization transaction.
*/
finalizeMessage(
message: MessageLike,
opts?: {
signer?: Signer
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Deposits some ETH into the L2 chain.
*
* @param amount Amount of ETH to deposit (in wei).
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the deposit transaction.
*/
depositETH(
amount: NumberLike,
opts?: {
signer?: Signer
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Withdraws some ETH back to the L1 chain.
*
* @param amount Amount of ETH to withdraw.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the withdraw transaction.
*/
withdrawETH(
amount: NumberLike,
opts?: {
signer?: Signer
recipient?: AddressLike
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Queries the account's approval amount for a given L1 token.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param opts Additional options.
* @param opts.signer Optional signer to get the approval for.
* @returns Amount of tokens approved for deposits from the account.
*/
approval(
l1Token: AddressLike,
l2Token: AddressLike,
opts?: {
signer?: Signer
}
): Promise<BigNumber>
/**
* Approves a deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approveERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
signer?: Signer
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Deposits some ERC20 tokens into the L2 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to deposit.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the deposit transaction.
*/
depositERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
signer?: Signer
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Withdraws some ERC20 tokens back to the L1 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to withdraw.
* @param opts Additional options.
* @param opts.signer Optional signer to use to send the transaction.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the withdraw transaction.
*/
withdrawERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
signer?: Signer
recipient?: AddressLike
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Object that holds the functions that generate transactions to be signed by the user.
* Follows the pattern used by ethers.js.
*/
populateTransaction: {
/**
* Generates a transaction that sends a given cross chain message. This transaction can be signed
* and executed by a signer.
*
* @param message Cross chain message to send.
* @param opts Additional options.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to send the message.
*/
sendMessage: (
message: CrossChainMessageRequest,
opts?: {
l2GasLimit?: NumberLike
overrides?: Overrides
}
) => Promise<TransactionRequest>
/**
* Generates a transaction that resends a given cross chain message. Only applies to L1 to L2
* messages. This transaction can be signed and executed by a signer.
*
* @param message Cross chain message to resend.
* @param messageGasLimit New gas limit to use for the message.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to resend the message.
*/
resendMessage(
message: MessageLike,
messageGasLimit: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest>
/**
* Generates a message finalization transaction that can be signed and executed. Only
* applicable for L2 to L1 messages. Will throw an error if the message has not completed
* its challenge period yet.
*
* @param message Message to generate the finalization transaction for.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to finalize the message.
*/
finalizeMessage(
message: MessageLike,
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest>
/**
* Generates a transaction for approving some tokens to deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approveERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest>
/**
* Generates a transaction for depositing some ETH into the L2 chain.
*
* @param amount Amount of ETH to deposit.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to deposit the ETH.
*/
depositETH(
amount: NumberLike,
opts?: {
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: Overrides
}
): Promise<TransactionRequest>
/**
* Generates a transaction for withdrawing some ETH back to the L1 chain.
*
* @param amount Amount of ETH to withdraw.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to withdraw the ETH.
*/
withdrawETH(
amount: NumberLike,
opts?: {
recipient?: AddressLike
overrides?: Overrides
}
): Promise<TransactionRequest>
/**
* Generates a transaction for depositing some ERC20 tokens into the L2 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to deposit.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to deposit the tokens.
*/
depositERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: Overrides
}
): Promise<TransactionRequest>
/**
* Generates a transaction for withdrawing some ERC20 tokens back to the L1 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to withdraw.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to withdraw the tokens.
*/
withdrawERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
recipient?: AddressLike
overrides?: Overrides
}
): Promise<TransactionRequest>
}
/**
* Object that holds the functions that estimates the gas required for a given transaction.
* Follows the pattern used by ethers.js.
*/
estimateGas: {
/**
* Estimates gas required to send a cross chain message.
*
* @param message Cross chain message to send.
* @param opts Additional options.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
sendMessage: (
message: CrossChainMessageRequest,
opts?: {
l2GasLimit?: NumberLike
overrides?: CallOverrides
}
) => Promise<BigNumber>
/**
* Estimates gas required to resend a cross chain message. Only applies to L1 to L2 messages.
*
* @param message Cross chain message to resend.
* @param messageGasLimit New gas limit to use for the message.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
resendMessage(
message: MessageLike,
messageGasLimit: NumberLike,
opts?: {
overrides?: CallOverrides
}
): Promise<BigNumber>
/**
* Estimates gas required to finalize a cross chain message. Only applies to L2 to L1 messages.
*
* @param message Message to generate the finalization transaction for.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
finalizeMessage(
message: MessageLike,
opts?: {
overrides?: CallOverrides
}
): Promise<BigNumber>
/**
* Estimates gas required to approve some tokens to deposit into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to approve.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approveERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: CallOverrides
}
): Promise<BigNumber>
/**
* Estimates gas required to deposit some ETH into the L2 chain.
*
* @param amount Amount of ETH to deposit.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
depositETH(
amount: NumberLike,
opts?: {
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: CallOverrides
}
): Promise<BigNumber>
/**
* Estimates gas required to withdraw some ETH back to the L1 chain.
*
* @param amount Amount of ETH to withdraw.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
withdrawETH(
amount: NumberLike,
opts?: {
recipient?: AddressLike
overrides?: CallOverrides
}
): Promise<BigNumber>
/**
* Estimates gas required to deposit some ERC20 tokens into the L2 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to deposit.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L2. Defaults to sender.
* @param opts.l2GasLimit Optional gas limit to use for the transaction on L2.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
depositERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: CallOverrides
}
): Promise<BigNumber>
/**
* Estimates gas required to withdraw some ERC20 tokens back to the L1 chain.
*
* @param l1Token Address of the L1 token.
* @param l2Token Address of the L2 token.
* @param amount Amount to withdraw.
* @param opts Additional options.
* @param opts.recipient Optional address to receive the funds on L1. Defaults to sender.
* @param opts.overrides Optional transaction overrides.
* @returns Gas estimate for the transaction.
*/
withdrawERC20(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
recipient?: AddressLike
overrides?: CallOverrides
}
): Promise<BigNumber>
}
}
export * from './bridge-adapter' export * from './bridge-adapter'
export * from './cross-chain-messenger'
export * from './l2-provider' export * from './l2-provider'
export * from './types' export * from './types'
...@@ -6,7 +6,7 @@ import { ...@@ -6,7 +6,7 @@ import {
import { Signer } from '@ethersproject/abstract-signer' import { Signer } from '@ethersproject/abstract-signer'
import { Contract, BigNumber } from 'ethers' import { Contract, BigNumber } from 'ethers'
import { ICrossChainMessenger } from './cross-chain-messenger' import { CrossChainMessenger } from '../cross-chain-messenger'
import { IBridgeAdapter } from './bridge-adapter' import { IBridgeAdapter } from './bridge-adapter'
/** /**
...@@ -103,7 +103,7 @@ export interface OEContractsLike { ...@@ -103,7 +103,7 @@ export interface OEContractsLike {
export interface BridgeAdapterData { export interface BridgeAdapterData {
[name: string]: { [name: string]: {
Adapter: new (opts: { Adapter: new (opts: {
messenger: ICrossChainMessenger messenger: CrossChainMessenger
l1Bridge: AddressLike l1Bridge: AddressLike
l2Bridge: AddressLike l2Bridge: AddressLike
}) => IBridgeAdapter }) => IBridgeAdapter
......
...@@ -4,6 +4,7 @@ import { ethers, Contract } from 'ethers' ...@@ -4,6 +4,7 @@ import { ethers, Contract } from 'ethers'
import { toAddress } from './coercion' import { toAddress } from './coercion'
import { DeepPartial } from './type-utils' import { DeepPartial } from './type-utils'
import { CrossChainMessenger } from '../cross-chain-messenger'
import { import {
OEContracts, OEContracts,
OEL1Contracts, OEL1Contracts,
...@@ -13,7 +14,6 @@ import { ...@@ -13,7 +14,6 @@ import {
AddressLike, AddressLike,
BridgeAdapters, BridgeAdapters,
BridgeAdapterData, BridgeAdapterData,
ICrossChainMessenger,
L2ChainID, L2ChainID,
} from '../interfaces' } from '../interfaces'
import { import {
...@@ -323,7 +323,7 @@ export const getAllOEContracts = ( ...@@ -323,7 +323,7 @@ export const getAllOEContracts = (
*/ */
export const getBridgeAdapters = ( export const getBridgeAdapters = (
l2ChainId: number, l2ChainId: number,
messenger: ICrossChainMessenger, messenger: CrossChainMessenger,
opts?: { opts?: {
overrides?: BridgeAdapterData overrides?: BridgeAdapterData
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment