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
1c6d89be
Unverified
Commit
1c6d89be
authored
Jan 25, 2022
by
smartcontracts
Committed by
GitHub
Jan 25, 2022
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2076 from ethereum-optimism/sc/sdk-send-message
feat(sdk): implement sendMessage
parents
22234b1d
bc1758ca
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
359 additions
and
77 deletions
+359
-77
cross-chain-messenger.ts
packages/sdk/src/cross-chain-messenger.ts
+179
-0
cross-chain-provider.ts
packages/sdk/src/cross-chain-provider.ts
+20
-24
index.ts
packages/sdk/src/index.ts
+1
-0
cross-chain-messenger.ts
packages/sdk/src/interfaces/cross-chain-messenger.ts
+14
-12
cross-chain-provider.ts
packages/sdk/src/interfaces/cross-chain-provider.ts
+4
-20
types.ts
packages/sdk/src/interfaces/types.ts
+11
-3
MockMessenger.sol
packages/sdk/test/contracts/MockMessenger.sol
+10
-1
cross-chain-messenger.spec.ts
packages/sdk/test/cross-chain-messenger.spec.ts
+111
-5
cross-chain-provider.spec.ts
packages/sdk/test/cross-chain-provider.spec.ts
+9
-12
No files found.
packages/sdk/src/cross-chain-messenger.ts
0 → 100644
View file @
1c6d89be
/* eslint-disable @typescript-eslint/no-unused-vars */
import
{
Overrides
,
Signer
,
BigNumber
}
from
'
ethers
'
import
{
TransactionRequest
,
TransactionResponse
,
}
from
'
@ethersproject/abstract-provider
'
import
{
CrossChainMessageRequest
,
ICrossChainMessenger
,
ICrossChainProvider
,
L1ToL2Overrides
,
MessageLike
,
NumberLike
,
MessageDirection
,
}
from
'
./interfaces
'
export
class
CrossChainMessenger
implements
ICrossChainMessenger
{
provider
:
ICrossChainProvider
l1Signer
:
Signer
l2Signer
:
Signer
/**
* Creates a new CrossChainMessenger instance.
*
* @param opts Options for the messenger.
* @param opts.provider CrossChainProvider to use to send messages.
* @param opts.l1Signer Signer to use to send messages on L1.
* @param opts.l2Signer Signer to use to send messages on L2.
*/
constructor
(
opts
:
{
provider
:
ICrossChainProvider
l1Signer
:
Signer
l2Signer
:
Signer
})
{
this
.
provider
=
opts
.
provider
this
.
l1Signer
=
opts
.
l1Signer
this
.
l2Signer
=
opts
.
l2Signer
}
public
async
sendMessage
(
message
:
CrossChainMessageRequest
,
overrides
?:
L1ToL2Overrides
):
Promise
<
TransactionResponse
>
{
const
tx
=
await
this
.
populateTransaction
.
sendMessage
(
message
,
overrides
)
if
(
message
.
direction
===
MessageDirection
.
L1_TO_L2
)
{
return
this
.
l1Signer
.
sendTransaction
(
tx
)
}
else
{
return
this
.
l2Signer
.
sendTransaction
(
tx
)
}
}
public
async
resendMessage
(
message
:
MessageLike
,
messageGasLimit
:
NumberLike
,
overrides
?:
Overrides
):
Promise
<
TransactionResponse
>
{
throw
new
Error
(
'
Not implemented
'
)
}
public
async
finalizeMessage
(
message
:
MessageLike
,
overrides
?:
Overrides
):
Promise
<
TransactionResponse
>
{
throw
new
Error
(
'
Not implemented
'
)
}
public
async
depositETH
(
amount
:
NumberLike
,
overrides
?:
L1ToL2Overrides
):
Promise
<
TransactionResponse
>
{
throw
new
Error
(
'
Not implemented
'
)
}
public
async
withdrawETH
(
amount
:
NumberLike
,
overrides
?:
Overrides
):
Promise
<
TransactionResponse
>
{
throw
new
Error
(
'
Not implemented
'
)
}
populateTransaction
=
{
sendMessage
:
async
(
message
:
CrossChainMessageRequest
,
overrides
?:
L1ToL2Overrides
):
Promise
<
TransactionRequest
>
=>
{
if
(
message
.
direction
===
MessageDirection
.
L1_TO_L2
)
{
return
this
.
provider
.
contracts
.
l1
.
L1CrossDomainMessenger
.
connect
(
this
.
l1Signer
).
populateTransaction
.
sendMessage
(
message
.
target
,
message
.
message
,
overrides
?.
l2GasLimit
||
(
await
this
.
provider
.
estimateL2MessageGasLimit
(
message
))
)
}
else
{
return
this
.
provider
.
contracts
.
l2
.
L2CrossDomainMessenger
.
connect
(
this
.
l2Signer
).
populateTransaction
.
sendMessage
(
message
.
target
,
message
.
message
,
0
// Gas limit goes unused when sending from L2 to L1
)
}
},
resendMessage
:
async
(
message
:
MessageLike
,
messageGasLimit
:
NumberLike
,
overrides
?:
Overrides
):
Promise
<
TransactionRequest
>
=>
{
throw
new
Error
(
'
Not implemented
'
)
},
finalizeMessage
:
async
(
message
:
MessageLike
,
overrides
?:
Overrides
):
Promise
<
TransactionRequest
>
=>
{
throw
new
Error
(
'
Not implemented
'
)
},
depositETH
:
async
(
amount
:
NumberLike
,
overrides
?:
L1ToL2Overrides
):
Promise
<
TransactionRequest
>
=>
{
throw
new
Error
(
'
Not implemented
'
)
},
withdrawETH
:
async
(
amount
:
NumberLike
,
overrides
?:
Overrides
):
Promise
<
TransactionRequest
>
=>
{
throw
new
Error
(
'
Not implemented
'
)
},
}
estimateGas
=
{
sendMessage
:
async
(
message
:
CrossChainMessageRequest
,
overrides
?:
L1ToL2Overrides
):
Promise
<
BigNumber
>
=>
{
const
tx
=
await
this
.
populateTransaction
.
sendMessage
(
message
,
overrides
)
if
(
message
.
direction
===
MessageDirection
.
L1_TO_L2
)
{
return
this
.
provider
.
l1Provider
.
estimateGas
(
tx
)
}
else
{
return
this
.
provider
.
l2Provider
.
estimateGas
(
tx
)
}
},
resendMessage
:
async
(
message
:
MessageLike
,
messageGasLimit
:
NumberLike
,
overrides
?:
Overrides
):
Promise
<
BigNumber
>
=>
{
throw
new
Error
(
'
Not implemented
'
)
},
finalizeMessage
:
async
(
message
:
MessageLike
,
overrides
?:
Overrides
):
Promise
<
BigNumber
>
=>
{
throw
new
Error
(
'
Not implemented
'
)
},
depositETH
:
async
(
amount
:
NumberLike
,
overrides
?:
L1ToL2Overrides
):
Promise
<
BigNumber
>
=>
{
throw
new
Error
(
'
Not implemented
'
)
},
withdrawETH
:
async
(
amount
:
NumberLike
,
overrides
?:
Overrides
):
Promise
<
BigNumber
>
=>
{
throw
new
Error
(
'
Not implemented
'
)
},
}
}
packages/sdk/src/cross-chain-provider.ts
View file @
1c6d89be
...
@@ -12,11 +12,13 @@ import {
...
@@ -12,11 +12,13 @@ import {
OEContracts
,
OEContracts
,
OEContractsLike
,
OEContractsLike
,
MessageLike
,
MessageLike
,
MessageRequestLike
,
TransactionLike
,
TransactionLike
,
AddressLike
,
AddressLike
,
NumberLike
,
NumberLike
,
ProviderLike
,
ProviderLike
,
CrossChainMessage
,
CrossChainMessage
,
CrossChainMessageRequest
,
MessageDirection
,
MessageDirection
,
MessageStatus
,
MessageStatus
,
TokenBridgeMessage
,
TokenBridgeMessage
,
...
@@ -41,7 +43,6 @@ export class CrossChainProvider implements ICrossChainProvider {
...
@@ -41,7 +43,6 @@ export class CrossChainProvider implements ICrossChainProvider {
public
l1Provider
:
Provider
public
l1Provider
:
Provider
public
l2Provider
:
Provider
public
l2Provider
:
Provider
public
l1ChainId
:
number
public
l1ChainId
:
number
public
l1BlockTime
:
number
public
contracts
:
OEContracts
public
contracts
:
OEContracts
public
bridges
:
CustomBridges
public
bridges
:
CustomBridges
...
@@ -52,7 +53,6 @@ export class CrossChainProvider implements ICrossChainProvider {
...
@@ -52,7 +53,6 @@ export class CrossChainProvider implements ICrossChainProvider {
* @param opts.l1Provider Provider for the L1 chain, or a JSON-RPC url.
* @param opts.l1Provider Provider for the L1 chain, or a JSON-RPC url.
* @param opts.l2Provider Provider for the L2 chain, or a JSON-RPC url.
* @param opts.l2Provider Provider for the L2 chain, or a JSON-RPC url.
* @param opts.l1ChainId Chain ID for the L1 chain.
* @param opts.l1ChainId Chain ID for the L1 chain.
* @param opts.l1BlockTime Optional L1 block time in seconds. Defaults to 15 seconds.
* @param opts.contracts Optional contract address overrides.
* @param opts.contracts Optional contract address overrides.
* @param opts.bridges Optional bridge address list.
* @param opts.bridges Optional bridge address list.
*/
*/
...
@@ -60,16 +60,12 @@ export class CrossChainProvider implements ICrossChainProvider {
...
@@ -60,16 +60,12 @@ export class CrossChainProvider implements ICrossChainProvider {
l1Provider
:
ProviderLike
l1Provider
:
ProviderLike
l2Provider
:
ProviderLike
l2Provider
:
ProviderLike
l1ChainId
:
NumberLike
l1ChainId
:
NumberLike
l1BlockTime
?:
NumberLike
contracts
?:
DeepPartial
<
OEContractsLike
>
contracts
?:
DeepPartial
<
OEContractsLike
>
bridges
?:
Partial
<
CustomBridgesLike
>
bridges
?:
Partial
<
CustomBridgesLike
>
})
{
})
{
this
.
l1Provider
=
toProvider
(
opts
.
l1Provider
)
this
.
l1Provider
=
toProvider
(
opts
.
l1Provider
)
this
.
l2Provider
=
toProvider
(
opts
.
l2Provider
)
this
.
l2Provider
=
toProvider
(
opts
.
l2Provider
)
this
.
l1ChainId
=
toBigNumber
(
opts
.
l1ChainId
).
toNumber
()
this
.
l1ChainId
=
toBigNumber
(
opts
.
l1ChainId
).
toNumber
()
this
.
l1BlockTime
=
opts
.
l1BlockTime
?
toBigNumber
(
opts
.
l1ChainId
).
toNumber
()
:
15
this
.
contracts
=
getAllOEContracts
(
this
.
l1ChainId
,
{
this
.
contracts
=
getAllOEContracts
(
this
.
l1ChainId
,
{
l1SignerOrProvider
:
this
.
l1Provider
,
l1SignerOrProvider
:
this
.
l1Provider
,
l2SignerOrProvider
:
this
.
l2Provider
,
l2SignerOrProvider
:
this
.
l2Provider
,
...
@@ -364,9 +360,12 @@ export class CrossChainProvider implements ICrossChainProvider {
...
@@ -364,9 +360,12 @@ export class CrossChainProvider implements ICrossChainProvider {
if
(
stateRoot
===
null
)
{
if
(
stateRoot
===
null
)
{
return
MessageStatus
.
STATE_ROOT_NOT_PUBLISHED
return
MessageStatus
.
STATE_ROOT_NOT_PUBLISHED
}
else
{
}
else
{
const
challengePeriod
=
await
this
.
getChallengePeriodBlocks
()
const
challengePeriod
=
await
this
.
getChallengePeriodSeconds
()
const
latestBlock
=
await
this
.
l1Provider
.
getBlockNumber
()
const
targetBlock
=
await
this
.
l1Provider
.
getBlock
(
if
(
stateRoot
.
blockNumber
+
challengePeriod
>
latestBlock
)
{
stateRoot
.
blockNumber
)
const
latestBlock
=
await
this
.
l1Provider
.
getBlock
(
'
latest
'
)
if
(
targetBlock
.
timestamp
+
challengePeriod
>
latestBlock
.
timestamp
)
{
return
MessageStatus
.
IN_CHALLENGE_PERIOD
return
MessageStatus
.
IN_CHALLENGE_PERIOD
}
else
{
}
else
{
return
MessageStatus
.
READY_FOR_RELAY
return
MessageStatus
.
READY_FOR_RELAY
...
@@ -464,12 +463,21 @@ export class CrossChainProvider implements ICrossChainProvider {
...
@@ -464,12 +463,21 @@ export class CrossChainProvider implements ICrossChainProvider {
}
}
public
async
estimateL2MessageGasLimit
(
public
async
estimateL2MessageGasLimit
(
message
:
MessageLike
,
message
:
Message
Request
Like
,
opts
?:
{
opts
?:
{
bufferPercent
?:
number
bufferPercent
?:
number
from
?:
string
}
}
):
Promise
<
BigNumber
>
{
):
Promise
<
BigNumber
>
{
const
resolved
=
await
this
.
toCrossChainMessage
(
message
)
let
resolved
:
CrossChainMessage
|
CrossChainMessageRequest
let
from
:
string
if
((
message
as
CrossChainMessage
).
messageNonce
===
undefined
)
{
resolved
=
message
as
CrossChainMessageRequest
from
=
opts
?.
from
}
else
{
resolved
=
await
this
.
toCrossChainMessage
(
message
as
MessageLike
)
from
=
opts
?.
from
||
(
resolved
as
CrossChainMessage
).
sender
}
// L2 message gas estimation is only used for L1 => L2 messages.
// L2 message gas estimation is only used for L1 => L2 messages.
if
(
resolved
.
direction
===
MessageDirection
.
L2_TO_L1
)
{
if
(
resolved
.
direction
===
MessageDirection
.
L2_TO_L1
)
{
...
@@ -477,7 +485,7 @@ export class CrossChainProvider implements ICrossChainProvider {
...
@@ -477,7 +485,7 @@ export class CrossChainProvider implements ICrossChainProvider {
}
}
const
estimate
=
await
this
.
l2Provider
.
estimateGas
({
const
estimate
=
await
this
.
l2Provider
.
estimateGas
({
from
:
resolved
.
sender
,
from
,
to
:
resolved
.
target
,
to
:
resolved
.
target
,
data
:
resolved
.
message
,
data
:
resolved
.
message
,
})
})
...
@@ -493,24 +501,12 @@ export class CrossChainProvider implements ICrossChainProvider {
...
@@ -493,24 +501,12 @@ export class CrossChainProvider implements ICrossChainProvider {
throw
new
Error
(
'
Not implemented
'
)
throw
new
Error
(
'
Not implemented
'
)
}
}
public
async
estimateMessageWaitTimeBlocks
(
message
:
MessageLike
):
Promise
<
number
>
{
throw
new
Error
(
'
Not implemented
'
)
}
public
async
getChallengePeriodSeconds
():
Promise
<
number
>
{
public
async
getChallengePeriodSeconds
():
Promise
<
number
>
{
const
challengePeriod
=
const
challengePeriod
=
await
this
.
contracts
.
l1
.
StateCommitmentChain
.
FRAUD_PROOF_WINDOW
()
await
this
.
contracts
.
l1
.
StateCommitmentChain
.
FRAUD_PROOF_WINDOW
()
return
challengePeriod
.
toNumber
()
return
challengePeriod
.
toNumber
()
}
}
public
async
getChallengePeriodBlocks
():
Promise
<
number
>
{
return
Math
.
ceil
(
(
await
this
.
getChallengePeriodSeconds
())
/
this
.
l1BlockTime
)
}
public
async
getMessageStateRoot
(
public
async
getMessageStateRoot
(
message
:
MessageLike
message
:
MessageLike
):
Promise
<
StateRoot
|
null
>
{
):
Promise
<
StateRoot
|
null
>
{
...
...
packages/sdk/src/index.ts
View file @
1c6d89be
export
*
from
'
./interfaces
'
export
*
from
'
./interfaces
'
export
*
from
'
./utils
'
export
*
from
'
./utils
'
export
*
from
'
./cross-chain-provider
'
export
*
from
'
./cross-chain-provider
'
export
*
from
'
./cross-chain-messenger
'
packages/sdk/src/interfaces/cross-chain-messenger.ts
View file @
1c6d89be
import
{
Overrides
,
Signer
}
from
'
ethers
'
import
{
Overrides
,
Signer
,
BigNumber
}
from
'
ethers
'
import
{
import
{
TransactionRequest
,
TransactionRequest
,
TransactionResponse
,
TransactionResponse
,
...
@@ -22,9 +22,14 @@ export interface ICrossChainMessenger {
...
@@ -22,9 +22,14 @@ export interface ICrossChainMessenger {
provider
:
ICrossChainProvider
provider
:
ICrossChainProvider
/**
/**
* Signer that will carry out L1
/L2
transactions.
* Signer that will carry out L1 transactions.
*/
*/
signer
:
Signer
l1Signer
:
Signer
/**
* Signer that will carry out L2 transactions.
*/
l2Signer
:
Signer
/**
/**
* Sends a given cross chain message. Where the message is sent depends on the direction attached
* Sends a given cross chain message. Where the message is sent depends on the direction attached
...
@@ -107,7 +112,7 @@ export interface ICrossChainMessenger {
...
@@ -107,7 +112,7 @@ export interface ICrossChainMessenger {
sendMessage
:
(
sendMessage
:
(
message
:
CrossChainMessageRequest
,
message
:
CrossChainMessageRequest
,
overrides
?:
L1ToL2Overrides
overrides
?:
L1ToL2Overrides
)
=>
Promise
<
TransactionRe
sponse
>
)
=>
Promise
<
TransactionRe
quest
>
/**
/**
* Generates a transaction that resends a given cross chain message. Only applies to L1 to L2
* Generates a transaction that resends a given cross chain message. Only applies to L1 to L2
...
@@ -178,7 +183,7 @@ export interface ICrossChainMessenger {
...
@@ -178,7 +183,7 @@ export interface ICrossChainMessenger {
sendMessage
:
(
sendMessage
:
(
message
:
CrossChainMessageRequest
,
message
:
CrossChainMessageRequest
,
overrides
?:
L1ToL2Overrides
overrides
?:
L1ToL2Overrides
)
=>
Promise
<
TransactionResponse
>
)
=>
Promise
<
BigNumber
>
/**
/**
* Estimates gas required to resend a cross chain message. Only applies to L1 to L2 messages.
* Estimates gas required to resend a cross chain message. Only applies to L1 to L2 messages.
...
@@ -192,7 +197,7 @@ export interface ICrossChainMessenger {
...
@@ -192,7 +197,7 @@ export interface ICrossChainMessenger {
message
:
MessageLike
,
message
:
MessageLike
,
messageGasLimit
:
NumberLike
,
messageGasLimit
:
NumberLike
,
overrides
?:
Overrides
overrides
?:
Overrides
):
Promise
<
TransactionRequest
>
):
Promise
<
BigNumber
>
/**
/**
* Estimates gas required to finalize a cross chain message. Only applies to L2 to L1 messages.
* Estimates gas required to finalize a cross chain message. Only applies to L2 to L1 messages.
...
@@ -204,7 +209,7 @@ export interface ICrossChainMessenger {
...
@@ -204,7 +209,7 @@ export interface ICrossChainMessenger {
finalizeMessage
(
finalizeMessage
(
message
:
MessageLike
,
message
:
MessageLike
,
overrides
?:
Overrides
overrides
?:
Overrides
):
Promise
<
TransactionRequest
>
):
Promise
<
BigNumber
>
/**
/**
* Estimates gas required to deposit some ETH into the L2 chain.
* Estimates gas required to deposit some ETH into the L2 chain.
...
@@ -216,7 +221,7 @@ export interface ICrossChainMessenger {
...
@@ -216,7 +221,7 @@ export interface ICrossChainMessenger {
depositETH
(
depositETH
(
amount
:
NumberLike
,
amount
:
NumberLike
,
overrides
?:
L1ToL2Overrides
overrides
?:
L1ToL2Overrides
):
Promise
<
TransactionRequest
>
):
Promise
<
BigNumber
>
/**
/**
* Estimates gas required to withdraw some ETH back to the L1 chain.
* Estimates gas required to withdraw some ETH back to the L1 chain.
...
@@ -225,9 +230,6 @@ export interface ICrossChainMessenger {
...
@@ -225,9 +230,6 @@ export interface ICrossChainMessenger {
* @param overrides Optional transaction overrides.
* @param overrides Optional transaction overrides.
* @returns Transaction that can be signed and executed to withdraw the tokens.
* @returns Transaction that can be signed and executed to withdraw the tokens.
*/
*/
withdrawETH
(
withdrawETH
(
amount
:
NumberLike
,
overrides
?:
Overrides
):
Promise
<
BigNumber
>
amount
:
NumberLike
,
overrides
?:
Overrides
):
Promise
<
TransactionRequest
>
}
}
}
}
packages/sdk/src/interfaces/cross-chain-provider.ts
View file @
1c6d89be
...
@@ -3,6 +3,7 @@ import { Provider, BlockTag } from '@ethersproject/abstract-provider'
...
@@ -3,6 +3,7 @@ import { Provider, BlockTag } from '@ethersproject/abstract-provider'
import
{
import
{
MessageLike
,
MessageLike
,
MessageRequestLike
,
TransactionLike
,
TransactionLike
,
AddressLike
,
AddressLike
,
NumberLike
,
NumberLike
,
...
@@ -205,12 +206,14 @@ export interface ICrossChainProvider {
...
@@ -205,12 +206,14 @@ export interface ICrossChainProvider {
* @param message Message get a gas estimate for.
* @param message Message get a gas estimate for.
* @param opts Options object.
* @param opts Options object.
* @param opts.bufferPercent Percentage of gas to add to the estimate. Defaults to 20.
* @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.
* @returns Estimates L2 gas limit.
*/
*/
estimateL2MessageGasLimit
(
estimateL2MessageGasLimit
(
message
:
MessageLike
,
message
:
Message
Request
Like
,
opts
?:
{
opts
?:
{
bufferPercent
?:
number
bufferPercent
?:
number
from
?:
string
}
}
):
Promise
<
BigNumber
>
):
Promise
<
BigNumber
>
...
@@ -225,17 +228,6 @@ export interface ICrossChainProvider {
...
@@ -225,17 +228,6 @@ export interface ICrossChainProvider {
*/
*/
estimateMessageWaitTimeSeconds
(
message
:
MessageLike
):
Promise
<
number
>
estimateMessageWaitTimeSeconds
(
message
:
MessageLike
):
Promise
<
number
>
/**
* Returns the estimated amount of time before the message can be executed (in L1 blocks).
* 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 blocks) before the message can be executed.
*/
estimateMessageWaitTimeBlocks
(
message
:
MessageLike
):
Promise
<
number
>
/**
/**
* Queries the current challenge period in seconds from the StateCommitmentChain.
* Queries the current challenge period in seconds from the StateCommitmentChain.
*
*
...
@@ -243,14 +235,6 @@ export interface ICrossChainProvider {
...
@@ -243,14 +235,6 @@ export interface ICrossChainProvider {
*/
*/
getChallengePeriodSeconds
():
Promise
<
number
>
getChallengePeriodSeconds
():
Promise
<
number
>
/**
* Queries the current challenge period in blocks from the StateCommitmentChain. Estimation is
* based on the challenge period in seconds divided by the L1 block time.
*
* @returns Current challenge period in blocks.
*/
getChallengePeriodBlocks
():
Promise
<
number
>
/**
/**
* Returns the state root that corresponds to a given message. This is the state root for the
* 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
* block in which the transaction was included, as published to the StateCommitmentChain. If the
...
...
packages/sdk/src/interfaces/types.ts
View file @
1c6d89be
...
@@ -143,7 +143,6 @@ export interface CrossChainMessageRequest {
...
@@ -143,7 +143,6 @@ export interface CrossChainMessageRequest {
direction
:
MessageDirection
direction
:
MessageDirection
target
:
string
target
:
string
message
:
string
message
:
string
l2GasLimit
:
NumberLike
}
}
/**
/**
...
@@ -235,7 +234,7 @@ export interface StateRootBatch {
...
@@ -235,7 +234,7 @@ export interface StateRootBatch {
* limit field (gas used depends on the amount of gas provided).
* limit field (gas used depends on the amount of gas provided).
*/
*/
export
type
L1ToL2Overrides
=
Overrides
&
{
export
type
L1ToL2Overrides
=
Overrides
&
{
l2GasLimit
:
NumberLike
l2GasLimit
?
:
NumberLike
}
}
/**
/**
...
@@ -244,13 +243,22 @@ export type L1ToL2Overrides = Overrides & {
...
@@ -244,13 +243,22 @@ export type L1ToL2Overrides = Overrides & {
export
type
TransactionLike
=
string
|
TransactionReceipt
|
TransactionResponse
export
type
TransactionLike
=
string
|
TransactionReceipt
|
TransactionResponse
/**
/**
* Stuff that can be coerced into a
m
essage.
* Stuff that can be coerced into a
CrossChainM
essage.
*/
*/
export
type
MessageLike
=
export
type
MessageLike
=
|
CrossChainMessage
|
CrossChainMessage
|
TransactionLike
|
TransactionLike
|
TokenBridgeMessage
|
TokenBridgeMessage
/**
* Stuff that can be coerced into a CrossChainMessageRequest.
*/
export
type
MessageRequestLike
=
|
CrossChainMessageRequest
|
CrossChainMessage
|
TransactionLike
|
TokenBridgeMessage
/**
/**
* Stuff that can be coerced into a provider.
* Stuff that can be coerced into a provider.
*/
*/
...
...
packages/sdk/test/contracts/MockMessenger.sol
View file @
1c6d89be
...
@@ -7,13 +7,22 @@ contract MockMessenger is ICrossDomainMessenger {
...
@@ -7,13 +7,22 @@ contract MockMessenger is ICrossDomainMessenger {
return address(0);
return address(0);
}
}
uint256 public nonce;
// Empty function to satisfy the interface.
// Empty function to satisfy the interface.
function sendMessage(
function sendMessage(
address _target,
address _target,
bytes calldata _message,
bytes calldata _message,
uint32 _gasLimit
uint32 _gasLimit
) public {
) public {
return;
emit SentMessage(
_target,
msg.sender,
_message,
nonce,
_gasLimit
);
nonce++;
}
}
struct SentMessageEventParams {
struct SentMessageEventParams {
...
...
packages/sdk/test/cross-chain-messenger.spec.ts
View file @
1c6d89be
import
'
./setup
'
import
{
Contract
}
from
'
ethers
'
import
{
ethers
}
from
'
hardhat
'
import
{
expect
}
from
'
./setup
'
import
{
CrossChainProvider
,
CrossChainMessenger
,
MessageDirection
,
}
from
'
../src
'
describe
(
'
CrossChainMessenger
'
,
()
=>
{
describe
(
'
CrossChainMessenger
'
,
()
=>
{
let
l1Signer
:
any
let
l2Signer
:
any
before
(
async
()
=>
{
;[
l1Signer
,
l2Signer
]
=
await
ethers
.
getSigners
()
})
describe
(
'
sendMessage
'
,
()
=>
{
describe
(
'
sendMessage
'
,
()
=>
{
describe
(
'
when no l2GasLimit is provided
'
,
()
=>
{
let
l1Messenger
:
Contract
it
(
'
should send a message with an estimated l2GasLimit
'
)
let
l2Messenger
:
Contract
let
provider
:
CrossChainProvider
let
messenger
:
CrossChainMessenger
beforeEach
(
async
()
=>
{
l1Messenger
=
(
await
(
await
ethers
.
getContractFactory
(
'
MockMessenger
'
)
).
deploy
())
as
any
l2Messenger
=
(
await
(
await
ethers
.
getContractFactory
(
'
MockMessenger
'
)
).
deploy
())
as
any
provider
=
new
CrossChainProvider
({
l1Provider
:
ethers
.
provider
,
l2Provider
:
ethers
.
provider
,
l1ChainId
:
31337
,
contracts
:
{
l1
:
{
L1CrossDomainMessenger
:
l1Messenger
.
address
,
},
l2
:
{
L2CrossDomainMessenger
:
l2Messenger
.
address
,
},
},
})
messenger
=
new
CrossChainMessenger
({
provider
,
l1Signer
,
l2Signer
,
})
})
describe
(
'
when the message is an L1 to L2 message
'
,
()
=>
{
describe
(
'
when no l2GasLimit is provided
'
,
()
=>
{
it
(
'
should send a message with an estimated l2GasLimit
'
,
async
()
=>
{
const
message
=
{
direction
:
MessageDirection
.
L1_TO_L2
,
target
:
'
0x
'
+
'
11
'
.
repeat
(
20
),
message
:
'
0x
'
+
'
22
'
.
repeat
(
32
),
}
const
estimate
=
await
provider
.
estimateL2MessageGasLimit
(
message
)
await
expect
(
messenger
.
sendMessage
(
message
))
.
to
.
emit
(
l1Messenger
,
'
SentMessage
'
)
.
withArgs
(
message
.
target
,
await
l1Signer
.
getAddress
(),
message
.
message
,
0
,
estimate
)
})
})
describe
(
'
when an l2GasLimit is provided
'
,
()
=>
{
it
(
'
should send a message with the provided l2GasLimit
'
,
async
()
=>
{
const
message
=
{
direction
:
MessageDirection
.
L1_TO_L2
,
target
:
'
0x
'
+
'
11
'
.
repeat
(
20
),
message
:
'
0x
'
+
'
22
'
.
repeat
(
32
),
}
await
expect
(
messenger
.
sendMessage
(
message
,
{
l2GasLimit
:
1234
,
})
)
.
to
.
emit
(
l1Messenger
,
'
SentMessage
'
)
.
withArgs
(
message
.
target
,
await
l1Signer
.
getAddress
(),
message
.
message
,
0
,
1234
)
})
})
})
})
describe
(
'
when an l2GasLimit is provided
'
,
()
=>
{
describe
(
'
when the message is an L2 to L1 message
'
,
()
=>
{
it
(
'
should send a message with the provided l2GasLimit
'
)
it
(
'
should send a message
'
,
async
()
=>
{
const
message
=
{
direction
:
MessageDirection
.
L2_TO_L1
,
target
:
'
0x
'
+
'
11
'
.
repeat
(
20
),
message
:
'
0x
'
+
'
22
'
.
repeat
(
32
),
}
await
expect
(
messenger
.
sendMessage
(
message
))
.
to
.
emit
(
l2Messenger
,
'
SentMessage
'
)
.
withArgs
(
message
.
target
,
await
l2Signer
.
getAddress
(),
message
.
message
,
0
,
0
)
})
})
})
})
})
...
...
packages/sdk/test/cross-chain-provider.spec.ts
View file @
1c6d89be
...
@@ -898,10 +898,9 @@ describe('CrossChainProvider', () => {
...
@@ -898,10 +898,9 @@ describe('CrossChainProvider', () => {
await
submitStateRootBatchForMessage
(
message
)
await
submitStateRootBatchForMessage
(
message
)
const
challengePeriod
=
await
provider
.
getChallengePeriodBlocks
()
const
challengePeriod
=
await
provider
.
getChallengePeriodSeconds
()
for
(
let
x
=
0
;
x
<
challengePeriod
+
1
;
x
++
)
{
ethers
.
provider
.
send
(
'
evm_increaseTime
'
,
[
challengePeriod
+
1
])
await
ethers
.
provider
.
send
(
'
evm_mine
'
,
[])
ethers
.
provider
.
send
(
'
evm_mine
'
,
[])
}
await
l1Messenger
.
triggerRelayedMessageEvents
([
await
l1Messenger
.
triggerRelayedMessageEvents
([
hashCrossChainMessage
(
message
),
hashCrossChainMessage
(
message
),
...
@@ -921,10 +920,9 @@ describe('CrossChainProvider', () => {
...
@@ -921,10 +920,9 @@ describe('CrossChainProvider', () => {
await
submitStateRootBatchForMessage
(
message
)
await
submitStateRootBatchForMessage
(
message
)
const
challengePeriod
=
await
provider
.
getChallengePeriodBlocks
()
const
challengePeriod
=
await
provider
.
getChallengePeriodSeconds
()
for
(
let
x
=
0
;
x
<
challengePeriod
+
1
;
x
++
)
{
ethers
.
provider
.
send
(
'
evm_increaseTime
'
,
[
challengePeriod
+
1
])
await
ethers
.
provider
.
send
(
'
evm_mine
'
,
[])
ethers
.
provider
.
send
(
'
evm_mine
'
,
[])
}
await
l1Messenger
.
triggerFailedRelayedMessageEvents
([
await
l1Messenger
.
triggerFailedRelayedMessageEvents
([
hashCrossChainMessage
(
message
),
hashCrossChainMessage
(
message
),
...
@@ -944,10 +942,9 @@ describe('CrossChainProvider', () => {
...
@@ -944,10 +942,9 @@ describe('CrossChainProvider', () => {
await
submitStateRootBatchForMessage
(
message
)
await
submitStateRootBatchForMessage
(
message
)
const
challengePeriod
=
await
provider
.
getChallengePeriodBlocks
()
const
challengePeriod
=
await
provider
.
getChallengePeriodSeconds
()
for
(
let
x
=
0
;
x
<
challengePeriod
+
1
;
x
++
)
{
ethers
.
provider
.
send
(
'
evm_increaseTime
'
,
[
challengePeriod
+
1
])
await
ethers
.
provider
.
send
(
'
evm_mine
'
,
[])
ethers
.
provider
.
send
(
'
evm_mine
'
,
[])
}
expect
(
await
provider
.
getMessageStatus
(
message
)).
to
.
equal
(
expect
(
await
provider
.
getMessageStatus
(
message
)).
to
.
equal
(
MessageStatus
.
READY_FOR_RELAY
MessageStatus
.
READY_FOR_RELAY
...
...
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