-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add eth-weth example to readme #53
Merged
Merged
Changes from 2 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
00d037d
add eth-weth example to readme
gsteenkamp89 ba7db2b
tidy up
gsteenkamp89 99920b1
Merge branch 'master' into chore/expand-docs-example
gsteenkamp89 0a43d2f
use eth/weth example only
gsteenkamp89 8818393
edit
gsteenkamp89 ac74fa9
show progress state machine
gsteenkamp89 04bb998
small fix
gsteenkamp89 8360de1
fox spelling errors
gsteenkamp89 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -112,7 +112,9 @@ Have a look at our [example app](../../apps/example) for a more detailed usage o | |
|
||
Across enables users to seamlessly interact with your dApp or chain using assets from other chains. | ||
|
||
### 1. Craft a cross-chain message | ||
- ### Example A - _Stake an ERC20 on destination chain_ | ||
|
||
### 1. Craft a cross-chain message (A) | ||
|
||
To implement this feature, you first need to specify a `crossChainMessage`. | ||
The example below shows a cross-chain message for staking USDC into a contract deployed | ||
|
@@ -230,6 +232,118 @@ await client.executeQuote({ | |
}); | ||
``` | ||
|
||
- ### **Example (B)** - _Stake Native ETH on destination chain_ | ||
|
||
> This follows the logic in the example app. | ||
|
||
To implement this feature, we need to bridge either ETH or WETH from our origin chain to our destination chain. Across will always send WETH to the recipient on the destination chain, **unless the recipient is an EOA**. For our use-case, we want to stake native ETH, moreover we want to do this in one step. For this we recommend using Across's MulticallHandler contract (or deploying your own). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please check this information is accurate |
||
|
||
So here's how we can stake ETH onto our staking contract: | ||
|
||
1. Bridge ETH => destination chain and send output tokens to MulticallHandler contract (this will be WETH since it's a contract). | ||
2. Unwrap WETH | ||
3. Stake ETH on the staking contract. | ||
|
||
The rest of the flow is exactly the same as the previous example. | ||
|
||
It is also worth noting that whenever our calldata is dependant on the output amount we **MUST** make use of the `update()` function. | ||
|
||
### 1. Craft a cross-chain message (B) | ||
|
||
```ts | ||
import { type Amount } from "@across-protocol/app-sdk"; | ||
import { encodeFunctionData } from "viem"; | ||
import { optimism } from "viem/chains"; | ||
|
||
// constants | ||
const userAddress = "0xFoo"; | ||
const multicallHandlerOptimism = "0x924a9f036260DdD5808007E1AA95f08eD08aA569"; | ||
|
||
export const WETH_OPTIMISM = { | ||
chain: optimism, | ||
abi: WethAbi, | ||
token: { | ||
address: "0x4200000000000000000000000000000000000006", | ||
decimals: 18, | ||
logoUrl: | ||
"https://raw.githubusercontent.com/across-protocol/frontend/master/src/assets/token-logos/weth.svg", | ||
name: "Wrapped Ether", | ||
symbol: "WETH", | ||
}, | ||
address: "0x4200000000000000000000000000000000000006", | ||
} as const; | ||
|
||
export const STAKE_CONTRACT = { | ||
address: "0x733Debf51574c70CfCdb7918F032E16F686bd9f8", | ||
chain: optimism, | ||
token: { | ||
address: "0x4200000000000000000000000000000000000006", // notice that ETH & WETH both have the same address | ||
symbol: "ETH", | ||
name: "Ether", | ||
decimals: 18, | ||
logoUrl: | ||
"https://raw.githubusercontent.com/across-protocol/frontend/master/src/assets/token-logos/eth.svg", | ||
}, | ||
abi: StakerContractABI, | ||
} as const; | ||
|
||
// WETH unwrap action | ||
function generateUnwrapCallData(wethAmount: Amount) { | ||
return encodeFunctionData({ | ||
abi: WethAbi, | ||
functionName: "withdraw", | ||
args: [BigInt(wethAmount)], | ||
}); | ||
} | ||
|
||
// STAKE action | ||
function generateStakeCallData(userAddress: Address) { | ||
return encodeFunctionData({ | ||
abi: STAKE_CONTRACT.abi, | ||
functionName: "stake", | ||
args: [userAddress], | ||
}); | ||
} | ||
|
||
const crossChainMessage = { | ||
actions: [ | ||
{ | ||
target: WETH_OPTIMISM.address, | ||
callData: generateUnwrapCallData(inputAmount), | ||
value: 0n, | ||
// we only update the calldata since the unwrap call is non-payable, but we DO care about the output amount. | ||
update: (updatedOutputAmount) => { | ||
return { | ||
callData: generateUnwrapCallData(updatedOutputAmount), | ||
}; | ||
}, | ||
}, | ||
{ | ||
target: STAKE_CONTRACT.address, | ||
callData: generateStakeCallData(userAddress), | ||
// 🔔 the initial value may be set equal to the output amount. This MUST be updated via the `update()` function below oir this call will fail! | ||
value: inputAmount, | ||
// now we MUST update msg.value since this last call is calling a payable function. | ||
update: (updatedOutputAmount) => { | ||
return { | ||
value: updatedOutputAmount, | ||
}; | ||
}, | ||
}, | ||
], | ||
fallbackRecipient: userAddress, | ||
}; | ||
|
||
// Then get a quote | ||
const quote = await client.getQuote({ | ||
route, | ||
inputAmount: parseEther("1"), | ||
// 🔔 Notice the recipient is not the staking contract itself or even the user, but is instead the contract that will execute our cross chain messages | ||
recipient: multicallHandlerOptimism, | ||
crossChainMessage: buildCrossChainMessage(parseEther("1")), | ||
}); | ||
``` | ||
|
||
## Deposit details | ||
|
||
TODO | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
deleting unused function