From 4131977d1254d01488d34808ff3ae38aa3cb96c0 Mon Sep 17 00:00:00 2001 From: Aren Date: Fri, 27 Dec 2024 20:16:36 +0400 Subject: [PATCH] implement sophon wallet withdrawal --- Models/Network.ts | 1 + .../Withdraw/Wallet/SophonWalletWithdraw.tsx | 94 +++++++++++++++++++ .../Wallet/WalletTransfer/networkGas.tsx | 4 +- .../Withdraw/Wallet/WalletTransferContent.tsx | 13 +++ lib/gases/providers/evmGasProvider.ts | 2 + lib/knownIds.ts | 4 + package.json | 4 +- yarn.lock | 65 ++++++++----- 8 files changed, 158 insertions(+), 29 deletions(-) create mode 100644 components/Swap/Withdraw/Wallet/SophonWalletWithdraw.tsx diff --git a/Models/Network.ts b/Models/Network.ts index b66ef6177..64e087810 100644 --- a/Models/Network.ts +++ b/Models/Network.ts @@ -53,4 +53,5 @@ export class Metadata { evm_oracle_contract?: `0x${string}` | null evm_multicall_contract?: string | null listing_date: string + zks_paymaster_contract?: `0x${string}` | null } \ No newline at end of file diff --git a/components/Swap/Withdraw/Wallet/SophonWalletWithdraw.tsx b/components/Swap/Withdraw/Wallet/SophonWalletWithdraw.tsx new file mode 100644 index 000000000..d7582f43e --- /dev/null +++ b/components/Swap/Withdraw/Wallet/SophonWalletWithdraw.tsx @@ -0,0 +1,94 @@ +import { ArrowLeftRight } from 'lucide-react'; +import { FC, useCallback, useState } from 'react' +import toast from 'react-hot-toast'; +import { useSwapTransactionStore } from '../../../../stores/swapTransactionStore'; +import { BackendTransactionStatus } from '../../../../lib/layerSwapApiClient'; +import { ButtonWrapper, ChangeNetworkButton, ConnectWalletButton } from './WalletTransfer/buttons'; +import { useAccount } from 'wagmi'; +import useWallet from '../../../../hooks/useWallet'; +import { WithdrawPageProps } from './WalletTransferContent'; +import { sophon, sophonTestnet } from 'viem/chains'; +import { createWalletClient, custom, JsonRpcAccount } from 'viem'; +import { eip712WalletActions, getGeneralPaymasterInput } from 'viem/zksync'; +import KnownInternalNames from '../../../../lib/knownIds'; + +const SophonWalletWithdraw: FC = ({ amount, depositAddress, network, token, swapId, callData }) => { + const [loading, setLoading] = useState(false); + + const { setSwapTransaction } = useSwapTransactionStore(); + const { chain: activeChain, connector } = useAccount(); + + const networkChainId = Number(network?.chain_id) ?? undefined + const { provider } = useWallet(network, 'withdrawal') + const wallet = provider?.activeWallet + + const handleTransfer = useCallback(async () => { + + if (!wallet?.address || !swapId || !depositAddress || !token || amount == undefined || !callData || !network?.metadata.zks_paymaster_contract) return + + try { + setLoading(true) + + const walletProvider = await connector?.getProvider() as any + + if (!walletProvider) throw new Error('Could not get provider') + + const account = { + address: wallet?.address, + type: 'json-rpc' + } as JsonRpcAccount + + const walletClient = createWalletClient({ + chain: network.name === KnownInternalNames.Networks.SophonSepolia ? sophonTestnet : sophon, + transport: custom(walletProvider), + account: account + }).extend(eip712WalletActions()); + + const request = await walletClient.prepareTransactionRequest({ + to: depositAddress, + data: callData as `0x${string}`, + paymaster: network?.metadata.zks_paymaster_contract, + paymasterInput: getGeneralPaymasterInput({ innerInput: "0x" }), + }) + + const signature = await walletClient.signTransaction(request as any) + const hash = await walletClient.sendRawTransaction({ + serializedTransaction: signature + }) + + if (hash) { + setSwapTransaction(swapId, BackendTransactionStatus.Pending, hash); + } + } + catch (e) { + if (e?.message) { + if (e.name.includes("EstimateGasExecutionError")) return toast("You don't have enough funds") + toast(e.message) + return + } + } + finally { + setLoading(false) + } + }, [swapId, depositAddress, token, amount, callData]) + + if (!wallet) { + return + } + + else if (activeChain?.id !== networkChainId && network) { + return + } + + return ( + <> + + + ) +} +export default SophonWalletWithdraw; \ No newline at end of file diff --git a/components/Swap/Withdraw/Wallet/WalletTransfer/networkGas.tsx b/components/Swap/Withdraw/Wallet/WalletTransfer/networkGas.tsx index 51c2d0362..bc46c7595 100644 --- a/components/Swap/Withdraw/Wallet/WalletTransfer/networkGas.tsx +++ b/components/Swap/Withdraw/Wallet/WalletTransfer/networkGas.tsx @@ -12,14 +12,14 @@ const NetworkGas: FC = ({ address, token, network }) => { const { gas: networkGas, isGasLoading } = useSWRGas(address, network, token) - if (!networkGas) + if (networkGas == undefined) return <> return

Estimated gas:

- {isGasLoading ?
: networkGas?.toFixed(token.precision || 0)} {token?.symbol} + {isGasLoading ?
: networkGas?.toFixed(networkGas == 0 ? 0 : token.precision || 0)} {token?.symbol}
} diff --git a/components/Swap/Withdraw/Wallet/WalletTransferContent.tsx b/components/Swap/Withdraw/Wallet/WalletTransferContent.tsx index 5cb40698c..1c3a2b953 100644 --- a/components/Swap/Withdraw/Wallet/WalletTransferContent.tsx +++ b/components/Swap/Withdraw/Wallet/WalletTransferContent.tsx @@ -10,6 +10,7 @@ import LoopringWalletWithdraw from "./Loopring"; import { Network, Token } from "../../../../Models/Network"; import TonWalletWithdrawStep from "./TonWalletWithdraw"; import ParadexWalletWithdrawStep from "./paradex/index"; +import SophonWalletWithdraw from "./SophonWalletWithdraw"; //TODO have separate components for evm and none_evm as others are sweepless anyway export const WalletTransferContent: FC = () => { @@ -43,6 +44,9 @@ export const WalletTransferContent: FC = () => { const sourceIsParadex = source_network_internal_name?.toUpperCase() === KnownInternalNames.Networks.ParadexMainnet?.toUpperCase() || source_network_internal_name?.toUpperCase() === KnownInternalNames.Networks.ParadexTestnet?.toUpperCase(); + const sourceIsSophon = source_network_internal_name?.toUpperCase() === KnownInternalNames.Networks.SophonMainnet?.toUpperCase() + || source_network_internal_name?.toUpperCase() === KnownInternalNames.Networks.SophonSepolia?.toUpperCase(); + const depositAddress = depositActionsResponse?.find(da => true)?.to_address; const amount = depositActionsResponse?.find(da => true)?.amount || 0; const callData = depositActionsResponse?.find(da => true)?.call_data; @@ -106,6 +110,15 @@ export const WalletTransferContent: FC = () => { swapId={swap?.id} callData={callData} />; + else if (sourceIsSophon) + return ; else return <> { diff --git a/lib/gases/providers/evmGasProvider.ts b/lib/gases/providers/evmGasProvider.ts index 5c21bb55e..01ddfa9b4 100644 --- a/lib/gases/providers/evmGasProvider.ts +++ b/lib/gases/providers/evmGasProvider.ts @@ -24,6 +24,8 @@ export class EVMGasProvider implements Provider { try { + if (network.metadata.zks_paymaster_contract) return 0 + const { createPublicClient, http } = await import("viem") const resolveNetworkChain = (await import("../../resolveChain")).default const publicClient = createPublicClient({ diff --git a/lib/knownIds.ts b/lib/knownIds.ts index b62bf397c..e7dda2a2e 100644 --- a/lib/knownIds.ts +++ b/lib/knownIds.ts @@ -180,6 +180,10 @@ export default class KnownInternalNames { public static readonly EclipseMainnet: string = "ECLIPSE_MAINNET" + public static readonly SophonMainnet: string = "SOPHON_MAINNET" + + public static readonly SophonSepolia: string = "SOPHON_SEPOLIA" + } static Currencies = class { diff --git a/package.json b/package.json index 85ca82574..74c75cc21 100644 --- a/package.json +++ b/package.json @@ -90,8 +90,8 @@ "ton": "^13.9.0", "uuid": "^9.0.0", "vaul": "^1.1.0", - "viem": "^2.21.16", - "wagmi": "^2.12.16", + "viem": "^2.21.54", + "wagmi": "^2.12.54", "web-encoding": "^1.1.5", "web3": "1.8.0", "zksync": "0.13.1", diff --git a/yarn.lock b/yarn.lock index b3ebc2baf..1a60a9632 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3672,10 +3672,10 @@ dependencies: "@paulmillr/qr" "^0.2.1" -"@metamask/sdk@0.31.2": - version "0.31.2" - resolved "https://registry.yarnpkg.com/@metamask/sdk/-/sdk-0.31.2.tgz#2ec1c1c7cf6a444e65104862e83814a493047d72" - integrity sha512-6MWON2g1j7XwAHWam4trusGxeyhQweNLEHPsfuIxSwcsXoEm08Jj80OglJxQI4KwjcDnjSWBkQGG3mmK6ug/cA== +"@metamask/sdk@0.31.4": + version "0.31.4" + resolved "https://registry.yarnpkg.com/@metamask/sdk/-/sdk-0.31.4.tgz#2f9266e994ba838652925dc83e3409adfcae75ae" + integrity sha512-HLUN4IZGdyiy5YeebXmXi+ndpmrl6zslCQLdR2QHplIy4JmUL/eDyKNFiK7eBLVKXVVIDYFIb6g1iSEb+i8Kew== dependencies: "@babel/runtime" "^7.26.0" "@metamask/onboarding" "^1.0.1" @@ -5434,10 +5434,10 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz#427d5549943a9c6fce808e39ea64dbe60d4047f1" integrity sha512-WJgX9nzTqknM393q1QJDJmoW28kUfEnybeTfVNcNAPnIx210RXm2DiXiHzfNPJNIUUb1tJnz/l4QGtJ30PgWmA== -"@safe-global/safe-apps-provider@0.18.4": - version "0.18.4" - resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-provider/-/safe-apps-provider-0.18.4.tgz#53df912aa20d933f6b14c5bcb0737a8cd47def57" - integrity sha512-SWYeG3gyTO6wGHMSokfHakZ9isByn2mHsM0VohIorYFFEyGGmJ89btnTm+DqDUSoQtvWAatZB7XNy6CaYMvqtg== +"@safe-global/safe-apps-provider@0.18.5": + version "0.18.5" + resolved "https://registry.yarnpkg.com/@safe-global/safe-apps-provider/-/safe-apps-provider-0.18.5.tgz#745a932bda3739a8a298ae44ec6c465f6c4773b7" + integrity sha512-9v9wjBi3TwLsEJ3C2ujYoexp3pFJ0omDLH/GX91e2QB+uwCKTBYyhxFSrTQ9qzoyQd+bfsk4gjOGW87QcJhf7g== dependencies: "@safe-global/safe-apps-sdk" "^9.1.0" events "^3.3.0" @@ -9936,22 +9936,22 @@ tiny-invariant "^1.1.0" tiny-warning "^1.0.3" -"@wagmi/connectors@5.6.1": - version "5.6.1" - resolved "https://registry.yarnpkg.com/@wagmi/connectors/-/connectors-5.6.1.tgz#948ca387916136501da80989f3eba351b0c6a595" - integrity sha512-6nGxKSDtT6udnrW21SPqP7gcaZFpyRAz7Ecf2DelYh5OHpGk/FBNB8mtB/w0AVSCH6XRIpVK81pO412pPBiEYg== +"@wagmi/connectors@5.7.3": + version "5.7.3" + resolved "https://registry.yarnpkg.com/@wagmi/connectors/-/connectors-5.7.3.tgz#0e6d274d4734cbfeb8ad964b63b1edcfade42c63" + integrity sha512-i7Gk5M/Fc9gMvkVHbqw2kGtXvY8POsSY798/9I5npyglVjBddxoVk3xTYmcYTB1VIa4Fi0T2gLTHpQnpLrq1CQ== dependencies: "@coinbase/wallet-sdk" "4.2.3" - "@metamask/sdk" "0.31.2" - "@safe-global/safe-apps-provider" "0.18.4" + "@metamask/sdk" "0.31.4" + "@safe-global/safe-apps-provider" "0.18.5" "@safe-global/safe-apps-sdk" "9.1.0" "@walletconnect/ethereum-provider" "2.17.0" cbw-sdk "npm:@coinbase/wallet-sdk@3.9.3" -"@wagmi/core@2.16.0": - version "2.16.0" - resolved "https://registry.yarnpkg.com/@wagmi/core/-/core-2.16.0.tgz#b997b2544cd80b4aac4df25ccb2436bf77f9fbe1" - integrity sha512-sy4n7Jv6YCbT2jp4zQ/9H6l0A8StsN7P8mm2BRuODgW2w6Fj4j6h2xgYJD2tIjJHkLU/nvPJ7audZ55X7XQU/g== +"@wagmi/core@2.16.3": + version "2.16.3" + resolved "https://registry.yarnpkg.com/@wagmi/core/-/core-2.16.3.tgz#abbff0a19e75beaad56ffb90da772641552d49c3" + integrity sha512-SVovoWHaQ2AIkmGf+ucNijT6AHXcTMffFcLmcFF6++y21x+ge7Gkh3UoJiU91SDDv8n08eTQ9jbyia3GEgU5jQ== dependencies: eventemitter3 "5.0.1" mipd "0.0.7" @@ -22690,7 +22690,7 @@ vfile@^5.0.0: unist-util-stringify-position "^3.0.0" vfile-message "^3.0.0" -viem@2.x, viem@^2.1.1, viem@^2.21.1, viem@^2.21.16: +viem@2.x, viem@^2.1.1, viem@^2.21.1: version "2.21.55" resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.55.tgz#a57ad31fcf2a0f6c011b1909f02c94421ec4f781" integrity sha512-PgXew7C11cAuEtOSgRyQx2kJxEOPUwIwZA9dMglRByqJuFVA7wSGZZOOo/93iylAA8E15bEdqy9xulU3oKZ70Q== @@ -22719,6 +22719,21 @@ viem@^1.3.0: isows "1.0.3" ws "8.13.0" +viem@^2.21.54: + version "2.21.57" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.57.tgz#bedbb444bb42e07ccc2264a9a0441903a113aab8" + integrity sha512-Mw4f4Dw0+Y/wSHdynVmP4uh+Cw15HEoj8BOKvKH5nGA6oFZYRxSy9Ruu7ZG8jexeAVCZ57aIuXb0gNg6Vb1x0g== + dependencies: + "@noble/curves" "1.7.0" + "@noble/hashes" "1.6.1" + "@scure/bip32" "1.6.0" + "@scure/bip39" "1.5.0" + abitype "1.0.7" + isows "1.0.6" + ox "0.1.2" + webauthn-p256 "0.0.10" + ws "8.18.0" + vm-browserify@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" @@ -22729,13 +22744,13 @@ void-elements@3.1.0: resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== -wagmi@^2.12.16: - version "2.14.1" - resolved "https://registry.yarnpkg.com/wagmi/-/wagmi-2.14.1.tgz#8c6e1e389f8dab7c21d1c91e3c2fba4815c4fbdb" - integrity sha512-Lq/UFJVorjwJlFjXbU+Jtfo64PObNfUCPtwgqi+q/WGBWzG7CL0xmCsB3wPc+YZYwD8O9OqFDHfcggUi0qwcGA== +wagmi@^2.12.54: + version "2.14.6" + resolved "https://registry.yarnpkg.com/wagmi/-/wagmi-2.14.6.tgz#046db4c119f53c276c9f2d4b0034fe2ebc3ff05c" + integrity sha512-h8KDjPiXywZcKAbGttGDlZpwabZynR4lZ8eDO63tNgfxiMyhld0M5bMcB/u7XnH2xFgd0gq7PA2RVz96XMjazw== dependencies: - "@wagmi/connectors" "5.6.1" - "@wagmi/core" "2.16.0" + "@wagmi/connectors" "5.7.3" + "@wagmi/core" "2.16.3" use-sync-external-store "1.2.0" walker@^1.0.8: