Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
00428c2d
Commit
00428c2d
authored
May 18, 2023
by
James Kim
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add adapter and tests for eco
parent
d79b2496
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
297 additions
and
26 deletions
+297
-26
package.json
packages/sdk/package.json
+4
-2
setupVitest.ts
packages/sdk/setupVitest.ts
+4
-0
eco-bridge.ts
packages/sdk/src/adapters/eco-bridge.ts
+73
-0
index.ts
packages/sdk/src/adapters/index.ts
+1
-0
chain-constants.ts
packages/sdk/src/utils/chain-constants.ts
+6
-2
bridgeEcoToken.spec.ts
packages/sdk/test-next/bridgeEcoToken.spec.ts
+110
-0
proveMessage.spec.ts
packages/sdk/test-next/proveMessage.spec.ts
+2
-22
ethersProviders.ts
packages/sdk/test-next/testUtils/ethersProviders.ts
+31
-0
viemClients.ts
packages/sdk/test-next/testUtils/viemClients.ts
+57
-0
vitest.config.ts
packages/sdk/vitest.config.ts
+9
-0
No files found.
packages/sdk/package.json
View file @
00428c2d
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
"lint:fix"
:
"yarn lint:check --fix"
,
"lint:fix"
:
"yarn lint:check --fix"
,
"pre-commit"
:
"lint-staged"
,
"pre-commit"
:
"lint-staged"
,
"test"
:
"hardhat test"
,
"test"
:
"hardhat test"
,
"test:next"
:
"vitest
test-next/proveMessage.spec.ts
"
,
"test:next"
:
"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"
},
},
...
@@ -48,7 +48,9 @@
...
@@ -48,7 +48,9 @@
"typedoc"
:
"^0.22.13"
,
"typedoc"
:
"^0.22.13"
,
"mocha"
:
"^10.0.0"
,
"mocha"
:
"^10.0.0"
,
"vitest"
:
"^0.28.3"
,
"vitest"
:
"^0.28.3"
,
"zod"
:
"^3.11.6"
"zod"
:
"^3.11.6"
,
"viem"
:
"^0.3.30"
,
"isomorphic-fetch"
:
"^3.0.0"
},
},
"dependencies"
:
{
"dependencies"
:
{
"@eth-optimism/contracts"
:
"0.5.40"
,
"@eth-optimism/contracts"
:
"0.5.40"
,
...
...
packages/sdk/setupVitest.ts
0 → 100644
View file @
00428c2d
import
fetch
from
'
isomorphic-fetch
'
// viem needs this
global
.
fetch
=
fetch
packages/sdk/src/adapters/eco-bridge.ts
0 → 100644
View file @
00428c2d
/* 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
:
'
ecoAddress
'
,
outputs
:
[
{
internalType
:
'
address
'
,
name
:
''
,
type
:
'
address
'
,
},
],
stateMutability
:
'
view
'
,
type
:
'
function
'
,
},
],
this
.
messenger
.
l1Provider
)
const
l2Bridge
=
new
Contract
(
this
.
l2Bridge
.
address
,
[
{
inputs
:
[],
name
:
'
l2EcoToken
'
,
outputs
:
[
{
internalType
:
'
contract L2ECO
'
,
name
:
''
,
type
:
'
address
'
,
},
],
stateMutability
:
'
view
'
,
type
:
'
function
'
,
},
],
this
.
messenger
.
l2Provider
)
const
[
remoteL1Token
,
remoteL2Token
]
=
await
Promise
.
all
([
l1Bridge
.
ecoAddress
(),
l2Bridge
.
l2EcoToken
(),
])
if
(
!
hexStringEquals
(
remoteL1Token
,
toAddress
(
l1Token
)))
{
return
false
}
if
(
!
hexStringEquals
(
remoteL2Token
,
toAddress
(
l2Token
)))
{
return
false
}
return
true
}
}
packages/sdk/src/adapters/index.ts
View file @
00428c2d
export
*
from
'
./standard-bridge
'
export
*
from
'
./standard-bridge
'
export
*
from
'
./eth-bridge
'
export
*
from
'
./eth-bridge
'
export
*
from
'
./dai-bridge
'
export
*
from
'
./dai-bridge
'
export
*
from
'
./eco-bridge
'
packages/sdk/src/utils/chain-constants.ts
View file @
00428c2d
...
@@ -12,7 +12,11 @@ import {
...
@@ -12,7 +12,11 @@ import {
OEL2ContractsLike
,
OEL2ContractsLike
,
BridgeAdapterData
,
BridgeAdapterData
,
}
from
'
../interfaces
'
}
from
'
../interfaces
'
import
{
StandardBridgeAdapter
,
DAIBridgeAdapter
}
from
'
../adapters
'
import
{
StandardBridgeAdapter
,
DAIBridgeAdapter
,
ECOBridgeAdapter
,
}
from
'
../adapters
'
export
const
DEPOSIT_CONFIRMATION_BLOCKS
:
{
export
const
DEPOSIT_CONFIRMATION_BLOCKS
:
{
[
ChainID
in
L2ChainID
]:
number
[
ChainID
in
L2ChainID
]:
number
...
@@ -206,7 +210,7 @@ export const BRIDGE_ADAPTER_DATA: {
...
@@ -206,7 +210,7 @@ export const BRIDGE_ADAPTER_DATA: {
l2Bridge
:
'
0x467194771dAe2967Aef3ECbEDD3Bf9a310C76C65
'
as
const
,
l2Bridge
:
'
0x467194771dAe2967Aef3ECbEDD3Bf9a310C76C65
'
as
const
,
},
},
ECO
:
{
ECO
:
{
Adapter
:
Standard
BridgeAdapter
,
Adapter
:
ECO
BridgeAdapter
,
l1Bridge
:
'
0x7a01E277B8fDb8CDB2A2258508514716359f44A0
'
as
const
,
l1Bridge
:
'
0x7a01E277B8fDb8CDB2A2258508514716359f44A0
'
as
const
,
l2Bridge
:
'
0x7a01E277B8fDb8CDB2A2258508514716359f44A0
'
as
const
,
l2Bridge
:
'
0x7a01E277B8fDb8CDB2A2258508514716359f44A0
'
as
const
,
},
},
...
...
packages/sdk/test-next/bridgeEcoToken.spec.ts
0 → 100644
View file @
00428c2d
import
ethers
from
'
ethers
'
import
{
describe
,
expect
,
it
}
from
'
vitest
'
import
{
l1TestClient
,
l2TestClient
,
l1PublicClient
,
l2PublicClient
,
}
from
'
./testUtils/viemClients
'
import
{
BRIDGE_ADAPTER_DATA
,
CrossChainMessenger
,
DEPOSIT_CONFIRMATION_BLOCKS
,
L2ChainID
}
from
'
../src
'
import
{
Address
,
PublicClient
,
parseEther
}
from
'
viem
'
import
{
l1Provider
,
l2Provider
}
from
'
./testUtils/ethersProviders
'
const
ECO_WHALE
:
Address
=
'
0xBd11c836279a1352ce737FbBFba36b20734B04e7
'
// TODO: use tokenlist as source of truth
const
ECO_L1_TOKEN_ADDRESS
:
Address
=
'
0x3E87d4d9E69163E7590f9b39a70853cf25e5ABE3
'
const
ECO_L2_TOKEN_ADDRESS
:
Address
=
'
0x54bBECeA38ff36D32323f8A754683C1F5433A89f
'
const
getERC20TokenBalance
=
async
(
publicClient
:
PublicClient
,
tokenAddress
:
Address
,
ownerAddress
:
Address
)
=>
{
const
result
=
await
publicClient
.
readContract
({
address
:
tokenAddress
,
abi
:
[
{
inputs
:
[{
name
:
'
owner
'
,
type
:
'
address
'
}],
name
:
'
balanceOf
'
,
outputs
:
[{
name
:
''
,
type
:
'
uint256
'
}],
stateMutability
:
'
view
'
,
type
:
'
function
'
,
}
],
functionName
:
'
balanceOf
'
,
args
:
[
ownerAddress
]
})
return
result
as
bigint
}
const
getL1ERC20TokenBalance
=
async
(
ownerAddress
:
Address
)
=>
{
return
getERC20TokenBalance
(
l1PublicClient
,
ECO_L1_TOKEN_ADDRESS
,
ownerAddress
)
}
const
getL2ERC20TokenBalance
=
async
(
ownerAddress
:
Address
)
=>
{
return
getERC20TokenBalance
(
l2PublicClient
,
ECO_L2_TOKEN_ADDRESS
,
ownerAddress
)
}
describe
(
'
ECO token
'
,
()
=>
{
it
(
'
sdk should be able to deposit to l1 bridge contract correctly
'
,
async
()
=>
{
// this code is a bit whack because of the mix of viem + ethers
// TODO: use anviljs, and use viem entirely once the sdk supports it
await
l1TestClient
.
impersonateAccount
({
address
:
ECO_WHALE
})
const
l1EcoWhaleSigner
=
await
l1Provider
.
getSigner
(
ECO_WHALE
);
const
preBridgeL1EcoWhaleBalance
=
await
getL1ERC20TokenBalance
(
ECO_WHALE
)
const
crossChainMessenger
=
new
CrossChainMessenger
({
l1SignerOrProvider
:
l1EcoWhaleSigner
,
l2SignerOrProvider
:
l2Provider
,
l1ChainId
:
5
,
l2ChainId
:
420
,
// bedrock: true,
bridges
:
BRIDGE_ADAPTER_DATA
[
L2ChainID
.
OPTIMISM_GOERLI
]
})
await
crossChainMessenger
.
approveERC20
(
ECO_L1_TOKEN_ADDRESS
,
ECO_L2_TOKEN_ADDRESS
,
ethers
.
utils
.
parseEther
(
'
0.1
'
),
)
const
txResponse
=
await
crossChainMessenger
.
depositERC20
(
ECO_L1_TOKEN_ADDRESS
,
ECO_L2_TOKEN_ADDRESS
,
ethers
.
utils
.
parseEther
(
'
0.1
'
),
)
await
txResponse
.
wait
();
const
l1EcoWhaleBalance
=
await
getL1ERC20TokenBalance
(
ECO_WHALE
)
expect
(
l1EcoWhaleBalance
).
toEqual
(
preBridgeL1EcoWhaleBalance
-
parseEther
(
'
0.1
'
))
},
20
_000
)
it
(
'
sdk should be able to withdraw into the l2 bridge contract correctly
'
,
async
()
=>
{
await
l2TestClient
.
impersonateAccount
({
address
:
ECO_WHALE
})
const
l2EcoWhaleSigner
=
await
l2Provider
.
getSigner
(
ECO_WHALE
);
const
preBridgeL2EcoWhaleBalance
=
await
getL2ERC20TokenBalance
(
ECO_WHALE
)
const
crossChainMessenger
=
new
CrossChainMessenger
({
l1SignerOrProvider
:
l1Provider
,
l2SignerOrProvider
:
l2EcoWhaleSigner
,
l1ChainId
:
5
,
l2ChainId
:
420
,
// bedrock: true,
bridges
:
BRIDGE_ADAPTER_DATA
[
L2ChainID
.
OPTIMISM_GOERLI
]
})
const
txResponse
=
await
crossChainMessenger
.
withdrawERC20
(
ECO_L1_TOKEN_ADDRESS
,
ECO_L2_TOKEN_ADDRESS
,
ethers
.
utils
.
parseEther
(
'
0.1
'
),
)
await
txResponse
.
wait
();
const
l2EcoWhaleBalance
=
await
getL2ERC20TokenBalance
(
ECO_WHALE
)
expect
(
l2EcoWhaleBalance
).
toEqual
(
preBridgeL2EcoWhaleBalance
-
parseEther
(
'
0.1
'
))
},
20
_000
)
})
packages/sdk/test-next/proveMessage.spec.ts
View file @
00428c2d
...
@@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest'
...
@@ -3,6 +3,7 @@ import { describe, expect, it } from 'vitest'
import
{
z
}
from
'
zod
'
import
{
z
}
from
'
zod
'
import
{
CrossChainMessenger
}
from
'
../src
'
import
{
CrossChainMessenger
}
from
'
../src
'
import
{
l1Provider
,
l2Provider
}
from
'
./testUtils/ethersProviders
'
/**
/**
* This test repros the bug where legacy withdrawals are not provable
* This test repros the bug where legacy withdrawals are not provable
...
@@ -48,33 +49,12 @@ transactionHash 0xd66fda632b51a8b25a9d260d70da8be57b9930c461637086152633
...
@@ -48,33 +49,12 @@ transactionHash 0xd66fda632b51a8b25a9d260d70da8be57b9930c461637086152633
transactionIndex 0
transactionIndex 0
type
type
*/
*/
const
E2E_RPC_URL_L1
=
z
.
string
()
.
url
()
.
describe
(
'
L1 ethereum rpc Url
'
)
.
parse
(
import
.
meta
.
env
.
VITE_E2E_RPC_URL_L1
)
const
E2E_RPC_URL_L2
=
z
.
string
()
.
url
()
.
describe
(
'
L1 ethereum rpc Url
'
)
.
parse
(
import
.
meta
.
env
.
VITE_E2E_RPC_URL_L2
)
const
E2E_PRIVATE_KEY
=
z
const
E2E_PRIVATE_KEY
=
z
.
string
()
.
string
()
.
describe
(
'
Private key
'
)
.
describe
(
'
Private key
'
)
.
parse
(
import
.
meta
.
env
.
VITE_E2E_PRIVATE_KEY
)
.
parse
(
import
.
meta
.
env
.
VITE_E2E_PRIVATE_KEY
)
const
jsonRpcHeaders
=
{
'
User-Agent
'
:
'
eth-optimism/@gateway/backend
'
}
/**
* Initialize the signer, prover, and cross chain messenger
*/
const
l1Provider
=
new
ethers
.
providers
.
JsonRpcProvider
({
url
:
E2E_RPC_URL_L1
,
headers
:
jsonRpcHeaders
,
})
const
l2Provider
=
new
ethers
.
providers
.
JsonRpcProvider
({
url
:
E2E_RPC_URL_L2
,
headers
:
jsonRpcHeaders
,
})
const
l1Wallet
=
new
ethers
.
Wallet
(
E2E_PRIVATE_KEY
,
l1Provider
)
const
l1Wallet
=
new
ethers
.
Wallet
(
E2E_PRIVATE_KEY
,
l1Provider
)
const
crossChainMessenger
=
new
CrossChainMessenger
({
const
crossChainMessenger
=
new
CrossChainMessenger
({
l1SignerOrProvider
:
l1Wallet
,
l1SignerOrProvider
:
l1Wallet
,
...
...
packages/sdk/test-next/testUtils/ethersProviders.ts
0 → 100644
View file @
00428c2d
import
ethers
from
'
ethers
'
import
{
z
}
from
'
zod
'
const
E2E_RPC_URL_L1
=
z
.
string
()
.
url
()
.
describe
(
'
L1 ethereum rpc Url
'
)
.
parse
(
import
.
meta
.
env
.
VITE_E2E_RPC_URL_L1
)
const
E2E_RPC_URL_L2
=
z
.
string
()
.
url
()
.
describe
(
'
L1 ethereum rpc Url
'
)
.
parse
(
import
.
meta
.
env
.
VITE_E2E_RPC_URL_L2
)
const
jsonRpcHeaders
=
{
'
User-Agent
'
:
'
eth-optimism/@gateway/backend
'
}
/**
* Initialize the signer, prover, and cross chain messenger
*/
const
l1Provider
=
new
ethers
.
providers
.
JsonRpcProvider
({
url
:
E2E_RPC_URL_L1
,
headers
:
jsonRpcHeaders
,
})
const
l2Provider
=
new
ethers
.
providers
.
JsonRpcProvider
({
url
:
E2E_RPC_URL_L2
,
headers
:
jsonRpcHeaders
,
})
export
{
l1Provider
,
l2Provider
}
packages/sdk/test-next/testUtils/viemClients.ts
0 → 100644
View file @
00428c2d
import
{
createTestClient
,
createPublicClient
,
createWalletClient
,
http
,
}
from
'
viem
'
import
{
goerli
,
optimismGoerli
}
from
'
viem/chains
'
// TODO: use env vars to determine chain so we can support alternate l1/l2 pairs
const
L1_CHAIN
=
goerli
;
const
L2_CHAIN
=
optimismGoerli
;
const
L1_RPC_URL
=
'
http://localhost:8545
'
;
const
L2_RPC_URL
=
'
http://localhost:9545
'
const
l1TestClient
=
createTestClient
({
mode
:
'
anvil
'
,
chain
:
L1_CHAIN
,
transport
:
http
(
L1_RPC_URL
),
})
const
l2TestClient
=
createTestClient
({
mode
:
'
anvil
'
,
chain
:
L2_CHAIN
,
transport
:
http
(
L2_RPC_URL
),
})
const
l1PublicClient
=
createPublicClient
({
chain
:
L1_CHAIN
,
transport
:
http
(
L1_RPC_URL
),
})
const
l2PublicClient
=
createPublicClient
({
chain
:
L2_CHAIN
,
transport
:
http
(
L2_RPC_URL
),
})
const
l1WalletClient
=
createWalletClient
({
chain
:
L1_CHAIN
,
transport
:
http
(
L1_RPC_URL
),
})
const
l2WalletClient
=
createWalletClient
({
chain
:
L2_CHAIN
,
transport
:
http
(
L2_RPC_URL
),
})
export
{
l1TestClient
,
l2TestClient
,
l1PublicClient
,
l2PublicClient
,
l1WalletClient
,
l2WalletClient
,
}
packages/sdk/vitest.config.ts
0 → 100644
View file @
00428c2d
import
{
defineConfig
}
from
'
vitest/config
'
// https://vitest.dev/config/ - for docs
export
default
defineConfig
({
test
:
{
setupFiles
:
'
./setupVitest.ts
'
,
include
:
[
'
test-next/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}
'
],
},
})
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment