Commit c71b87de authored by smartcontracts's avatar smartcontracts Committed by GitHub

maint: remove sdk and add temporary tasks package (#10794)

Removes the SDK and adds a small temporary package that houses
the two Hardhat tasks that the bedrock-devnet relies on. It's
generally much nicer to have a dedicated place for the SDK in the
ecosystem repository rather than having it exist in two places
awkwardly simply because of these two tasks.
parent bee1ecbb
...@@ -840,23 +840,6 @@ jobs: ...@@ -840,23 +840,6 @@ jobs:
paths: paths:
- "/root/.cache/go-build" - "/root/.cache/go-build"
depcheck:
docker:
- image: <<pipeline.parameters.ci_builder_image>>
steps:
- checkout
- attach_workspace: { at: "." }
- restore_cache:
name: Restore PNPM Package Cache
keys:
- pnpm-packages-v2-{{ checksum "pnpm-lock.yaml" }}
- check-changed:
patterns: packages
- run:
name: Check sdk
command: npx depcheck
working_directory: packages/sdk
l1-geth-version-check: l1-geth-version-check:
docker: docker:
- image: <<pipeline.parameters.ci_builder_image>> - image: <<pipeline.parameters.ci_builder_image>>
...@@ -1632,9 +1615,6 @@ workflows: ...@@ -1632,9 +1615,6 @@ workflows:
dependencies: "contracts-bedrock" dependencies: "contracts-bedrock"
requires: requires:
- pnpm-monorepo - pnpm-monorepo
- depcheck:
requires:
- pnpm-monorepo
- go-lint-test-build: - go-lint-test-build:
name: proxyd-tests name: proxyd-tests
binary_name: proxyd binary_name: proxyd
......
...@@ -71,7 +71,7 @@ def main(): ...@@ -71,7 +71,7 @@ def main():
devnet_config_path = pjoin(deploy_config_dir, 'devnetL1.json') devnet_config_path = pjoin(deploy_config_dir, 'devnetL1.json')
devnet_config_template_path = pjoin(deploy_config_dir, 'devnetL1-template.json') devnet_config_template_path = pjoin(deploy_config_dir, 'devnetL1-template.json')
ops_chain_ops = pjoin(monorepo_dir, 'op-chain-ops') ops_chain_ops = pjoin(monorepo_dir, 'op-chain-ops')
sdk_dir = pjoin(monorepo_dir, 'packages', 'sdk') tasks_dir = pjoin(monorepo_dir, 'packages', 'devnet-tasks')
paths = Bunch( paths = Bunch(
mono_repo_dir=monorepo_dir, mono_repo_dir=monorepo_dir,
...@@ -86,7 +86,7 @@ def main(): ...@@ -86,7 +86,7 @@ def main():
op_node_dir=op_node_dir, op_node_dir=op_node_dir,
ops_bedrock_dir=ops_bedrock_dir, ops_bedrock_dir=ops_bedrock_dir,
ops_chain_ops=ops_chain_ops, ops_chain_ops=ops_chain_ops,
sdk_dir=sdk_dir, tasks_dir=tasks_dir,
genesis_l1_path=pjoin(devnet_dir, 'genesis-l1.json'), genesis_l1_path=pjoin(devnet_dir, 'genesis-l1.json'),
genesis_l2_path=pjoin(devnet_dir, 'genesis-l2.json'), genesis_l2_path=pjoin(devnet_dir, 'genesis-l2.json'),
allocs_l1_path=pjoin(devnet_dir, 'allocs-l1.json'), allocs_l1_path=pjoin(devnet_dir, 'allocs-l1.json'),
...@@ -334,11 +334,11 @@ def devnet_test(paths): ...@@ -334,11 +334,11 @@ def devnet_test(paths):
CommandPreset('erc20-test', CommandPreset('erc20-test',
['npx', 'hardhat', 'deposit-erc20', '--network', 'devnetL1', ['npx', 'hardhat', 'deposit-erc20', '--network', 'devnetL1',
'--l1-contracts-json-path', paths.addresses_json_path, '--signer-index', '14'], '--l1-contracts-json-path', paths.addresses_json_path, '--signer-index', '14'],
cwd=paths.sdk_dir, timeout=8*60), cwd=paths.tasks_dir, timeout=8*60),
CommandPreset('eth-test', CommandPreset('eth-test',
['npx', 'hardhat', 'deposit-eth', '--network', 'devnetL1', ['npx', 'hardhat', 'deposit-eth', '--network', 'devnetL1',
'--l1-contracts-json-path', paths.addresses_json_path, '--signer-index', '15'], '--l1-contracts-json-path', paths.addresses_json_path, '--signer-index', '15'],
cwd=paths.sdk_dir, timeout=8*60) cwd=paths.tasks_dir, timeout=8*60)
], max_workers=1) ], max_workers=1)
......
module.exports = {
extends: '../../.eslintrc.js',
overrides: [],
}
(The MIT License) (The MIT License)
Copyright 2020-2021 Optimism Copyright 2020-2024 Optimism
Permission is hereby granted, free of charge, to any person obtaining Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the a copy of this software and associated documentation files (the
......
# @eth-optimism/devnet-tasks
`@eth-optimism/devnet-tasks` is a temporary package that hosts two [Hardhat](https://hardhat.org/) tasks used within the [`bedrock-devnet`](/bedrock-devnet/README.md) and is not meant to be published to NPM.
You can generally disregard this package unless you are working on the `bedrock-devnet`.
...@@ -5,7 +5,7 @@ import '@nomiclabs/hardhat-ethers' ...@@ -5,7 +5,7 @@ import '@nomiclabs/hardhat-ethers'
import '@nomiclabs/hardhat-waffle' import '@nomiclabs/hardhat-waffle'
import 'hardhat-deploy' import 'hardhat-deploy'
import './tasks' import './src/tasks'
const config: HardhatUserConfig = { const config: HardhatUserConfig = {
solidity: { solidity: {
......
{ {
"name": "@eth-optimism/sdk", "private": true,
"name": "@eth-optimism/devnet-tasks",
"version": "3.3.1", "version": "3.3.1",
"description": "[Optimism] Tools for working with Optimism", "description": "[Optimism] Hardhat devnet testing tasks",
"main": "dist/index", "main": "dist/index",
"types": "dist/index", "types": "dist/index",
"files": [ "files": [
...@@ -17,17 +18,15 @@ ...@@ -17,17 +18,15 @@
"lint:fix": "pnpm lint:check --fix", "lint:fix": "pnpm lint:check --fix",
"pre-commit": "lint-staged", "pre-commit": "lint-staged",
"test": "hardhat test", "test": "hardhat test",
"test:next": "vitest",
"test:next:run": "vitest run",
"test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json", "test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json",
"autogen:docs": "typedoc --out docs src/index.ts" "autogen:docs": "typedoc --out docs src/index.ts"
}, },
"keywords": [ "keywords": [
"optimism", "optimism",
"ethereum", "ethereum",
"sdk" "devnet"
], ],
"homepage": "https://github.com/ethereum-optimism/optimism/tree/develop/packages/sdk#readme", "homepage": "https://github.com/ethereum-optimism/optimism/tree/develop/packages/devnet-tasks#readme",
"license": "MIT", "license": "MIT",
"author": "Optimism PBC", "author": "Optimism PBC",
"repository": { "repository": {
...@@ -35,38 +34,21 @@ ...@@ -35,38 +34,21 @@
"url": "https://github.com/ethereum-optimism/optimism.git" "url": "https://github.com/ethereum-optimism/optimism.git"
}, },
"devDependencies": { "devDependencies": {
"@ethersproject/abstract-provider": "^5.7.0",
"@ethersproject/abstract-signer": "^5.7.0",
"@ethersproject/transactions": "^5.7.0",
"@nomiclabs/hardhat-ethers": "^2.2.3", "@nomiclabs/hardhat-ethers": "^2.2.3",
"@nomiclabs/hardhat-waffle": "^2.0.1", "@nomiclabs/hardhat-waffle": "^2.0.1",
"@types/chai": "^4.3.11",
"@types/chai-as-promised": "^7.1.8",
"@types/mocha": "^10.0.6",
"@types/node": "^20.11.17", "@types/node": "^20.11.17",
"@types/semver": "^7.5.7",
"chai-as-promised": "^7.1.1",
"ethereum-waffle": "^4.0.10", "ethereum-waffle": "^4.0.10",
"ethers": "^5.7.2", "ethers": "^5.7.2",
"hardhat": "^2.20.1", "hardhat": "^2.20.1",
"hardhat-deploy": "^0.12.2", "hardhat-deploy": "^0.12.2",
"isomorphic-fetch": "^3.0.0",
"mocha": "^10.2.0",
"nyc": "^15.1.0", "nyc": "^15.1.0",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"typedoc": "^0.25.7", "typedoc": "^0.25.7",
"typescript": "^5.4.5", "typescript": "^5.4.5"
"viem": "^2.8.13",
"vitest": "^1.2.2",
"zod": "^3.22.4"
}, },
"dependencies": { "dependencies": {
"@eth-optimism/contracts": "0.6.0",
"@eth-optimism/core-utils": "^0.13.2", "@eth-optimism/core-utils": "^0.13.2",
"lodash": "^4.17.21", "@eth-optimism/sdk": "^3.3.1"
"merkletreejs": "^0.3.11",
"rlp": "^2.2.7",
"semver": "^7.6.0"
}, },
"peerDependencies": { "peerDependencies": {
"ethers": "^5" "ethers": "^5"
......
...@@ -7,24 +7,23 @@ import '@nomiclabs/hardhat-ethers' ...@@ -7,24 +7,23 @@ import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy' import 'hardhat-deploy'
import { Event, Contract, Wallet, providers, utils, ethers } from 'ethers' import { Event, Contract, Wallet, providers, utils, ethers } from 'ethers'
import { predeploys, sleep } from '@eth-optimism/core-utils' import { predeploys, sleep } from '@eth-optimism/core-utils'
import Artifact__WETH9 from '@eth-optimism/sdk/dist/forge-artifacts/WETH9.json'
import Artifact__WETH9 from '../src/forge-artifacts/WETH9.json' import Artifact__OptimismMintableERC20TokenFactory from '@eth-optimism/sdk/dist/forge-artifacts/OptimismMintableERC20Factory.json'
import Artifact__OptimismMintableERC20TokenFactory from '../src/forge-artifacts/OptimismMintableERC20Factory.json' import Artifact__OptimismMintableERC20Token from '@eth-optimism/sdk/dist/forge-artifacts/OptimismMintableERC20.json'
import Artifact__OptimismMintableERC20Token from '../src/forge-artifacts/OptimismMintableERC20.json' import Artifact__L2ToL1MessagePasser from '@eth-optimism/sdk/dist/forge-artifacts/L2ToL1MessagePasser.json'
import Artifact__L2ToL1MessagePasser from '../src/forge-artifacts/L2ToL1MessagePasser.json' import Artifact__L2CrossDomainMessenger from '@eth-optimism/sdk/dist/forge-artifacts/L2CrossDomainMessenger.json'
import Artifact__L2CrossDomainMessenger from '../src/forge-artifacts/L2CrossDomainMessenger.json' import Artifact__L2StandardBridge from '@eth-optimism/sdk/dist/forge-artifacts/L2StandardBridge.json'
import Artifact__L2StandardBridge from '../src/forge-artifacts/L2StandardBridge.json' import Artifact__OptimismPortal from '@eth-optimism/sdk/dist/forge-artifacts/OptimismPortal.json'
import Artifact__OptimismPortal from '../src/forge-artifacts/OptimismPortal.json' import Artifact__L1CrossDomainMessenger from '@eth-optimism/sdk/dist/forge-artifacts/L1CrossDomainMessenger.json'
import Artifact__L1CrossDomainMessenger from '../src/forge-artifacts/L1CrossDomainMessenger.json' import Artifact__L1StandardBridge from '@eth-optimism/sdk/dist/forge-artifacts/L1StandardBridge.json'
import Artifact__L1StandardBridge from '../src/forge-artifacts/L1StandardBridge.json' import Artifact__L2OutputOracle from '@eth-optimism/sdk/dist/forge-artifacts/L2OutputOracle.json'
import Artifact__L2OutputOracle from '../src/forge-artifacts/L2OutputOracle.json'
import { import {
CrossChainMessenger, CrossChainMessenger,
MessageStatus, MessageStatus,
CONTRACT_ADDRESSES, CONTRACT_ADDRESSES,
OEContractsLike, OEContractsLike,
DEFAULT_L2_CONTRACT_ADDRESSES, DEFAULT_L2_CONTRACT_ADDRESSES,
} from '../src' } from '@eth-optimism/sdk/dist'
const deployWETH9 = async ( const deployWETH9 = async (
hre: HardhatRuntimeEnvironment, hre: HardhatRuntimeEnvironment,
......
import { promises as fs } from 'fs' import { promises as fs } from 'fs'
import { task, types } from 'hardhat/config' import { task, types } from 'hardhat/config'
import { Deployment } from 'hardhat-deploy/types'
import '@nomiclabs/hardhat-ethers' import '@nomiclabs/hardhat-ethers'
import 'hardhat-deploy' import 'hardhat-deploy'
import { Deployment } from 'hardhat-deploy/types'
import { predeploys } from '@eth-optimism/core-utils' import { predeploys } from '@eth-optimism/core-utils'
import { providers, utils, ethers } from 'ethers' import { providers, utils, ethers } from 'ethers'
import Artifact__L2ToL1MessagePasser from '@eth-optimism/sdk/dist/forge-artifacts/L2ToL1MessagePasser.json'
import Artifact__L2ToL1MessagePasser from '../src/forge-artifacts/L2ToL1MessagePasser.json' import Artifact__L2CrossDomainMessenger from '@eth-optimism/sdk/dist/forge-artifacts/L2CrossDomainMessenger.json'
import Artifact__L2CrossDomainMessenger from '../src/forge-artifacts/L2CrossDomainMessenger.json' import Artifact__L2StandardBridge from '@eth-optimism/sdk/dist/forge-artifacts/L2StandardBridge.json'
import Artifact__L2StandardBridge from '../src/forge-artifacts/L2StandardBridge.json' import Artifact__OptimismPortal from '@eth-optimism/sdk/dist/forge-artifacts/OptimismPortal.json'
import Artifact__OptimismPortal from '../src/forge-artifacts/OptimismPortal.json' import Artifact__L1CrossDomainMessenger from '@eth-optimism/sdk/dist/forge-artifacts/L1CrossDomainMessenger.json'
import Artifact__L1CrossDomainMessenger from '../src/forge-artifacts/L1CrossDomainMessenger.json' import Artifact__L1StandardBridge from '@eth-optimism/sdk/dist/forge-artifacts/L1StandardBridge.json'
import Artifact__L1StandardBridge from '../src/forge-artifacts/L1StandardBridge.json' import Artifact__L2OutputOracle from '@eth-optimism/sdk/dist/forge-artifacts/L2OutputOracle.json'
import Artifact__L2OutputOracle from '../src/forge-artifacts/L2OutputOracle.json'
import { import {
CrossChainMessenger, CrossChainMessenger,
MessageStatus, MessageStatus,
CONTRACT_ADDRESSES, CONTRACT_ADDRESSES,
OEContractsLike, OEContractsLike,
DEFAULT_L2_CONTRACT_ADDRESSES, DEFAULT_L2_CONTRACT_ADDRESSES,
} from '../src' } from '@eth-optimism/sdk'
const { formatEther } = utils const { formatEther } = utils
......
import './deposit-eth' import './deposit-eth'
import './deposit-erc20' import './deposit-erc20'
import './finalize-withdrawal'
module.exports = {
extends: '../../.eslintrc.js',
overrides: [
{
files: ['src/**/*.ts'],
rules: {
'no-restricted-imports': [
'error',
'assert',
'buffer',
'child_process',
'cluster',
'crypto',
'dgram',
'dns',
'domain',
'events',
'freelist',
'fs',
'http',
'https',
'module',
'net',
'os',
'path',
'punycode',
'querystring',
'readline',
'repl',
'smalloc',
'stream',
'string_decoder',
'sys',
'timers',
'tls',
'tracing',
'tty',
'url',
'util',
'vm',
'zlib',
],
},
},
],
}
This diff is collapsed.
# @eth-optimism/sdk
[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/master/graph/badge.svg?token=0VTG7PG7YR&flag=sdk-tests)](https://codecov.io/gh/ethereum-optimism/optimism)
The `@eth-optimism/sdk` package provides a set of tools for interacting with Optimism.
## Warning!!!
`@eth-optimism/sdk` has been superseded by `op-viem`. For most developers we suggest you migrate to [viem](https://viem.sh/op-stack) which has native built in op-stack support built in. It also has additional benefits.
**The OP Labs team has no plans to add new features @eth-optimism/sdk and it is in maintenance mode**
If you are already using the sdk you are safe as it will continue to be maintained.
- an intuitive API that learned from this package and is now revamped
- great treeshaking with a 10x+ improvement to bundlesize
- Better performance
- Updated to use the latest op stack contracts. At times it will save you gas compared to using viem.
If viem does not have what you need please let us know by opening an issue in the viem repo or here. Letting us know helps us advocate to upstream more functionality to viem. Viem is missing the following functionality:
- ERC20 support
If viem doesn't have what you need, the extensions for viem, [op-viem extensions](https://github.com/base-org/op-viem), likely have it too.
## Installation
```
npm install @eth-optimism/sdk
```
## Docs
You can find auto-generated API documentation over at [sdk.optimism.io](https://sdk.optimism.io).
## Contributing
Most of the core functionality is in the [CrossChainMessenger](./src/cross-chain-messenger.ts) file.
## Using the SDK
### CrossChainMessenger
The [`CrossChainMessenger`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/sdk/src/cross-chain-messenger.ts) class simplifies the process of moving assets and data between Ethereum and Optimism.
You can use this class to, for example, initiate a withdrawal of ERC20 tokens from Optimism back to Ethereum, accurately track when the withdrawal is ready to be finalized on Ethereum, and execute the finalization transaction after the challenge period has elapsed.
The `CrossChainMessenger` can handle deposits and withdrawals of ETH and any ERC20-compatible token.
Detailed API descriptions can be found at [sdk.optimism.io](https://sdk.optimism.io/classes/crosschainmessenger).
The `CrossChainMessenger` automatically connects to all relevant contracts so complex configuration is not necessary.
### L2Provider and related utilities
The Optimism SDK includes [various utilities](https://github.com/ethereum-optimism/optimism/blob/develop/packages/sdk/src/l2-provider.ts) for handling Optimism's [transaction fee model](https://community.optimism.io/docs/developers/build/transaction-fees/).
For instance, [`estimateTotalGasCost`](https://sdk.optimism.io/modules.html#estimateTotalGasCost) will estimate the total cost (in wei) to send at transaction on Optimism including both the L2 execution cost and the L1 data cost.
You can also use the [`asL2Provider`](https://sdk.optimism.io/modules.html#asL2Provider) function to wrap an ethers Provider object into an `L2Provider` which will have all of these helper functions attached.
### Other utilities
The SDK contains other useful helper functions and constants.
For a complete list, refer to the auto-generated [SDK documentation](https://sdk.optimism.io/)
// public rpcs are heavily throttled/rate limited so replace these with rpcs with apikeys. These are meant to be testnet rpcs
// in future these will get renamed to VITE_E2E_RPC_URL_GOERLI etc.
VITE_E2E_RPC_URL_L1=https://ethereum-goerli.publicnode.com
VITE_E2E_RPC_URL_L2=https://goerli.optimism.io
\ No newline at end of file
import fetch from 'isomorphic-fetch'
// viem needs this
global.fetch = fetch
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Contract } from 'ethers'
import { hexStringEquals } from '@eth-optimism/core-utils'
import { AddressLike } from '../interfaces'
import { toAddress } from '../utils'
import { StandardBridgeAdapter } from './standard-bridge'
/**
* Bridge adapter for DAI.
*/
export class DAIBridgeAdapter extends StandardBridgeAdapter {
public async supportsTokenPair(
l1Token: AddressLike,
l2Token: AddressLike
): Promise<boolean> {
// Just need access to this ABI for this one function.
const l1Bridge = new Contract(
this.l1Bridge.address,
[
{
inputs: [],
name: 'l1Token' as const,
outputs: [
{
internalType: 'address' as const,
name: '' as const,
type: 'address' as const,
},
],
stateMutability: 'view' as const,
type: 'function' as const,
},
{
inputs: [],
name: 'l2Token' as const,
outputs: [
{
internalType: 'address' as const,
name: '' as const,
type: 'address' as const,
},
],
stateMutability: 'view' as const,
type: 'function' as const,
},
],
this.messenger.l1Provider
)
const allowedL1Token = await l1Bridge.l1Token()
if (!hexStringEquals(allowedL1Token, toAddress(l1Token))) {
return false
}
const allowedL2Token = await l1Bridge.l2Token()
if (!hexStringEquals(allowedL2Token, toAddress(l2Token))) {
return false
}
return true
}
}
/* eslint-disable @typescript-eslint/no-unused-vars */
import { Contract } from 'ethers'
import { hexStringEquals } from '@eth-optimism/core-utils'
import { AddressLike } from '../interfaces'
import { toAddress } from '../utils'
import { StandardBridgeAdapter } from './standard-bridge'
/**
* Bridge adapter for ECO.
* ECO bridge requires a separate adapter as exposes different functions than our standard bridge
*/
export class ECOBridgeAdapter extends StandardBridgeAdapter {
public async supportsTokenPair(
l1Token: AddressLike,
l2Token: AddressLike
): Promise<boolean> {
const l1Bridge = new Contract(
this.l1Bridge.address,
[
{
inputs: [],
name: 'l1Eco',
outputs: [
{
internalType: 'address',
name: '',
type: 'address',
},
],
stateMutability: 'view',
type: 'function',
},
],
this.messenger.l1Provider
)
const l2Bridge = new Contract(
this.l2Bridge.address,
[
{
inputs: [],
name: 'l2Eco',
outputs: [
{
internalType: 'contract L2ECO',
name: '',
type: 'address',
},
],
stateMutability: 'view',
type: 'function',
},
],
this.messenger.l2Provider
)
const [remoteL1Token, remoteL2Token] = await Promise.all([
l1Bridge.l1Eco(),
l2Bridge.l2Eco(),
])
if (!hexStringEquals(remoteL1Token, toAddress(l1Token))) {
return false
}
if (!hexStringEquals(remoteL2Token, toAddress(l2Token))) {
return false
}
return true
}
}
/* eslint-disable @typescript-eslint/no-unused-vars */
import { ethers, Overrides, BigNumber } from 'ethers'
import { TransactionRequest, BlockTag } from '@ethersproject/abstract-provider'
import { predeploys } from '@eth-optimism/contracts'
import { hexStringEquals } from '@eth-optimism/core-utils'
import {
NumberLike,
AddressLike,
TokenBridgeMessage,
MessageDirection,
} from '../interfaces'
import { toAddress, omit } from '../utils'
import { StandardBridgeAdapter } from './standard-bridge'
/**
* Bridge adapter for the ETH bridge.
*/
export class ETHBridgeAdapter extends StandardBridgeAdapter {
public async approval(
l1Token: AddressLike,
l2Token: AddressLike,
signer: ethers.Signer
): Promise<BigNumber> {
throw new Error(`approval not necessary for ETH bridge`)
}
public async getDepositsByAddress(
address: AddressLike,
opts?: {
fromBlock?: BlockTag
toBlock?: BlockTag
}
): Promise<TokenBridgeMessage[]> {
const events = await this.l1Bridge.queryFilter(
this.l1Bridge.filters.ETHDepositInitiated(address),
opts?.fromBlock,
opts?.toBlock
)
return events
.map((event) => {
return {
direction: MessageDirection.L1_TO_L2,
from: event.args.from,
to: event.args.to,
l1Token: ethers.constants.AddressZero,
l2Token: predeploys.OVM_ETH,
amount: event.args.amount,
data: event.args.extraData,
logIndex: event.logIndex,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
}
})
.sort((a, b) => {
// Sort descending by block number
return b.blockNumber - a.blockNumber
})
}
public async getWithdrawalsByAddress(
address: AddressLike,
opts?: {
fromBlock?: BlockTag
toBlock?: BlockTag
}
): Promise<TokenBridgeMessage[]> {
const events = await this.l2Bridge.queryFilter(
this.l2Bridge.filters.WithdrawalInitiated(undefined, undefined, address),
opts?.fromBlock,
opts?.toBlock
)
return events
.filter((event) => {
// Only find ETH withdrawals.
return (
hexStringEquals(event.args.l1Token, ethers.constants.AddressZero) &&
hexStringEquals(event.args.l2Token, predeploys.OVM_ETH)
)
})
.map((event) => {
return {
direction: MessageDirection.L2_TO_L1,
from: event.args.from,
to: event.args.to,
l1Token: event.args.l1Token,
l2Token: event.args.l2Token,
amount: event.args.amount,
data: event.args.extraData,
logIndex: event.logIndex,
blockNumber: event.blockNumber,
transactionHash: event.transactionHash,
}
})
.sort((a, b) => {
// Sort descending by block number
return b.blockNumber - a.blockNumber
})
}
public async supportsTokenPair(
l1Token: AddressLike,
l2Token: AddressLike
): Promise<boolean> {
// Only support ETH deposits and withdrawals.
return (
hexStringEquals(toAddress(l1Token), ethers.constants.AddressZero) &&
hexStringEquals(toAddress(l2Token), predeploys.OVM_ETH)
)
}
populateTransaction = {
approve: async (
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<never> => {
throw new Error(`approvals not necessary for ETH bridge`)
},
deposit: async (
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: Overrides
}
): Promise<TransactionRequest> => {
if (!(await this.supportsTokenPair(l1Token, l2Token))) {
throw new Error(`token pair not supported by bridge`)
}
if (opts?.recipient === undefined) {
return this.l1Bridge.populateTransaction.depositETH(
opts?.l2GasLimit || 200_000, // Default to 200k gas limit.
'0x', // No data.
{
...omit(opts?.overrides || {}, 'value'),
value: amount,
}
)
} else {
return this.l1Bridge.populateTransaction.depositETHTo(
toAddress(opts.recipient),
opts?.l2GasLimit || 200_000, // Default to 200k gas limit.
'0x', // No data.
{
...omit(opts?.overrides || {}, 'value'),
value: amount,
}
)
}
},
withdraw: async (
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
recipient?: AddressLike
overrides?: Overrides
}
): Promise<TransactionRequest> => {
if (!(await this.supportsTokenPair(l1Token, l2Token))) {
throw new Error(`token pair not supported by bridge`)
}
if (opts?.recipient === undefined) {
return this.l2Bridge.populateTransaction.withdraw(
toAddress(l2Token),
amount,
0, // L1 gas not required.
'0x', // No data.
{
...omit(opts?.overrides || {}, 'value'),
value: this.messenger.bedrock ? amount : 0,
}
)
} else {
return this.l2Bridge.populateTransaction.withdrawTo(
toAddress(l2Token),
toAddress(opts.recipient),
amount,
0, // L1 gas not required.
'0x', // No data.
{
...omit(opts?.overrides || {}, 'value'),
value: this.messenger.bedrock ? amount : 0,
}
)
}
},
}
}
export * from './standard-bridge'
export * from './eth-bridge'
export * from './dai-bridge'
export * from './eco-bridge'
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
export * from './interfaces'
export * from './utils'
export * from './cross-chain-messenger'
export * from './adapters'
export * from './l2-provider'
import {
Contract,
Overrides,
Signer,
BigNumber,
CallOverrides,
PayableOverrides,
} from 'ethers'
import {
TransactionRequest,
TransactionResponse,
BlockTag,
} from '@ethersproject/abstract-provider'
import { NumberLike, AddressLike, TokenBridgeMessage } from './types'
import { CrossChainMessenger } from '../cross-chain-messenger'
/**
* Represents an adapter for an L1<>L2 token bridge. Each custom bridge currently needs its own
* adapter because the bridge interface is not standardized. This may change in the future.
*/
export interface IBridgeAdapter {
/**
* Provider used to make queries related to cross-chain interactions.
*/
messenger: CrossChainMessenger
/**
* L1 bridge contract.
*/
l1Bridge: Contract
/**
* L2 bridge contract.
*/
l2Bridge: Contract
/**
* 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[]>
/**
* Checks whether the given token pair is supported by the bridge.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @returns Whether the given token pair is supported by the bridge.
*/
supportsTokenPair(
l1Token: AddressLike,
l2Token: AddressLike
): Promise<boolean>
/**
* Queries the account's approval amount for a given L1 token.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param signer Signer to query the approval for.
* @returns Amount of tokens approved for deposits from the account.
*/
approval(
l1Token: AddressLike,
l2Token: AddressLike,
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 signer Signer used to sign and send the transaction.
* @param opts Additional options.
* @param opts.overrides Optional transaction overrides.
* @returns Transaction response for the approval transaction.
*/
approve(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
signer: Signer,
opts?: {
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Deposits some tokens into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to deposit.
* @param signer Signer used to sign and send the transaction.
* @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 response for the deposit transaction.
*/
deposit(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
signer: Signer,
opts?: {
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: Overrides
}
): Promise<TransactionResponse>
/**
* Withdraws some tokens back to the L1 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token to withdraw.
* @param signer Signer used to sign and send the transaction.
* @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 response for the withdraw transaction.
*/
withdraw(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
signer: Signer,
opts?: {
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 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 that can be signed and executed to deposit the tokens.
*/
approve(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: Overrides
}
): Promise<TransactionRequest>
/**
* Generates a transaction for depositing some tokens into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token 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.
*/
deposit(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: PayableOverrides
}
): Promise<TransactionRequest>
/**
* Generates a transaction for withdrawing some tokens back to the L1 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token 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.
*/
withdraw(
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 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 Gas estimate for the transaction.
*/
approve(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
overrides?: CallOverrides
}
): Promise<BigNumber>
/**
* Estimates gas required to deposit some tokens into the L2 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token 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.
*/
deposit(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
recipient?: AddressLike
l2GasLimit?: NumberLike
overrides?: CallOverrides
}
): Promise<BigNumber>
/**
* Estimates gas required to withdraw some tokens back to the L1 chain.
*
* @param l1Token The L1 token address.
* @param l2Token The L2 token address.
* @param amount Amount of the token 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.
*/
withdraw(
l1Token: AddressLike,
l2Token: AddressLike,
amount: NumberLike,
opts?: {
recipient?: AddressLike
overrides?: CallOverrides
}
): Promise<BigNumber>
}
}
export * from './bridge-adapter'
export * from './l2-provider'
export * from './types'
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
export const assert = (condition: boolean, message: string): void => {
if (!condition) {
throw new Error(message)
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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