Skip to content

feat: add native wsteth support#246

Merged
JackHamer09 merged 12 commits intomainfrom
tx-nikola-txfusion-support-wsteth-on-bridge
Jul 8, 2025
Merged

feat: add native wsteth support#246
JackHamer09 merged 12 commits intomainfrom
tx-nikola-txfusion-support-wsteth-on-bridge

Conversation

@tx-nikola
Copy link
Copy Markdown

@tx-nikola tx-nikola commented May 8, 2025

  • Tested withdraw, deposit, and transfer for the native wstETH token, as well as the bridged (erc20) one, also tested ETH token and others to not mess up the previous flow.

  • The custom gas price fetching and custom withdraw tx creation had to be added since newer version of the SDK works in a different way for bridge addresses and it didn't work with native wstETH address

  • The balances/tokens map had to be updated - previously it used L1 address as the key, but I had to change it so that it uses the L2 address as the key - since we want to keep backward compatibility with the previous bridged (non-native non-Lido) wstETH token, so we want to support both, but they have the same L1 address, so we couldn't use the L1 address as the key

This PR fixes #238

@tx-nikola tx-nikola requested a review from JackHamer09 May 8, 2025 11:38
@tx-nikola tx-nikola self-assigned this May 8, 2025
@tx-nikola tx-nikola added the enhancement New feature or request label May 8, 2025
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 8, 2025

Visit the preview URL for this PR (updated for commit 7ec2240):

https://staging-zksync-dapp-wallet-v2--pr246-tx-nikola-txfusio-3ifj5qui.web.app

(expires Tue, 15 Jul 2025 18:26:59 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: a25831e6058958ccabf0f806505b5b8e7241b178

Copy link
Copy Markdown
Member

@JackHamer09 JackHamer09 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tldr: code is just ai generated and the quality is really poor

const eraWalletStore = useZkSyncWalletStore();
const { eraNetwork } = useZkSyncProviderStore();
const { captureException } = useSentryLogger();
const chain = eraNetwork.key === "mainnet" ? mainnet : sepolia;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't make a lot of sense to me.. Why not use l1 network config of selected network?

fee: DepositFeeValues
) => {
// Create signer
const { ethereum } = window as any;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would only support injected wallets... You should use connected wallet instead of creating new one

Comment on lines +40 to +42
const browserProvider = new BrowserProvider(ethereum);
const isMainnet = eraNetwork.key === "mainnet" || eraNetwork.id === 324;
const networkType = isMainnet ? types.Network.Mainnet : types.Network.Sepolia;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like AI generated code which doesn't make too much sense

const allowance = await signer.getAllowanceL1(transaction.tokenAddress, transaction.bridgeAddress);

if (allowance < BigInt(transaction.amount)) {
const approveTx = await signer.approveERC20(transaction.tokenAddress, transaction.amount, {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Allowance should be done properly and handled on the UI, there is already logic for it

@tx-nikola
Copy link
Copy Markdown
Author

I didn't use AI for any of the mentioned parts - those were basically examples for how we did it previously, but I agree with the comments and I agree that it could be polished!

Updated based on the comments:

  • Now we use the getL1VoidSigner for the signer (which under the hood uses onboardStore.getPublicClient())

  • Removed the networkType part as it's not needed, because the l1 signer handles that part now

  • I left the allowance part - the reason I added it for the handleCustomBridgeDeposit function is because before, when calling wallet.deposit, we pass the approveBaseERC20 as true

  • Tested wstETH for both withdraw and deposit

Copy link
Copy Markdown
Member

@JackHamer09 JackHamer09 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Please check this PR with some improvements #253

  2. See the comments, left some feedback about general logic of token addresses

  3. I'm getting a bunch of errors in views/transactions/Deposit.vue. Mostly Property 'l2Address' does not exist on type 'Token'.. I tried rebuilding everything and installing latest dependencies.

I left the allowance part - the reason I added it for the handleCustomBridgeDeposit function is because before, when calling wallet.deposit, we pass the approveBaseERC20 as true

It was a hacky way of fixing deposit for those chains that use custom erc20 as base token I think. Normally, and in this case as well, you should do it correctly through the UI, so that user understands what's going on and which transaction they are signing. Or is this already handled?

Comment thread composables/transaction/useAllowance.ts
Comment thread views/transactions/Transfer.vue Outdated
Comment thread views/transactions/Deposit.vue Outdated
Comment thread views/transactions/Deposit.vue Outdated
Comment thread views/transactions/Deposit.vue Outdated
Comment thread store/zksync/wallet.ts Outdated
Comment thread store/zksync/wallet.ts Outdated
Comment thread store/zksync/tokens.ts Outdated
@tx-nikola
Copy link
Copy Markdown
Author

@JackHamer09

  • Removed all occurencies of this pattern:
{
<object properties>,
...(transaction.value.token.l2BridgeAddress ? { bridgeAddress: transaction.value.token.l2BridgeAddress } : {}),
}

I used it because in some cases in other projects, I found it that some functions that expect object params, expect either an object with a parameter or with no parameter, and even if we pass "undefined" as a param, the function will take it as a param that exists, and potentially throw an error - so I just adopted the style that if I pass the object with potentially undefined params, I don't pass the params that would be undefined. In these cases it doesn't make a difference, so I agree with you to keep it simplified.

  • I updated changes for tokens.ts to not be hacky
    • Instead of mapping L1 and L2 token objects in a complicated way, I created new mapper functions in helpers.ts and use them wherever we need balances/tokens arrays.
      Before, it was hacky because I was trying to change the object mapping - it was {[l1Address]: Token} because the object keys must be unique and there can't be 2 same L1 addresses (as we have in the case of wstETH) but now I left it as it is and just map it whenever we use the array.

@tx-nikola tx-nikola requested a review from JackHamer09 June 24, 2025 08:16
@JackHamer09 JackHamer09 merged commit 7f899d0 into main Jul 8, 2025
7 checks passed
@JackHamer09 JackHamer09 deleted the tx-nikola-txfusion-support-wsteth-on-bridge branch July 8, 2025 18:27
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Jul 8, 2025

🎉 This PR is included in version 1.44.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for wstETH on native bridge

2 participants