diff --git a/package.json b/package.json index e6b0cd3e0..1146f4cbb 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "@astar-network/metamask-astar-adapter": "^0.5.4", "@astar-network/metamask-astar-types": "^0.6.1", "@ethersproject/bignumber": "^5.5.0", + "@layerzerolabs/scan-client": "^0.0.8", "@polkadot/api": "^10.9.1", "@polkadot/api-contract": "^10.9.1", "@polkadot/extension-dapp": "0.46.5", diff --git a/src/components/assets/EvmNativeToken.vue b/src/components/assets/EvmNativeToken.vue index d50f59de2..7c56c0048 100644 --- a/src/components/assets/EvmNativeToken.vue +++ b/src/components/assets/EvmNativeToken.vue @@ -43,7 +43,7 @@ - + @@ -51,7 +51,7 @@ {{ $t('assets.bridge') }} - + @@ -113,9 +113,12 @@ import ModalFaucet from 'src/components/assets/modals/ModalFaucet.vue'; import { useAccount, useBreakpoints, useFaucet, useNetworkInfo } from 'src/hooks'; import { faucetSethLink } from 'src/links'; import { getTokenImage } from 'src/modules/token'; -import { buildEthereumBridgePageLink, buildTransferPageLink } from 'src/router/routes'; +import { + buildEthereumBridgePageLink, + buildTransferPageLink, + buildLzBridgePageLink, +} from 'src/router/routes'; import { useStore } from 'src/store'; -import { stargateUrl } from '../../modules/zk-evm-bridge'; import { computed, defineComponent, ref, watchEffect } from 'vue'; export default defineComponent({ @@ -195,12 +198,12 @@ export default defineComponent({ width, screenSize, isTruncate, - stargateUrl, isAstar, truncate, handleModalFaucet, buildTransferPageLink, buildEthereumBridgePageLink, + buildLzBridgePageLink, }; }, }); diff --git a/src/components/assets/ZkAstr.vue b/src/components/assets/ZkAstr.vue index 2260122b8..8cb0f48af 100644 --- a/src/components/assets/ZkAstr.vue +++ b/src/components/assets/ZkAstr.vue @@ -42,13 +42,7 @@ - + @@ -56,7 +50,7 @@ {{ $t('assets.bridge') }} - + @@ -118,9 +112,9 @@ import { useNetworkInfo } from 'src/hooks'; import { useEthProvider } from 'src/hooks/custom-signature/useEthProvider'; import { addToEvmProvider } from 'src/hooks/helper/wallet'; import { Erc20Token, getErc20Explorer } from 'src/modules/token'; -import { buildTransferPageLink } from 'src/router/routes'; +import { buildTransferPageLink, buildLzBridgePageLink } from 'src/router/routes'; import { PropType, defineComponent } from 'vue'; -import { stargateUrl, vAstrOmniLink } from '../../modules/zk-evm-bridge'; +import { vAstrOmniLink } from '../../modules/zk-evm-bridge'; export default defineComponent({ components: {}, @@ -140,7 +134,7 @@ export default defineComponent({ return { ethProvider, - stargateUrl, + buildLzBridgePageLink, vAstrOmniLink, truncate, addToEvmProvider, diff --git a/src/components/assets/transfer/Information.vue b/src/components/assets/transfer/Information.vue index e4ac2ef4e..5bdb10aef 100644 --- a/src/components/assets/transfer/Information.vue +++ b/src/components/assets/transfer/Information.vue @@ -43,6 +43,11 @@ + + + + + {{ $t('assets.transferPage.noTxRecords') }} @@ -75,6 +80,7 @@ diff --git a/src/components/bridge/BridgeSelection.vue b/src/components/bridge/BridgeSelection.vue index 0020057b8..501721f7e 100644 --- a/src/components/bridge/BridgeSelection.vue +++ b/src/components/bridge/BridgeSelection.vue @@ -42,8 +42,12 @@ - - + + - + + + {{ $t('bridge.astarBridge.text2') }} + @@ -182,15 +189,20 @@ import { cbridgeAppLink } from 'src/c-bridge'; import { useAccount, useNetworkInfo } from 'src/hooks'; import { EthBridgeNetworkName } from 'src/modules/zk-evm-bridge'; -import { Path as RoutePath, buildEthereumBridgePageLink } from 'src/router/routes'; +import { + Path as RoutePath, + buildEthereumBridgePageLink, + buildLzBridgePageLink, +} from 'src/router/routes'; import { computed, defineComponent } from 'vue'; -import { stargateUrl, layerSwapLink, zKatanaBridgeUrl } from 'src/modules/zk-evm-bridge/index'; +import { layerSwapLink, zKatanaBridgeUrl } from 'src/modules/zk-evm-bridge/index'; export default defineComponent({ components: {}, setup() { const { currentAccount } = useAccount(); - const { isZkEvm, networkNameSubstrate, isMainnet, isZkyoto } = useNetworkInfo(); + const { isZkEvm, networkNameSubstrate, isMainnet, isZkyoto, isAstarZkEvm, isAstar, isH160 } = + useNetworkInfo(); const l1Name = computed(() => { return isZkyoto.value ? EthBridgeNetworkName.Sepolia : EthBridgeNetworkName.Ethereum; @@ -211,6 +223,10 @@ export default defineComponent({ return true; }); + const isEnableLzBridge = computed(() => { + return isH160.value && (isAstar.value || isAstarZkEvm.value); + }); + return { currentAccount, cbridgeAppLink, @@ -220,10 +236,11 @@ export default defineComponent({ l2Name, cbridgeNetworkName, buildEthereumBridgePageLink, - stargateUrl, + buildLzBridgePageLink, layerSwapLink, zKatanaBridgeUrl, isZkyoto, + isEnableLzBridge, }; }, }); diff --git a/src/components/bridge/layerzero/LayerZero.vue b/src/components/bridge/layerzero/LayerZero.vue new file mode 100644 index 000000000..412a5b6aa --- /dev/null +++ b/src/components/bridge/layerzero/LayerZero.vue @@ -0,0 +1,170 @@ + + + + + (isApproveMaxAmount = value)" + /> + + + + + + + + + diff --git a/src/components/bridge/layerzero/LzBridge.vue b/src/components/bridge/layerzero/LzBridge.vue new file mode 100644 index 000000000..4684fec3d --- /dev/null +++ b/src/components/bridge/layerzero/LzBridge.vue @@ -0,0 +1,320 @@ + + + + + + {{ $t('from') }} + + + + + + + + + + + {{ fromChainName }} + + + + + + reverseChain(fromChainName, toChainName)" + > + + + + + + + + + + {{ $t('bridge.disabledWithdrawal', { network: fromChainName }) }} + + + + + + {{ $t('to') }} + + + + + + + + + + + {{ toChainName }} + + + + + + + + + + + + + + + + + + + + {{ selectedToken.symbol }} + + + + + + inputHandler(e)" + /> + + + + + + + $emit('update:isApproveMaxAmount', event.target.checked)" + /> + + {{ $t('bridge.approvalMaxAmount') }} + + + + + + {{ $t(errMsg) }} + + + + + {{ $t('bridge.slippage', { percent: LayerZeroSlippage }) }} + + {{ + $t('bridge.feeOnTransaction', { + amount: + nativeTokenSymbol === 'ASTR' ? $n(truncate(transactionFee, 4)) : transactionFee, + symbol: nativeTokenSymbol, + }) + }} + + {{ $t('bridge.warningLzWithdrawal') }} + + + + + + {{ $t('approve') }} + + + {{ $t('bridge.bridge') }} + + + + + + + + + diff --git a/src/components/bridge/layerzero/SelectToken.vue b/src/components/bridge/layerzero/SelectToken.vue new file mode 100644 index 000000000..e7b49a056 --- /dev/null +++ b/src/components/bridge/layerzero/SelectToken.vue @@ -0,0 +1,80 @@ + + + + {{ $t('assets.transferPage.selectToken') }} + + + + + + + + {{ token.symbol }} + + + + {{ + $t('amountToken', { + amount: $n(truncate(token.fromChainBalance ?? 0)), + token: token.symbol, + }) + }} + + + + + + + + + diff --git a/src/components/bridge/layerzero/styles/layerzero.scss b/src/components/bridge/layerzero/styles/layerzero.scss new file mode 100644 index 000000000..616a79cb6 --- /dev/null +++ b/src/components/bridge/layerzero/styles/layerzero.scss @@ -0,0 +1,35 @@ +@import 'src/css/quasar.variables.scss'; + +.wrapper--bridge { + position: relative; + display: flex; + justify-content: center; +} + +.container--bridge { + display: grid; + row-gap: 32px; + margin-bottom: 24px; + margin-top: 52px; + @media (min-width: $xl) { + justify-content: center; + } +} + +.wrapper-containers { + display: flex; + flex-direction: column; + row-gap: 80px; + @media (min-width: $md) { + flex-direction: row; + column-gap: 24px; + row-gap: 0px; + } + @media (min-width: $lg) { + flex-direction: row; + column-gap: 40px; + } + @media (min-width: $xl) { + column-gap: 50px; + } +} diff --git a/src/components/bridge/layerzero/styles/lz-bridge.scss b/src/components/bridge/layerzero/styles/lz-bridge.scss new file mode 100644 index 000000000..3a26d785e --- /dev/null +++ b/src/components/bridge/layerzero/styles/lz-bridge.scss @@ -0,0 +1,263 @@ +@import 'src/css/quasar.variables.scss'; + +.wrapper--l1-bridge { + display: flex; + flex-direction: column; + align-items: center; +} + +.box--input-field { + display: grid; + row-gap: 12px; + padding: 9px 15px; + border-radius: 6px; + height: 88px; + background: transparent; + + border: 1px solid $navy-1; + @media (min-width: $xs) { + width: 344px; + } + @media (min-width: $sm) { + width: 412px; + } +} + +.rows { + display: grid; + row-gap: 16px; + margin-bottom: 8px; +} + +.btn-margin-adjuster { + margin-top: 24px; +} + +.row--box-error { + padding: 10px 20px; + border-radius: 6px; + width: 344px; + border: 1px solid $warning-red; + background: $box-red; + text-align: left; + @media (min-width: $sm) { + width: 412px; + } +} + +.box__row { + display: flex; + column-gap: 8px; + align-items: center; +} + +.box__space-between { + display: flex; + justify-content: space-between; +} + +.box__available { + display: flex; + column-gap: 10px; + align-items: center; +} + +.wrapper__row--button { + display: flex; + justify-content: center; +} + +.box__column--input-amount { + justify-self: flex-end; + width: 100%; + display: grid; +} + +.text--to--balance { + font-weight: 400; + font-size: 12px; + color: $gray-4; +} + +.text--available { + color: $astar-blue; + font-weight: 400; + font-size: 12px; +} + +.input--amount { + width: 180px; + font-size: 22px; + outline: none; + background: transparent; + text-align: right; + font-weight: 600; + color: $navy-1; + justify-self: flex-end; + @media (min-width: $md) { + width: 250px; + } +} + +.token-logo { + width: 24px; + height: 24px; + img { + border-radius: 50%; + } +} + +.row--buttons { + display: grid; + row-gap: 16px; + @media (min-width: $sm) { + grid-template-columns: 48% 48%; + justify-content: space-between; + row-gap: 0px; + } +} + +.icon--expand { + border-radius: 100%; + display: flex; + justify-content: center; + align-items: center; +} + +.button--confirm { + font-size: 16px; + font-weight: 600; + height: 44px; + width: 100%; +} + +.row--reverse { + display: flex; + justify-content: center; + position: relative; + margin-top: 16px; +} + +.icon--reverse { + position: absolute; + height: 32px; + width: 32px; + padding: 4px; + border-radius: 100%; + display: flex; + justify-content: center; + align-items: center; + border: 1px solid $gray-4; + cursor: pointer !important; + margin-top: -24px; + background: transparent; + transition: all 0.3s ease 0s; + &:hover { + border: 1px solid $astar-blue !important; + color: $astar-blue; + transition: all 0.3s ease 0s; + } +} + +.container--approve { + display: flex; + align-items: center; + column-gap: 8px; +} + +.input--checkbox { + display: flex; + column-gap: 8px; +} + +.input--checkbox input[type='checkbox'] { + display: none; + width: 20px; +} + +.input--checkbox input[type='checkbox'] + label { + display: none; + cursor: pointer; + display: inline-block; + position: relative; + padding-left: 32px; +} + +.input--checkbox input[type='checkbox'] + label::before { + content: ''; + position: absolute; + display: block; + box-sizing: border-box; + width: 20px; + height: 20px; + margin-top: -10px; + left: 0; + top: 50%; + border: 1px solid; + border-color: $navy-1; + background-color: transparent; + border-radius: 4px; +} + +.input--checkbox--checked input[type='checkbox'] + label::before { + border-color: $astar-blue !important; +} + +.input--checkbox input[type='checkbox']:checked + label::after { + content: ''; + position: absolute; + display: block; + box-sizing: border-box; + width: 14px; + height: 7px; + margin-top: -5px; + top: 50%; + left: 3px; + transform: rotate(-45deg); + border-bottom: 3px solid; + border-left: 3px solid; + border-color: $astar-blue; +} + +.container--warning { + display: flex; + flex-direction: column; + row-gap: 6px; + border: 1px solid $border-yellow; + padding: 8px 0; + padding-left: 24px; + width: 344px; + border-radius: 6px; + background: $transparent-yellow; + color: $warning-yellow; + @media (min-width: $sm) { + width: 412px; + } + + ul { + list-style-type: disc; + } +} + +.body--dark { + input { + color: white; + } + .box--input-field, + .icon--reverse { + background: transparent; + border: 1px solid $gray-3; + } + + .row--box-error { + background: $box-red-dark; + } + .input--checkbox input[type='checkbox'] + label::before { + border-color: $gray-3; + } +} + +.text-underline { + text-decoration: underline; + cursor: pointer; +} diff --git a/src/components/bridge/layerzero/styles/select-token.scss b/src/components/bridge/layerzero/styles/select-token.scss new file mode 100644 index 000000000..efdb8b023 --- /dev/null +++ b/src/components/bridge/layerzero/styles/select-token.scss @@ -0,0 +1,210 @@ +@import 'src/css/quasar.variables.scss'; + +.container--select-item { + border: 1px solid $gray-4; + border-radius: 6px; + box-sizing: border-box; + padding: 16px; + color: $gray-4; + height: 412px; + width: 348px; + overflow: auto; + @media (min-width: $md) { + width: 320px; + } + @media (min-width: $xl) { + width: 420px; + } +} + +.container--select-item-mobile { + border-radius: 6px; + box-sizing: border-box; + color: $gray-4; + background-color: transparent; + padding: 24px; + max-height: 420px; + overflow: auto; + padding-top: 0; +} + +.row--title { + display: flex; + align-items: center; + column-gap: 8px; + margin-bottom: 12px; + font-size: 16px; + font-weight: 700; +} + +.container--items { + display: flex; + flex-direction: column; + row-gap: 8px; +} + +.row--item { + display: flex; + justify-content: space-between; + align-items: center; + cursor: pointer; + border-radius: 8px; + margin-left: -8px; + margin-right: -8px; + background-color: white; + border: 1px solid transparent; + transition: all 0.3s ease 0s; + &:hover { + transition: all 0.3s ease 0s; + border: 1px solid $astar-blue; + } + @media (min-width: $md) { + background-color: transparent; + padding-top: 0; + padding-bottom: 0; + &:hover { + border: 1px solid transparent; + background-color: white; + } + } +} + +.row--item-selected { + border: 1px solid $astar-blue; + @media (min-width: $md) { + background-color: transparent; + border: 1px solid transparent; + } +} + +.column--item-name { + display: flex; + column-gap: 8px; + align-items: center; + padding: 16px; +} + +.item-logo { + width: 24px; + height: 24px; + border-radius: 50%; +} + +.native-token-logo { + width: 24px; + border-radius: 50%; +} + +.text--item-name { + color: $navy-1; + font-weight: 700; + font-size: 16px; + @media (min-width: $md) { + font-weight: 600; + font-size: 16px; + } +} + +.text--token-amount { + font-size: 12px; + font-weight: 400; + color: $navy-1; +} + +.row--import-token { + display: flex; + justify-content: space-between; + align-items: center; + height: 24px; +} + +.icon--warning { + color: $warning-red; +} + +.row--warning { + display: flex; + align-items: center; + column-gap: 8px; + margin-bottom: 8px; +} + +.button--confirm { + width: 100%; + font-size: 22px; + font-weight: 600; + height: 44px; +} + +.container--token-info { + display: flex; + flex-direction: column; + row-gap: 6px; + margin-top: 16px; + margin-bottom: 8px; +} + +.column--chain { + display: flex; + align-items: center; + column-gap: 4px; + img { + margin-top: 2px; + } +} + +.row--to-chain-address { + display: none !important; + @media (min-width: $xl) { + display: flex !important; + } +} + +.icon--chain { + display: none; + @media (min-width: $xl) { + display: block; + } +} + +.text--link { + color: $astar-blue; +} + +.icon--copy { + stroke: $astar-blue; + font-size: 20px; +} + +.body--dark { + .container--select-item { + color: $gray-1; + border: 1px solid $gray-4; + } + .row--item { + background-color: transparent; + @media (min-width: $md) { + &:hover { + background: rgba(255, 255, 255, 0.02); + } + } + } + .row--item-selected { + @media (min-width: $md) { + background-color: $gray-5; + } + } + .text--item-name { + color: $gray-1; + } + .text--token-amount { + color: $gray-1; + } + input { + color: white; + } + .box--input-field { + background: transparent; + border: 1px solid $gray-3; + } +} diff --git a/src/components/common/LzHistory.vue b/src/components/common/LzHistory.vue new file mode 100644 index 000000000..e41021859 --- /dev/null +++ b/src/components/common/LzHistory.vue @@ -0,0 +1,53 @@ + + + + + + + + + + + {{ time }} + + [{{ tx.status }}] + + + {{ tx.note }} + + + + + + + + + + + + diff --git a/src/components/common/styles/transaction-history.scss b/src/components/common/styles/transaction-history.scss index 0abfe1917..4ef4378ae 100644 --- a/src/components/common/styles/transaction-history.scss +++ b/src/components/common/styles/transaction-history.scss @@ -33,6 +33,27 @@ align-items: center; } +@mixin icon-mark { + transition: all 0.3s ease 0s; + margin-bottom: -8px; + opacity: 0.5; +} + +.icon--check { + @include icon-mark; + color: $connected-green; +} + +.icon--pending { + @include icon-mark; + color: $warning-yellow; +} + +.icon--failed { + @include icon-mark; + color: $warning-red; +} + .icon--check { opacity: 0.5; color: $connected-green; diff --git a/src/config/web3/abi/layerzero/oft-astar-bridge-abi.json b/src/config/web3/abi/layerzero/oft-astar-bridge-abi.json new file mode 100644 index 000000000..cb5a756db --- /dev/null +++ b/src/config/web3/abi/layerzero/oft-astar-bridge-abi.json @@ -0,0 +1,1403 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "uint8", + "name": "_sharedDecimals", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_lzEndpoint", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + } + ], + "name": "CallOFTReceivedSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "MessageFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "NonContractAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReceiveFromChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_payloadHash", + "type": "bytes32" + } + ], + "name": "RetryMessageSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "SendToChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "feeBp", + "type": "uint16" + } + ], + "name": "SetDefaultFeeBp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "dstchainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "feeBp", + "type": "uint16" + } + ], + "name": "SetFeeBp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeOwner", + "type": "address" + } + ], + "name": "SetFeeOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "_type", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minDstGas", + "type": "uint256" + } + ], + "name": "SetMinDstGas", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "precrime", + "type": "address" + } + ], + "name": "SetPrecrime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "SetTrustedRemote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "BP_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_PAYLOAD_SIZE_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NO_EXTRA_GAS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND_AND_CALL", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "_from", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_gasForCall", + "type": "uint256" + } + ], + "name": "callOnOFTReceived", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "chainIdToFeeBps", + "outputs": [ + { + "internalType": "uint16", + "name": "feeBP", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "creditedPackets", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFeeBp", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_dstGasForCall", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "_useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendAndCallFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "forceResumeReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + } + ], + "name": "getConfig", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + } + ], + "name": "getTrustedRemoteAddress", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "isTrustedRemote", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lzEndpoint", + "outputs": [ + { + "internalType": "contract ILayerZeroEndpoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "lzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "minDstGasLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "nonblockingLzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "outboundAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "payloadSizeLimitLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "precrime", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "quoteOFTFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "retryMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_dstGasForCall", + "type": "uint64" + }, + { + "components": [ + { + "internalType": "address payable", + "name": "refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "internalType": "struct ICommonOFT.LzCallParams", + "name": "_callParams", + "type": "tuple" + } + ], + "name": "sendAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minAmount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address payable", + "name": "refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "internalType": "struct ICommonOFT.LzCallParams", + "name": "_callParams", + "type": "tuple" + } + ], + "name": "sendFrom", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_config", + "type": "bytes" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_feeBp", + "type": "uint16" + } + ], + "name": "setDefaultFeeBp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "_enabled", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "_feeBp", + "type": "uint16" + } + ], + "name": "setFeeBp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeOwner", + "type": "address" + } + ], + "name": "setFeeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_packetType", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_minGas", + "type": "uint256" + } + ], + "name": "setMinDstGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_size", + "type": "uint256" + } + ], + "name": "setPayloadSizeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "name": "setPrecrime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setReceiveVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "setTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sharedDecimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "trustedRemoteLookup", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/src/config/web3/abi/layerzero/oft-astar-native-abi.json b/src/config/web3/abi/layerzero/oft-astar-native-abi.json new file mode 100644 index 000000000..cc11b424e --- /dev/null +++ b/src/config/web3/abi/layerzero/oft-astar-native-abi.json @@ -0,0 +1,1739 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_lzEndpoint", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + } + ], + "name": "CallOFTReceivedSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_dst", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "MessageFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "NonContractAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReceiveFromChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_payloadHash", + "type": "bytes32" + } + ], + "name": "RetryMessageSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "SendToChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "feeBp", + "type": "uint16" + } + ], + "name": "SetDefaultFeeBp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "dstchainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "feeBp", + "type": "uint16" + } + ], + "name": "SetFeeBp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeOwner", + "type": "address" + } + ], + "name": "SetFeeOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "_type", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minDstGas", + "type": "uint256" + } + ], + "name": "SetMinDstGas", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "precrime", + "type": "address" + } + ], + "name": "SetPrecrime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "SetTrustedRemote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_src", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "Withdrawal", + "type": "event" + }, + { + "inputs": [], + "name": "BP_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_PAYLOAD_SIZE_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NO_EXTRA_GAS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND_AND_CALL", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "_from", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_gasForCall", + "type": "uint256" + } + ], + "name": "callOnOFTReceived", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "chainIdToFeeBps", + "outputs": [ + { + "internalType": "uint16", + "name": "feeBP", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "creditedPackets", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFeeBp", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_dstGasForCall", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "_useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendAndCallFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "forceResumeReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + } + ], + "name": "getConfig", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + } + ], + "name": "getTrustedRemoteAddress", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "isTrustedRemote", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lzEndpoint", + "outputs": [ + { + "internalType": "contract ILayerZeroEndpoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "lzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "minDstGasLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "nonblockingLzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "outboundAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "payloadSizeLimitLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "precrime", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "quoteOFTFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "retryMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_dstGasForCall", + "type": "uint64" + }, + { + "components": [ + { + "internalType": "address payable", + "name": "refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "internalType": "struct ICommonOFT.LzCallParams", + "name": "_callParams", + "type": "tuple" + } + ], + "name": "sendAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minAmount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address payable", + "name": "refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "internalType": "struct ICommonOFT.LzCallParams", + "name": "_callParams", + "type": "tuple" + } + ], + "name": "sendFrom", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_config", + "type": "bytes" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_feeBp", + "type": "uint16" + } + ], + "name": "setDefaultFeeBp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "_enabled", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "_feeBp", + "type": "uint16" + } + ], + "name": "setFeeBp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeOwner", + "type": "address" + } + ], + "name": "setFeeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_packetType", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_minGas", + "type": "uint256" + } + ], + "name": "setMinDstGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_size", + "type": "uint256" + } + ], + "name": "setPayloadSizeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "name": "setPrecrime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setReceiveVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "setTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sharedDecimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "trustedRemoteLookup", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/src/config/web3/abi/layerzero/oft-zkevm-bridge-abi.json b/src/config/web3/abi/layerzero/oft-zkevm-bridge-abi.json new file mode 100644 index 000000000..c92145d8c --- /dev/null +++ b/src/config/web3/abi/layerzero/oft-zkevm-bridge-abi.json @@ -0,0 +1,1679 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "uint8", + "name": "_sharedDecimals", + "type": "uint8" + }, + { + "internalType": "address", + "name": "_lzEndpoint", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_hash", + "type": "bytes32" + } + ], + "name": "CallOFTReceivedSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_reason", + "type": "bytes" + } + ], + "name": "MessageFailed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_address", + "type": "address" + } + ], + "name": "NonContractAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Paused", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "ReceiveFromChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "_payloadHash", + "type": "bytes32" + } + ], + "name": "RetryMessageSuccess", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "SendToChain", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "feeBp", + "type": "uint16" + } + ], + "name": "SetDefaultFeeBp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "dstchainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bool", + "name": "enabled", + "type": "bool" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "feeBp", + "type": "uint16" + } + ], + "name": "SetFeeBp", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "feeOwner", + "type": "address" + } + ], + "name": "SetFeeOwner", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "_type", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_minDstGas", + "type": "uint256" + } + ], + "name": "SetMinDstGas", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "precrime", + "type": "address" + } + ], + "name": "SetPrecrime", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "SetTrustedRemote", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "SetTrustedRemoteAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "BP_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DEFAULT_PAYLOAD_SIZE_LIMIT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "NO_EXTRA_GAS", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "PT_SEND_AND_CALL", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "_from", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "_to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "_gasForCall", + "type": "uint256" + } + ], + "name": "callOnOFTReceived", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "chainIdToFeeBps", + "outputs": [ + { + "internalType": "uint16", + "name": "feeBP", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "enabled", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "circulatingSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "creditedPackets", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultFeeBp", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_dstGasForCall", + "type": "uint64" + }, + { + "internalType": "bool", + "name": "_useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendAndCallFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "_useZro", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "_adapterParams", + "type": "bytes" + } + ], + "name": "estimateSendFee", + "outputs": [ + { + "internalType": "uint256", + "name": "nativeFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "zroFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "failedMessages", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "forceResumeReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + } + ], + "name": "getConfig", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + } + ], + "name": "getTrustedRemoteAddress", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + } + ], + "name": "isTrustedRemote", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lzEndpoint", + "outputs": [ + { + "internalType": "contract ILayerZeroEndpoint", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "lzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "minDstGasLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "nonblockingLzReceive", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "payloadSizeLimitLookup", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "precrime", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "quoteOFTFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_srcChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_srcAddress", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + } + ], + "name": "retryMessage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_payload", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "_dstGasForCall", + "type": "uint64" + }, + { + "components": [ + { + "internalType": "address payable", + "name": "refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "internalType": "struct ICommonOFT.LzCallParams", + "name": "_callParams", + "type": "tuple" + } + ], + "name": "sendAndCall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bytes32", + "name": "_toAddress", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_minAmount", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address payable", + "name": "refundAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "zroPaymentAddress", + "type": "address" + }, + { + "internalType": "bytes", + "name": "adapterParams", + "type": "bytes" + } + ], + "internalType": "struct ICommonOFT.LzCallParams", + "name": "_callParams", + "type": "tuple" + } + ], + "name": "sendFrom", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_chainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_configType", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "_config", + "type": "bytes" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_feeBp", + "type": "uint16" + } + ], + "name": "setDefaultFeeBp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "_enabled", + "type": "bool" + }, + { + "internalType": "uint16", + "name": "_feeBp", + "type": "uint16" + } + ], + "name": "setFeeBp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_feeOwner", + "type": "address" + } + ], + "name": "setFeeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "_packetType", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_minGas", + "type": "uint256" + } + ], + "name": "setMinDstGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_dstChainId", + "type": "uint16" + }, + { + "internalType": "uint256", + "name": "_size", + "type": "uint256" + } + ], + "name": "setPayloadSizeLimit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_precrime", + "type": "address" + } + ], + "name": "setPrecrime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setReceiveVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_version", + "type": "uint16" + } + ], + "name": "setSendVersion", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_path", + "type": "bytes" + } + ], + "name": "setTrustedRemote", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "_remoteChainId", + "type": "uint16" + }, + { + "internalType": "bytes", + "name": "_remoteAddress", + "type": "bytes" + } + ], + "name": "setTrustedRemoteAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "sharedDecimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "trustedRemoteLookup", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/src/config/web3/index.ts b/src/config/web3/index.ts index a46ee9055..2f06b596e 100644 --- a/src/config/web3/index.ts +++ b/src/config/web3/index.ts @@ -14,6 +14,7 @@ export { checkAllowance, getTokenImage, handleCheckProviderChainId, + addressToBytes32, } from 'src/config/web3/utils'; export { contractInstance, Staking } from 'src/config/web3/contracts'; diff --git a/src/config/web3/utils/index.ts b/src/config/web3/utils/index.ts index 9781ebb67..2b9131a94 100644 --- a/src/config/web3/utils/index.ts +++ b/src/config/web3/utils/index.ts @@ -361,3 +361,18 @@ export const handleCheckProviderChainId = async (provider: any): Promise { + if (!address.startsWith('0x')) { + throw Error('Address must start with 0x'); + } + const abiCoder = new ethers.utils.AbiCoder(); + const byte32Address = abiCoder.encode(['address'], [address]); + const byte32AddressLength = 66; + + if (byte32Address.length !== byte32AddressLength) { + throw Error('There is an error with formatting address'); + } + + return byte32Address; +}; diff --git a/src/hooks/bridge/useL1Bridge.ts b/src/hooks/bridge/useL1Bridge.ts index 2b9f77332..5560fd2f4 100644 --- a/src/hooks/bridge/useL1Bridge.ts +++ b/src/hooks/bridge/useL1Bridge.ts @@ -263,7 +263,7 @@ export const useL1Bridge = () => { } else if (providerChainIdRef !== fromChainId.value) { errMsg.value = t('warning.selectedInvalidNetworkInWallet'); } else if (isBalanceNotEnough) { - errMsg.value = t('warning.balanceNotEnough'); + errMsg.value = t('warning.balanceNotEnough', { symbol: 'ETH' }); } else { errMsg.value = ''; } diff --git a/src/hooks/bridge/useLayerZeroBridge.ts b/src/hooks/bridge/useLayerZeroBridge.ts new file mode 100644 index 000000000..f6e76b1fa --- /dev/null +++ b/src/hooks/bridge/useLayerZeroBridge.ts @@ -0,0 +1,463 @@ +import { ethers, constants as ethersConstants } from 'ethers'; +import { debounce } from 'lodash-es'; +import { checkAllowance, getTokenBal, setupNetwork } from 'src/config/web3'; +import { useAccount, useNetworkInfo } from 'src/hooks'; +import { astarNativeTokenErcAddr } from 'src/modules/xcm'; +import { + LayerZeroId, + LayerZeroNetworkName, + LayerZeroToken, + LayerZeroTokens, + LayerZeroSlippage, + layerZeroId, + lzBridgeChainId, + LayerZeroChainId, +} from 'src/modules/zk-evm-bridge'; +import { useStore } from 'src/store'; +import { container } from 'src/v2/common'; +import { ILzBridgeService } from 'src/v2/services/ILzBridgeService'; +import { Symbols } from 'src/v2/symbols'; +import { WatchCallback, computed, onUnmounted, ref, watch } from 'vue'; +import { useI18n } from 'vue-i18n'; +import { useEthProvider } from '../custom-signature/useEthProvider'; +import { EthereumProvider } from '../types/CustomSignature'; +import { showLoading } from 'src/modules/extrinsic/utils'; +import { HistoryTxType, addLzHistories } from 'src/modules/account'; +import { isHex } from '@polkadot/util'; + +export const useLayerZeroBridge = () => { + const { isAstar } = useNetworkInfo(); + + const lzTokens = ref([]); + const selectedToken = ref(LayerZeroTokens[0]); + const importTokenAddress = ref(''); + const bridgeAmt = ref(null); + const toBridgeBalance = ref(0); + const fromBridgeBalance = ref(0); + const isGasPayable = ref(undefined); + const isLoadingGasPayable = ref(true); + const errMsg = ref(''); + const fromChainName = ref( + isAstar.value ? LayerZeroNetworkName.AstarEvm : LayerZeroNetworkName.AstarZk + ); + const toChainName = ref( + isAstar.value ? LayerZeroNetworkName.AstarZk : LayerZeroNetworkName.AstarEvm + ); + const isApproved = ref(false); + const isApproving = ref(false); + const isApproveMaxAmount = ref(false); + const providerChainId = ref(0); + const transactionFee = ref(0); + + const resetStates = (): void => { + bridgeAmt.value = ''; + fromBridgeBalance.value = 0; + toBridgeBalance.value = 0; + transactionFee.value = 0; + errMsg.value = ''; + isApproveMaxAmount.value = false; + isApproving.value = false; + isApproved.value = false; + }; + + const store = useStore(); + const { t } = useI18n(); + const { currentAccount } = useAccount(); + const { web3Provider, ethProvider } = useEthProvider(); + + const isLoading = computed(() => store.getters['general/isLoading']); + const fromChainId = computed( + () => lzBridgeChainId[fromChainName.value as LayerZeroNetworkName] + ); + + const fromLzId = computed( + () => layerZeroId[fromChainName.value as LayerZeroNetworkName] + ); + + const toChainId = computed( + () => lzBridgeChainId[toChainName.value as LayerZeroNetworkName] + ); + + const toLzId = computed( + () => layerZeroId[toChainName.value as LayerZeroNetworkName] + ); + + const isDisabledBridge = computed(() => { + const isLessAmount = + 0 >= Number(bridgeAmt.value) || fromBridgeBalance.value < Number(bridgeAmt.value); + return errMsg.value !== '' || isLessAmount; + }); + + const setSelectedToken = (token: LayerZeroToken): void => { + selectedToken.value = token; + }; + + const setIsApproving = (result: boolean) => { + isApproving.value = result; + }; + + const setIsApproved = async (): Promise => { + const fromChainIdRef = fromChainId.value as number; + const senderAddress = currentAccount.value; + const fromNetworkId = fromLzId.value; + const contractAddress = selectedToken.value.oftBridgeContract[fromNetworkId]; + const tokenAddress = selectedToken.value.tokenAddress[fromNetworkId]; + const decimals = selectedToken.value.decimals[fromNetworkId]; + const amount = bridgeAmt.value ?? '0'; + + const isApprovalRequired = + tokenAddress !== astarNativeTokenErcAddr && contractAddress !== tokenAddress; + + if (!isApprovalRequired) { + isApproved.value = true; + return; + } + if (!amount) return; + try { + const amountAllowance = await checkAllowance({ + srcChainId: fromChainIdRef, + senderAddress, + contractAddress, + tokenAddress, + }); + const formattedAllowance = ethers.utils.formatUnits(amountAllowance, decimals).toString(); + console.info('allowance: ', formattedAllowance, selectedToken.value.symbol[fromNetworkId]); + isApproved.value = Number(formattedAllowance) >= Number(amount); + } catch (error) { + console.error(error); + isApproved.value = false; + } + }; + + const initLzTokens = async (): Promise => { + try { + const address = currentAccount.value; + if (!address) return; + + const fromNetworkId = fromLzId.value; + const toNetworkId = toLzId.value; + const balTokens = await Promise.all( + LayerZeroTokens.map(async (token: LayerZeroToken) => { + const [fromChainBalance, toChainBalance] = await Promise.all([ + getTokenBal({ + address, + tokenAddress: token.tokenAddress[fromNetworkId], + srcChainId: lzBridgeChainId[fromChainName.value], + tokenSymbol: token.symbol, + }), + getTokenBal({ + address, + tokenAddress: token.tokenAddress[toNetworkId], + srcChainId: lzBridgeChainId[toChainName.value], + tokenSymbol: token.symbol, + }), + setBridgeBalance(), + ]); + return { + ...token, + fromChainBalance: Number(fromChainBalance), + toChainBalance: Number(toChainBalance), + }; + }) + ); + + const sortedTokens = balTokens + .sort((a, b) => { + if (a.symbol < b.symbol) { + return -1; + } + if (a.symbol > b.symbol) { + return 1; + } + return 0; + }) + .sort((a, b) => Number(b.fromChainBalance) - Number(a.fromChainBalance)); + + const moveAstrToFront = (tokens: LayerZeroToken[]): LayerZeroToken[] => { + const astrIndex = tokens.findIndex((token) => token.symbol === 'ASTR'); + if (astrIndex > -1) { + const [astrToken] = tokens.splice(astrIndex, 1); + tokens.unshift(astrToken); + } + return tokens; + }; + + lzTokens.value = moveAstrToFront(sortedTokens); + } catch (error) { + console.error(error); + } + }; + + const inputHandler = (event: any): void => { + bridgeAmt.value = event.target.value; + }; + + const inputImportTokenHandler = (event: any): void => { + importTokenAddress.value = event.target.value; + }; + + const setBridgeBalance = async (): Promise => { + if (!currentAccount.value || !selectedToken.value) { + return; + } + try { + showLoading(store.dispatch, true); + const [fromChainBalance, toChainBalance] = await Promise.all([ + getTokenBal({ + address: currentAccount.value, + tokenAddress: selectedToken.value.tokenAddress[fromLzId.value] as string, + srcChainId: lzBridgeChainId[fromChainName.value], + tokenSymbol: selectedToken.value.symbol, + }), + getTokenBal({ + address: currentAccount.value, + tokenAddress: selectedToken.value.tokenAddress[toLzId.value], + srcChainId: lzBridgeChainId[toChainName.value], + tokenSymbol: selectedToken.value.symbol, + }), + ]); + + fromBridgeBalance.value = Number(fromChainBalance); + toBridgeBalance.value = Number(toChainBalance); + } catch (error) { + console.error(error); + } finally { + showLoading(store.dispatch, false); + } + }; + + const setErrorMsg = (): void => { + const isLoadingGasPayableRef = isLoadingGasPayable.value; + if (isLoading.value || isLoadingGasPayableRef) return; + const bridgeAmtRef = Number(bridgeAmt.value); + const providerChainIdRef = providerChainId.value; + const selectedTokenRef = selectedToken.value; + const isGasPayableRef = isGasPayable.value; + const isBalanceNotEnough = !isGasPayableRef && bridgeAmtRef > 0 && isApproved.value; + + try { + if (bridgeAmtRef > fromBridgeBalance.value) { + errMsg.value = t('warning.insufficientBalance', { + token: selectedTokenRef.symbol, + }); + } else if (providerChainIdRef !== fromChainId.value) { + errMsg.value = t('warning.selectedInvalidNetworkInWallet'); + } else if (isBalanceNotEnough) { + errMsg.value = t('warning.balanceNotEnough', { + symbol: fromChainId.value === LayerZeroChainId.Astar ? 'ASTR' : 'ETH', + }); + } else { + errMsg.value = ''; + } + } catch (error: any) { + errMsg.value = error.message; + } + }; + + const reverseChain = async ( + fromChain: LayerZeroNetworkName, + toChain: LayerZeroNetworkName + ): Promise => { + fromChainName.value = toChain; + toChainName.value = fromChain; + resetStates(); + }; + + const setProviderChainId: WatchCallback<[number, EthereumProvider | undefined]> = async ( + [fromChainId, provider], + _, + registerCleanup + ) => { + try { + if (!provider || !web3Provider.value || !ethProvider.value) return; + const chainId = await web3Provider.value.eth.getChainId(); + providerChainId.value = chainId; + + providerChainId.value = await web3Provider.value!.eth.net.getId(); + if (providerChainId.value !== fromChainId) { + await setupNetwork({ network: fromChainId, provider: ethProvider.value }); + const chainId = await web3Provider.value.eth.getChainId(); + providerChainId.value = chainId; + } + + const handleChainChanged = (chainId: string) => { + providerChainId.value = Number(chainId); + }; + + //subscribe to chainChanged event + provider.on('chainChanged', handleChainChanged); + + registerCleanup(() => { + // unsubscribe from chainChanged event to prevent memory leak + provider.removeListener('chainChanged', handleChainChanged); + }); + } catch (error) { + console.error(error); + } + }; + + const handleApprove = async (): Promise => { + if (!bridgeAmt.value) return ''; + const lzBridgeService = container.get(Symbols.LzBridgeService); + const amount = isApproveMaxAmount.value + ? ethersConstants.MaxUint256 + : ethers.utils + .parseUnits(bridgeAmt.value, selectedToken.value.decimals[fromLzId.value]) + .toString(); + return await lzBridgeService.approve({ + amount: String(amount), + contractAddress: selectedToken.value.oftBridgeContract[fromLzId.value], + senderAddress: currentAccount.value, + tokenAddress: selectedToken.value.tokenAddress[fromLzId.value], + fromChainId: fromChainId.value, + }); + }; + + const calcMinAmount = (amount: number): number => { + // Memo: LayerZeroSlippage: 0.5% + const result = amount * (1 - LayerZeroSlippage / 100); + // Memo: resolve the issue due to the limitations of floating-point precision in JS. + return parseFloat(result.toFixed(5)); + }; + + const handleBridge = async (): Promise => { + if (!bridgeAmt.value || !isApproved.value) return ''; + const lzBridgeService = container.get(Symbols.LzBridgeService); + const amount = Number(bridgeAmt.value); + + const isNativeToken = + fromChainName.value === LayerZeroNetworkName.AstarEvm && + selectedToken.value.symbol === 'ASTR'; + + const hash = await lzBridgeService.bridgeLzAsset({ + senderAddress: currentAccount.value, + amount, + minAmount: calcMinAmount(amount), + fromNetworkId: fromLzId.value, + destNetworkId: toLzId.value, + tokenAddress: selectedToken.value.tokenAddress[fromLzId.value], + isNativeToken, + token: selectedToken.value, + fromChainId: fromChainId.value, + }); + + if (isHex(hash)) { + addLzHistories({ + hash: hash, + type: HistoryTxType.LZ_BRIDGE, + address: currentAccount.value, + amount: bridgeAmt.value, + symbol: selectedToken.value.symbol, + fromChainId: fromChainId.value, + toChainId: toChainId.value, + }); + } + + await setIsApproved(); + bridgeAmt.value = ''; + isApproveMaxAmount.value = false; + return hash; + }; + + const setIsGasPayable = async (): Promise => { + try { + if (errMsg.value || !currentAccount.value) return; + isLoadingGasPayable.value = true; + const lzBridgeService = container.get(Symbols.LzBridgeService); + const amount = bridgeAmt.value ? Number(bridgeAmt.value) : 0.01; + const isNativeToken = + fromChainName.value === LayerZeroNetworkName.AstarEvm && + selectedToken.value.symbol === 'ASTR'; + + const { isGasPayable: resIsGasPayable, fee } = await lzBridgeService.dryRunBridgeAsset({ + senderAddress: currentAccount.value, + amount, + minAmount: calcMinAmount(amount), + fromNetworkId: fromLzId.value, + destNetworkId: toLzId.value, + tokenAddress: selectedToken.value.tokenAddress[fromLzId.value], + isNativeToken, + token: selectedToken.value, + fromChainId: fromChainId.value, + }); + transactionFee.value = fee; + isGasPayable.value = resIsGasPayable; + } catch (error) { + // Memo: can be ignore 'outOfFund' error due to the token balance is not enough because of hardcoding in amount variable above + console.error(error); + } finally { + isLoadingGasPayable.value = false; + } + }; + + watch([fromChainId, ethProvider], setProviderChainId, { immediate: true }); + watch([providerChainId, isLoading, bridgeAmt, selectedToken, isGasPayable], setErrorMsg, { + immediate: false, + }); + + watch([fromChainName, selectedToken], setBridgeBalance, { + immediate: false, + }); + watch([currentAccount, fromChainName], initLzTokens, { immediate: true }); + + const debounceDelay = 500; + const debounceIsGasPayable = 1000; + const debouncedSetIsApproved = debounce(setIsApproved, debounceDelay); + const debouncedSetIsGasPayable = debounce(setIsGasPayable, debounceIsGasPayable); + + watch([selectedToken, fromChainId, currentAccount, bridgeAmt], debouncedSetIsApproved, { + immediate: true, + }); + + watch( + [bridgeAmt, fromChainName, currentAccount, errMsg, providerChainId, currentAccount], + debouncedSetIsGasPayable, + { + immediate: false, + } + ); + + watch([selectedToken, fromChainId], resetStates, { + immediate: false, + }); + + const autoFetchAllowanceHandler = setInterval( + async () => { + if (!isApproved.value) { + await setIsApproved(); + } + }, + isApproving.value ? 5 : 30 * 1000 + ); + + onUnmounted(() => { + clearInterval(autoFetchAllowanceHandler); + }); + + return { + bridgeAmt, + errMsg, + isDisabledBridge, + fromBridgeBalance, + toBridgeBalance, + fromChainName, + toChainName, + importTokenAddress, + fromChainId, + toChainId, + lzTokens, + selectedToken, + isApproved, + isApproving, + isApproveMaxAmount, + transactionFee, + setIsApproving, + setSelectedToken, + inputHandler, + inputImportTokenHandler, + resetStates, + reverseChain, + handleBridge, + handleApprove, + }; +}; diff --git a/src/hooks/index.ts b/src/hooks/index.ts index 81724933d..0029b2a4b 100644 --- a/src/hooks/index.ts +++ b/src/hooks/index.ts @@ -48,6 +48,7 @@ export * from './ui/useBalloons'; export * from './bridge/useL1Bridge'; export * from './bridge/useL1History'; export * from './bridge/useImportToken'; +export * from './bridge/useLayerZeroBridge'; export * from './dapps-staking/useCompoundRewards'; export * from './useTokenDistribution'; export * from './useTokenCirculation'; diff --git a/src/hooks/useNetworkInfo.ts b/src/hooks/useNetworkInfo.ts index 75e7fb55d..8a48a9b56 100644 --- a/src/hooks/useNetworkInfo.ts +++ b/src/hooks/useNetworkInfo.ts @@ -33,6 +33,7 @@ export function useNetworkInfo() { const isZkyoto = computed(() => currentNetworkIdx.value === endpointKey.ZKYOTO); const isAstarZkEvm = computed(() => currentNetworkIdx.value === endpointKey.ASTAR_ZKEVM); const isAstar = computed(() => currentNetworkIdx.value === endpointKey.ASTAR); + const isH160 = computed(() => store.getters['general/isH160Formatted']); const currentNetworkChain = computed(() => { if (isZkEvm.value) { @@ -121,5 +122,6 @@ export function useNetworkInfo() { isAstarZkEvm, isAstar, dappStakingCurrency, + isH160, }; } diff --git a/src/i18n/en-US/index.ts b/src/i18n/en-US/index.ts index e1541af14..1400a7865 100644 --- a/src/i18n/en-US/index.ts +++ b/src/i18n/en-US/index.ts @@ -68,7 +68,8 @@ export default { blankDestAddress: 'Destination address is blank', inputtedInvalidAddress: 'Inputted invalid address', selectedInvalidNetworkInWallet: 'Selected invalid network in your wallet', - balanceNotEnough: 'You do not have enough ETH in your account to pay for the transaction fee', + balanceNotEnough: + 'You do not have enough {symbol} in your account to pay for the transaction fee', insufficientBridgeAmount: 'Minimum transfer amount is {amount} {token}', insufficientOriginChainBalance: 'Minimum balance on {chain} network is {amount} {token}', insufficientOriginChainNativeBalance: 'Insufficient native token balance on {chain}', @@ -1025,8 +1026,8 @@ export default { astarBridge: { title: 'LayerZero', tag: 'ASTR', - text: 'Transfer ASTR token between Astar EVM and Astar zkEVM.', - text2: 'Currently under development', + text: 'Transfer assets between Astar EVM and Astar zkEVM.', + text2: 'Available on Astar zkEVM and Astar EVM. Switch the network to use it.', }, celerBridge: { title: 'Celer Bridge', @@ -1039,8 +1040,12 @@ export default { text: '3rd Party Bridge. Fast and reliable crypto transfers across networks to Astar zkEVM.', }, warning32blocks: 'It could take around 10~20mins or more to finalize', + warningLzWithdrawal: + 'It could take approximately 6 hours to finalize the bridge transaction from Astar zkEVM to Astar EVM', warning2steps: 'Bridging to L1 (Ethereum) involves 2 steps, and it requires users to make a claim on the L1 network (available in Recent History)', + slippage: 'Slippage: {percent}%', + feeOnTransaction: 'Transaction fee: {amount} {symbol}', gelatoApiError: 'Bridge UI is not available, please try again later', warningHighTraffic: 'High bridge traffic may delay withdrawal transactions up to 5 hours. We appreciate your patience.', diff --git a/src/modules/account/index.ts b/src/modules/account/index.ts index 2b4279f2b..0f78f6ca1 100644 --- a/src/modules/account/index.ts +++ b/src/modules/account/index.ts @@ -1,7 +1,7 @@ import { Struct } from '@polkadot/types'; import { BN } from '@polkadot/util'; -export { addTxHistories } from 'src/modules/account/utils'; +export { addTxHistories, addLzHistories } from 'src/modules/account/utils'; // Memo: used for determining if the SS58 account is Lockdrop account export const ETHEREUM_EXTENSION = 'Ethereum Extension'; @@ -20,6 +20,7 @@ export enum HistoryTxType { Xcm = 'XCM', Xvm = 'XVM Transfer', ZK_ETHEREUM_BRIDGE = 'ZK Ethereum Bridge', + LZ_BRIDGE = 'LayerZero Bridge', } export interface TxHistory { diff --git a/src/modules/account/utils/index.ts b/src/modules/account/utils/index.ts index 289e99862..8c3953e76 100644 --- a/src/modules/account/utils/index.ts +++ b/src/modules/account/utils/index.ts @@ -36,3 +36,46 @@ export const addTxHistories = ({ txs, }); }; + +// Memo: store users lz bridge histories to browser's local-storage +export const addLzHistories = ({ + hash, + type, + address, + amount, + symbol, + fromChainId, + toChainId, +}: { + hash: string; + type: HistoryTxType; + address: string; + amount: string; + symbol: string; + fromChainId: number; + toChainId: number; +}): void => { + const networkIdx = localStorage.getItem(NETWORK_IDX); + const network = getNetworkName(Number(networkIdx)); + + const txs = getAccountHistories({ storageKey: TX_HISTORIES, address, network }) as TxHistory[]; + const data = { + hash, + type, + timestamp: getTimestamp(), + data: { + amount, + symbol, + fromChainId, + toChainId, + }, + }; + txs.unshift(data); + + updateAccountHistories({ + storageKey: TX_HISTORIES, + address, + network, + txs, + }); +}; diff --git a/src/modules/information/index.ts b/src/modules/information/index.ts index 7ffe4f2aa..57560ba43 100644 --- a/src/modules/information/index.ts +++ b/src/modules/information/index.ts @@ -28,7 +28,10 @@ export type RecentHistoryTxType = | 'BondAndStake' | 'NominationTransfer' | 'UnbondAndUnstake' - | 'Reward'; + | 'Reward' + | 'LayerZeroBridge'; + +export type LayerZeroStatus = 'SENT' | 'INFLIGHT' | 'DELIVERED' | 'FAILED'; export interface RecentHistory { timestamp: string; @@ -44,3 +47,12 @@ export interface RecentStakeHistory { amount: string; explorerUrl: string; } + +export interface RecentLzHistory { + timestamp: string; + amount: string; + symbol: string; + note: string; + explorerUrl: string; + status: string; +} diff --git a/src/modules/information/recent-history/transfer/index.ts b/src/modules/information/recent-history/transfer/index.ts index 8d4d9ce83..68102f499 100644 --- a/src/modules/information/recent-history/transfer/index.ts +++ b/src/modules/information/recent-history/transfer/index.ts @@ -1,20 +1,21 @@ -import { getXvmTransferContractAddress } from 'src/modules/xvm-transfer'; -import { HistoryTxType } from 'src/modules/account'; -import { castChainName } from 'src/modules/xcm/utils'; -import { getAccountHistories, LOCAL_STORAGE } from 'src/config/localStorage'; -import { RecentHistory } from 'src/modules/information'; -import { TxHistory } from 'src/modules/account'; -import { xcmChainObj } from 'src/modules/xcm'; -import { providerEndpoints } from 'src/config/chainEndpoints'; import { - fetchXvmAssetsTransferHistories, - fetchTransferDetails, TransferDetail, XvmAssetsTransferHistory, + fetchTransferDetails, + fetchXvmAssetsTransferHistories, getShortenAddress, } from '@astar-network/astar-sdk-core'; -import { getTokenDetails } from 'src/config/web3'; import { ethers } from 'ethers'; +import { endpointKey, providerEndpoints } from 'src/config/chainEndpoints'; +import { LOCAL_STORAGE, getAccountHistories } from 'src/config/localStorage'; +import { EVM, getTokenDetails } from 'src/config/web3'; +import { HistoryTxType, TxHistory } from 'src/modules/account'; +import { LayerZeroStatus, RecentHistory, RecentLzHistory } from 'src/modules/information'; +import { xcmChainObj } from 'src/modules/xcm'; +import { castChainName } from 'src/modules/xcm/utils'; +import { getXvmTransferContractAddress } from 'src/modules/xvm-transfer'; +import { createClient } from '@layerzerolabs/scan-client'; +import { urlLayerZeroScan } from 'src/modules/zk-evm-bridge'; const { NETWORK_IDX, XVM_TX_HISTORIES, XCM_TX_HISTORIES, TX_HISTORIES } = LOCAL_STORAGE; const NumberOfHistories = 5; @@ -31,6 +32,32 @@ export const castXcmHistory = (tx: TxHistory): RecentHistory => { return { timestamp, txType, amount, symbol, note, explorerUrl }; }; +export const castLzHistory = async (tx: TxHistory): Promise => { + const timestamp = String(tx.timestamp); + const amount = tx.data.amount as string; + const symbol = tx.data.symbol as string; + const fromChainId = tx.data.fromChainId as number; + const fromChain = fromChainId === EVM.ASTAR_MAINNET ? 'Astar EVM' : 'Astar zkEVM'; + const toChain = fromChainId === EVM.ASTAR_MAINNET ? 'Astar zkEVM' : 'Astar EVM'; + const fromChainIndexId = + fromChainId === EVM.ASTAR_MAINNET ? endpointKey.ASTAR : endpointKey.ASTAR_ZKEVM; + const note = `${fromChain} to ${toChain}`; + + let explorerUrl = providerEndpoints[fromChainIndexId].blockscout + `/tx/${tx.hash}`; + let status = 'SENT'; + + try { + const client = createClient('mainnet'); + const { messages } = await client.getMessagesBySrcTxHash(tx.hash); + if (messages.length > 0) { + status = messages[0].status as LayerZeroStatus; + explorerUrl = urlLayerZeroScan + `/tx/${tx.hash}`; + } + } catch (error) {} + + return { timestamp, amount, symbol, note, explorerUrl, status }; +}; + export const castTransferHistory = ({ tx, hash, @@ -118,3 +145,33 @@ export const getTxHistories = async ({ ); return parsedTxs.filter((it) => it !== undefined) as RecentHistory[]; }; + +export const getLzTxHistories = async ({ + address, + network, +}: { + address: string; + network: string; +}): Promise => { + const txs: TxHistory[] = []; + + const transactions = getAccountHistories({ + storageKey: TX_HISTORIES, + address, + network, + }); + transactions.forEach((it) => txs.push(it)); + + const formattedTxs = txs.sort((a, b) => b.timestamp - a.timestamp).slice(0, NumberOfHistories); + const parsedTxs = await Promise.all( + formattedTxs.map(async (it) => { + try { + return await castLzHistory(it); + } catch (error) { + console.error(error); + return undefined; + } + }) + ); + return parsedTxs.filter((it) => it !== undefined) as RecentLzHistory[]; +}; diff --git a/src/modules/zk-evm-bridge/index.ts b/src/modules/zk-evm-bridge/index.ts index 5d9506f22..60e4acdfe 100644 --- a/src/modules/zk-evm-bridge/index.ts +++ b/src/modules/zk-evm-bridge/index.ts @@ -1,7 +1,8 @@ export * from './l1-bridge'; +export * from './layerzero'; export * from './tokens'; -export const stargateUrl = 'https://stargate.finance/transfer'; +export const relayBridgeAppLink = 'https://relay.link/bridge/astar-zkevm/?fromChainId=1'; export const layerSwapLink = 'https://www.layerswap.io/app?to=astarzk_mainnet&from=ethereum_mainnet'; export const zKatanaBridgeUrl = 'https://bridge.gelato.network/bridge/zkatana'; diff --git a/src/modules/zk-evm-bridge/layerzero/index.ts b/src/modules/zk-evm-bridge/layerzero/index.ts new file mode 100644 index 000000000..c66e8411e --- /dev/null +++ b/src/modules/zk-evm-bridge/layerzero/index.ts @@ -0,0 +1,92 @@ +import { astarNativeTokenErcAddr } from 'src/modules/xcm'; + +export const urlLayerZeroScan = 'https://layerzeroscan.com'; + +export const LayerZeroSlippage = 0.5; + +export enum LayerZeroNetworkName { + 'AstarZk' = 'Astar zkEVM', + 'AstarEvm' = 'Astar EVM', +} + +export enum LayerZeroId { + 'AstarZk' = 257, + 'AstarEvm' = 210, +} + +export enum LayerZeroChainId { + 'AstarZk' = 3776, + 'Astar' = 592, +} + +export const lzBridgeIcon = { + [LayerZeroNetworkName.AstarEvm]: require('src/assets/img/chain/astar.png'), + [LayerZeroNetworkName.AstarZk]: require('src/assets/img/chain/zkatana-logo.png'), +} as any; + +export const lzBridgeChainId = { + [LayerZeroNetworkName.AstarEvm]: LayerZeroChainId.Astar, + [LayerZeroNetworkName.AstarZk]: LayerZeroChainId.AstarZk, +}; + +export const layerZeroId = { + [LayerZeroNetworkName.AstarEvm]: LayerZeroId.AstarEvm, + [LayerZeroNetworkName.AstarZk]: LayerZeroId.AstarZk, +}; + +export interface LayerZeroToken { + symbol: string; + name: string; + oftBridgeContract: { + [LayerZeroId.AstarEvm]: string; + [LayerZeroId.AstarZk]: string; + }; + tokenAddress: { + [LayerZeroId.AstarEvm]: string; + [LayerZeroId.AstarZk]: string; + }; + decimals: { + [LayerZeroId.AstarEvm]: number; + [LayerZeroId.AstarZk]: number; + }; + image: string; + fromChainBalance?: number; + toChainBalance?: number; +} + +export const LayerZeroTokens: LayerZeroToken[] = [ + { + symbol: 'ASTR', + name: 'Astar Token', + oftBridgeContract: { + [LayerZeroId.AstarEvm]: '0xdf41220C7e322bFEF933D85D01821ad277f90172', + [LayerZeroId.AstarZk]: '0xdf41220C7e322bFEF933D85D01821ad277f90172', + }, + tokenAddress: { + [LayerZeroId.AstarEvm]: astarNativeTokenErcAddr, + [LayerZeroId.AstarZk]: '0xdf41220C7e322bFEF933D85D01821ad277f90172', + }, + decimals: { + [LayerZeroId.AstarEvm]: 18, + [LayerZeroId.AstarZk]: 18, + }, + image: require('/src/assets/img/token/astr.png'), + }, + { + symbol: 'DOT', + name: 'DOT Token', + oftBridgeContract: { + [LayerZeroId.AstarEvm]: '0x105C0F4a5Eae3bcb4c9Edbb3FD5f6b60FAcc3b36', + [LayerZeroId.AstarZk]: '0x7Cb5d4D178d93D59ea0592abF139459957898a59', + }, + tokenAddress: { + [LayerZeroId.AstarEvm]: '0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF', + [LayerZeroId.AstarZk]: '0x7Cb5d4D178d93D59ea0592abF139459957898a59', + }, + decimals: { + [LayerZeroId.AstarEvm]: 10, + [LayerZeroId.AstarZk]: 18, + }, + image: require('/src/assets/img/token/dot.png'), + }, +]; diff --git a/src/router/routes.ts b/src/router/routes.ts index b1ed6753d..72b979a10 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -17,12 +17,14 @@ import DiscoverV3 from 'src/staking-v3/components/DiscoverV3.vue'; import Owner from 'src/staking-v3/components/Owner.vue'; import MaintenanceMode from 'src/staking-v3/components/MaintenanceMode.vue'; import { RouteRecordRaw } from 'vue-router'; +import LayerZero from 'src/components/bridge/layerzero/LayerZero.vue'; export { buildTransferPageLink, getHeaderName, buildXvmTransferPageLink, buildEthereumBridgePageLink, + buildLzBridgePageLink, } from 'src/router/utils'; const networkIdxStore = localStorage.getItem(LOCAL_STORAGE.NETWORK_IDX); @@ -35,6 +37,7 @@ export enum Path { Assets = '/assets', Bridge = '/bridge', Ethereum = '/ethereum', + Layerzero = '/layerzero', Dashboard = '/dashboard', DappStaking = '/dapp-staking', Discover = '/discover', @@ -118,6 +121,10 @@ const routes: RouteRecordRaw[] = [ path: 'ethereum', component: L1, }, + { + path: 'Layerzero', + component: LayerZero, + }, ], }, diff --git a/src/router/utils/index.ts b/src/router/utils/index.ts index 25695a0be..d18e897e5 100644 --- a/src/router/utils/index.ts +++ b/src/router/utils/index.ts @@ -30,6 +30,10 @@ export const buildEthereumBridgePageLink = (): string => { return networkParam + Path.Bridge + Path.Ethereum; }; +export const buildLzBridgePageLink = (): string => { + return networkParam + Path.Bridge + Path.Layerzero; +}; + export const buildXvmTransferPageLink = (symbol: string): string => { const base = networkParam + Path.Assets + Path.XvmTransfer; return `${base}?token=${symbol.toLowerCase()}`; diff --git a/src/v2/app.container.ts b/src/v2/app.container.ts index 379acd36b..209635204 100644 --- a/src/v2/app.container.ts +++ b/src/v2/app.container.ts @@ -1,98 +1,102 @@ -import 'reflect-metadata'; import { interfaces } from 'inversify'; +import 'reflect-metadata'; +import { endpointKey } from 'src/config/chainEndpoints'; +import { XcmTokenInformation, xcmToken } from 'src/modules/xcm'; +import { + DappStakingRepository as DappStakingRepositoryV3, + DappStakingServiceEvm as DappStakingServiceEvmV3, + DappStakingService as DappStakingServiceV3, + IDappStakingRepository as IDappStakingRepositoryV3, + IDappStakingService as IDappStakingServiceV3, +} from 'src/staking-v3'; +import { + DappStakingServiceV2V3, + IDappStakingServiceV2V3, +} from 'src/staking-v3/logic/services/DappStakingServiceV2V3'; +import { XvmRepository } from 'src/v2/repositories/implementations/XvmRepository'; +import { XvmService } from 'src/v2/services/implementations/XvmService'; +import { + DappStakingServiceV2Ledger, + IDappStakingServiceV2Ledger, + IDataProviderRepository, + TokenApiProviderRepository, +} from '../staking-v3/logic'; +import { container } from './common'; +import { ITypeFactory, TypeFactory, TypeMapping } from './config/types'; +import { XcmRepositoryConfiguration } from './config/xcm/XcmRepositoryConfiguration'; import { IApi, IApiFactory } from './integration'; import { ApiFactory, DefaultApi } from './integration/implementation'; +import { EventAggregator, IEventAggregator } from './messaging'; import { + IAccountUnificationRepository, + IAssetsRepository, IDappStakingRepository, IEthCallRepository, + IEvmAssetsRepository, + IIdentityRepository, + IInflationRepository, IMetadataRepository, + INftRepository, + IPolkasafeRepository, IPriceRepository, ISystemRepository, IXcmRepository, - IEvmAssetsRepository, IXvmRepository, - IAssetsRepository, IZkBridgeRepository, - IPolkasafeRepository, - IIdentityRepository, - INftRepository, - IAccountUnificationRepository, - IInflationRepository, ISubscanRepository, } from './repositories'; +import { ILzBridgeRepository } from './repositories/ILzBridgeRepository'; import { + AccountUnificationRepository, + AssetsRepository, DappStakingRepository, EthCallRepository, + EvmAssetsRepository, + InflationRepository, MetadataRepository, + NftRepository, + PolkasafeRepository, SystemRepository, TokenApiRepository, XcmRepository, - EvmAssetsRepository, - AssetsRepository, ZkBridgeRepository, - PolkasafeRepository, - NftRepository, - AccountUnificationRepository, - InflationRepository, SubscanRepository, } from './repositories/implementations'; +import { IdentityRepository } from './repositories/implementations/IdentityRepository'; +import { LzBridgeRepository } from './repositories/implementations/LzBridgeRepository'; import { + IAccountUnificationService, + IAssetsService, IBalanceFormatterService, IDappStakingService, + IEvmAssetsService, IGasPriceProvider, + IIdentityService, IWalletService, IXcmEvmService, IXcmService, - IEvmAssetsService, - IAssetsService, + IXvmService, IZkBridgeService, + ILzBridgeService, WalletType, - IXvmService, - IAccountUnificationService, - IIdentityService, } from './services'; import { + AccountUnificationService, + AssetsService, + BalanceFormatterService, DappStakingService, - PolkadotWalletService, - MetamaskWalletService, - GasPriceProvider, - XcmService, EvmAssetsService, - BalanceFormatterService, - XcmEvmService, EvmDappStakingService, - AssetsService, - ZkBridgeService, - AccountUnificationService, + GasPriceProvider, IdentityService, + MetamaskWalletService, + PolkadotWalletService, + XcmEvmService, + XcmService, + ZkBridgeService, + LzBridgeService, } from './services/implementations'; -import { - IDappStakingRepository as IDappStakingRepositoryV3, - DappStakingRepository as DappStakingRepositoryV3, - IDappStakingService as IDappStakingServiceV3, - DappStakingService as DappStakingServiceV3, - DappStakingServiceEvm as DappStakingServiceEvmV3, -} from 'src/staking-v3'; import { Symbols } from './symbols'; -import { IEventAggregator, EventAggregator } from './messaging'; -import { container } from './common'; -import { ITypeFactory, TypeFactory, TypeMapping } from './config/types'; -import { XcmRepositoryConfiguration } from './config/xcm/XcmRepositoryConfiguration'; -import { endpointKey } from 'src/config/chainEndpoints'; -import { xcmToken, XcmTokenInformation } from 'src/modules/xcm'; -import { XvmRepository } from 'src/v2/repositories/implementations/XvmRepository'; -import { XvmService } from 'src/v2/services/implementations/XvmService'; -import { IdentityRepository } from './repositories/implementations/IdentityRepository'; -import { - DappStakingServiceV2V3, - IDappStakingServiceV2V3, -} from 'src/staking-v3/logic/services/DappStakingServiceV2V3'; -import { - DappStakingServiceV2Ledger, - IDappStakingServiceV2Ledger, - IDataProviderRepository, - TokenApiProviderRepository, -} from '../staking-v3/logic'; let currentWalletType = WalletType.Polkadot; let currentWalletName = ''; @@ -169,6 +173,7 @@ export default function buildDependencyContainer(network: endpointKey): void { container.addTransient(EvmAssetsRepository, Symbols.EvmAssetsRepository); container.addTransient(AssetsRepository, Symbols.AssetsRepository); container.addTransient(ZkBridgeRepository, Symbols.ZkBridgeRepository); + container.addTransient(LzBridgeRepository, Symbols.LzBridgeRepository); container.addSingleton(IdentityRepository, Symbols.IdentityRepository); container.addSingleton(NftRepository, Symbols.NftRepository); container.addSingleton( @@ -194,6 +199,7 @@ export default function buildDependencyContainer(network: endpointKey): void { ); container.addTransient(AssetsService, Symbols.AssetsService); container.addTransient(ZkBridgeService, Symbols.ZkBridgeService); + container.addTransient(LzBridgeService, Symbols.LzBridgeService); container.addSingleton( AccountUnificationService, Symbols.AccountUnificationService diff --git a/src/v2/repositories/ILzBridgeRepository.ts b/src/v2/repositories/ILzBridgeRepository.ts new file mode 100644 index 000000000..97a674f82 --- /dev/null +++ b/src/v2/repositories/ILzBridgeRepository.ts @@ -0,0 +1,15 @@ +import Web3 from 'web3'; +import { TransactionConfig } from 'web3-eth'; +import { ParamApprove, ParamBridgeLzAsset } from '../services/ILzBridgeService'; + +export interface ILzBridgeRepository { + getApproveData({ param, web3 }: { param: ParamApprove; web3: Web3 }): Promise; + + getBridgeLzAssetData({ + param, + web3, + }: { + param: ParamBridgeLzAsset; + web3: Web3; + }): Promise<{ txParam: TransactionConfig; nativeFee: number }>; +} diff --git a/src/v2/repositories/IZkBridgeRepository.ts b/src/v2/repositories/IZkBridgeRepository.ts index 56c111d96..24be1ae34 100644 --- a/src/v2/repositories/IZkBridgeRepository.ts +++ b/src/v2/repositories/IZkBridgeRepository.ts @@ -1,4 +1,3 @@ -import { BridgeHistory } from 'src/modules/zk-evm-bridge'; import { ParamBridgeAsset, ParamClaim } from 'src/v2/services'; import Web3 from 'web3'; import { TransactionConfig } from 'web3-eth'; diff --git a/src/v2/repositories/implementations/LzBridgeRepository.ts b/src/v2/repositories/implementations/LzBridgeRepository.ts new file mode 100644 index 000000000..45eb57145 --- /dev/null +++ b/src/v2/repositories/implementations/LzBridgeRepository.ts @@ -0,0 +1,98 @@ +import { ethers } from 'ethers'; +import { injectable } from 'inversify'; +import ERC20_ABI from 'src/config/abi/ERC20.json'; +import { addressToBytes32 } from 'src/config/web3'; +import ERC20_ASTAR_OFT_ABI from 'src/config/web3/abi/layerzero/oft-astar-bridge-abi.json'; +import ASTR_OFT_ABI from 'src/config/web3/abi/layerzero/oft-astar-native-abi.json'; +import ERC20_ZKEVM_OFT_ABI from 'src/config/web3/abi/layerzero/oft-zkevm-bridge-abi.json'; +import { LayerZeroId } from 'src/modules/zk-evm-bridge'; +import { ParamApprove, ParamBridgeLzAsset } from 'src/v2/services/ILzBridgeService'; +import Web3 from 'web3'; +import { TransactionConfig } from 'web3-eth'; +import { AbiItem } from 'web3-utils'; +import { ILzBridgeRepository } from '../ILzBridgeRepository'; + +@injectable() +export class LzBridgeRepository implements ILzBridgeRepository { + constructor() {} + + public async getApproveData({ + param, + web3, + }: { + param: ParamApprove; + web3: Web3; + }): Promise { + const { contractAddress, tokenAddress } = param; + const contract = new web3.eth.Contract(ERC20_ABI as AbiItem[], tokenAddress); + + const data = contract.methods.approve(contractAddress, param.amount).encodeABI(); + return { + from: param.senderAddress, + to: tokenAddress, + value: '0x0', + data, + }; + } + + public async getBridgeLzAssetData({ + param, + web3, + }: { + param: ParamBridgeLzAsset; + web3: Web3; + }): Promise<{ txParam: TransactionConfig; nativeFee: number }> { + const { token, fromNetworkId, destNetworkId, senderAddress, amount, minAmount, isNativeToken } = + param; + + const contractAddress = token.oftBridgeContract[fromNetworkId]; + + const abi = isNativeToken + ? ASTR_OFT_ABI + : fromNetworkId === LayerZeroId.AstarEvm + ? ERC20_ASTAR_OFT_ABI + : ERC20_ZKEVM_OFT_ABI; + const contract = new web3.eth.Contract(abi as AbiItem[], contractAddress); + + // Ref: https://docs.layerzero.network/v1/developers/evm-guides/contract-standards/oft-v1.2#how-to-deploy-proxyoft-and-oft-contracts + const minDstGas = await contract.methods.minDstGasLookup(destNetworkId, 1).call(); + const adapterParams = ethers.utils.solidityPack(['uint16', 'uint256'], [1, Number(minDstGas)]); + const fromAddressByte32 = addressToBytes32(senderAddress); + const zeroAddress = '0x0000000000000000000000000000000000000000'; + const callParams = [senderAddress, zeroAddress, adapterParams]; + const decimal = token.decimals[fromNetworkId]; + const qty = ethers.utils.parseUnits(String(amount), decimal); + const fee = await contract.methods + .estimateSendFee(destNetworkId, fromAddressByte32, qty, false, adapterParams) + .call(); + + const data = contract.methods + .sendFrom( + senderAddress, + destNetworkId, + fromAddressByte32, + ethers.utils.parseUnits(String(amount), decimal).toString(), + ethers.utils.parseUnits(String(minAmount), decimal).toString(), + callParams + ) + .encodeABI(); + + // Memo: increasing 20% of the fee to avoid transactions stacking. This is the same amount of increasing percentage as LayerZero does. + // Ref: https://github.com/LayerZero-Labs/mainnet-testnet-bridge/blob/9c80a2c5bfaa64bee5f98c7cd450010f8eecca19/tasks/swapAndBridge.js#L13 + const increasedFee = Number(ethers.utils.formatEther(fee[0])) * 1.2; + const nativeFee = Number(parseFloat(String(increasedFee)).toFixed(5)); + const value = ethers.utils + .parseEther(String(isNativeToken ? amount + nativeFee : nativeFee)) + .toString(); + + return { + txParam: { + from: senderAddress, + to: contractAddress, + value, + data, + }, + nativeFee, + }; + } +} diff --git a/src/v2/repositories/implementations/ZkBridgeRepository.ts b/src/v2/repositories/implementations/ZkBridgeRepository.ts index eb9c0a844..dfc605b5d 100644 --- a/src/v2/repositories/implementations/ZkBridgeRepository.ts +++ b/src/v2/repositories/implementations/ZkBridgeRepository.ts @@ -1,6 +1,6 @@ -import ERC20_ABI from 'src/config/abi/ERC20.json'; import { ethers } from 'ethers'; import { injectable } from 'inversify'; +import ERC20_ABI from 'src/config/abi/ERC20.json'; import { astarNativeTokenErcAddr } from 'src/modules/xcm/tokens/index'; import { EthBridgeContract, diff --git a/src/v2/services/ILzBridgeService.ts b/src/v2/services/ILzBridgeService.ts new file mode 100644 index 000000000..eec1776f0 --- /dev/null +++ b/src/v2/services/ILzBridgeService.ts @@ -0,0 +1,27 @@ +import { LayerZeroChainId, LayerZeroId, LayerZeroToken } from 'src/modules/zk-evm-bridge'; + +export interface ILzBridgeService { + approve(param: ParamApprove): Promise; + bridgeLzAsset(param: ParamBridgeLzAsset): Promise; + dryRunBridgeAsset(param: ParamBridgeLzAsset): Promise<{ isGasPayable: boolean; fee: number }>; +} + +export interface ParamBridgeLzAsset { + senderAddress: string; + amount: number; + minAmount: number; + destNetworkId: LayerZeroId; + fromNetworkId: LayerZeroId; + fromChainId: LayerZeroChainId; + tokenAddress: string; + isNativeToken: boolean; + token: LayerZeroToken; +} + +export interface ParamApprove { + contractAddress: string; + tokenAddress: string; + amount: string; + senderAddress: string; + fromChainId: LayerZeroChainId; +} diff --git a/src/v2/services/implementations/LzBridgeService.ts b/src/v2/services/implementations/LzBridgeService.ts new file mode 100644 index 000000000..d4eeaced4 --- /dev/null +++ b/src/v2/services/implementations/LzBridgeService.ts @@ -0,0 +1,124 @@ +import { ethers } from 'ethers'; +import { inject, injectable } from 'inversify'; +import { getEvmProvider } from 'src/hooks/helper/wallet'; +import { getRawEvmTransaction } from 'src/modules/evm'; +import { astarNativeTokenErcAddr } from 'src/modules/xcm'; +import { LayerZeroChainId } from 'src/modules/zk-evm-bridge'; +import { ExtrinsicStatusMessage, IEventAggregator } from 'src/v2/messaging'; +import { ILzBridgeRepository } from 'src/v2/repositories/ILzBridgeRepository'; +import { IWalletService } from 'src/v2/services'; +import { ILzBridgeService } from 'src/v2/services/ILzBridgeService'; +import { Symbols } from 'src/v2/symbols'; +import Web3 from 'web3'; +import { ParamApprove, ParamBridgeLzAsset } from '../ILzBridgeService'; + +@injectable() +export class LzBridgeService implements ILzBridgeService { + private readonly wallet: IWalletService; + + constructor( + @inject(Symbols.LzBridgeRepository) + private LzBridgeRepository: ILzBridgeRepository, + @inject(Symbols.WalletFactory) walletFactory: () => IWalletService, + @inject(Symbols.EventAggregator) readonly eventAggregator: IEventAggregator, + @inject(Symbols.CurrentWallet) private currentWallet: string + ) { + this.wallet = walletFactory(); + } + + private async checkConnectedNetwork(chainId: LayerZeroChainId, web3: Web3): Promise { + const connectedNetwork = await web3.eth.net.getId(); + if (connectedNetwork !== chainId) { + const errMsg = "Connected Network doesn't match"; + this.eventAggregator.publish( + new ExtrinsicStatusMessage({ + success: false, + message: errMsg, + }) + ); + throw Error(errMsg); + } + return; + } + + public async approve(param: ParamApprove): Promise { + const provider = getEvmProvider(this.currentWallet as any); + const web3 = new Web3(provider as any); + + await this.checkConnectedNetwork(param.fromChainId, web3); + const rawTx = await this.LzBridgeRepository.getApproveData({ + param, + web3, + }); + + const transactionHash = await this.wallet.sendEvmTransaction({ + from: String(rawTx.from), + to: String(rawTx.to), + value: String(rawTx.value), + data: String(rawTx.data), + }); + return transactionHash; + } + + public async bridgeLzAsset(param: ParamBridgeLzAsset): Promise { + const provider = getEvmProvider(this.currentWallet as any); + const web3 = new Web3(provider as any); + await this.checkConnectedNetwork(param.fromChainId, web3); + + const { txParam } = await this.LzBridgeRepository.getBridgeLzAssetData({ + param, + web3, + }); + const transactionHash = await this.wallet.sendEvmTransaction({ + from: String(txParam.from), + to: String(txParam.to), + value: String(txParam.value), + data: String(txParam.data), + }); + return transactionHash; + } + + // Memo: to check if users have enough native token to pay the gas and fee + public async dryRunBridgeAsset( + param: ParamBridgeLzAsset + ): Promise<{ isGasPayable: boolean; fee: number }> { + const provider = getEvmProvider(this.currentWallet as any); + const web3 = new Web3(provider as any); + + const { txParam, nativeFee } = await this.LzBridgeRepository.getBridgeLzAssetData({ + param, + web3, + }); + + try { + const [accountBalanceWei, gasPriceWei] = await Promise.all([ + web3.eth.getBalance(param.senderAddress), + web3.eth.getGasPrice(), + ]); + + const tx = await getRawEvmTransaction( + web3, + param.senderAddress, + txParam.to as string, + txParam.data as string, + txParam.value as string + ); + + const gasPrice = Number(ethers.utils.formatEther(gasPriceWei.toString())); + const estimatedGas = await web3.eth.estimateGas({ ...tx }); + const gasFee = gasPrice * Number(estimatedGas); + const accountBalance = Number(ethers.utils.formatEther(accountBalanceWei.toString())); + const amountNativeToken = + param.tokenAddress === astarNativeTokenErcAddr + ? Number(param.amount) + nativeFee + : nativeFee; + + const result = accountBalance - amountNativeToken - gasFee > 0; + + return { isGasPayable: result, fee: nativeFee }; + } catch (error) { + console.error(error); + return { isGasPayable: false, fee: nativeFee }; + } + } +} diff --git a/src/v2/services/implementations/index.ts b/src/v2/services/implementations/index.ts index 91c31c024..bca90109c 100644 --- a/src/v2/services/implementations/index.ts +++ b/src/v2/services/implementations/index.ts @@ -12,3 +12,4 @@ export * from './AssetsService'; export * from './ZkBridgeService'; export * from './AccountUnificationService'; export * from './IdentityService'; +export * from './LzBridgeService'; diff --git a/src/v2/services/index.ts b/src/v2/services/index.ts index 28f6d8ee8..4ba802ecb 100644 --- a/src/v2/services/index.ts +++ b/src/v2/services/index.ts @@ -8,5 +8,6 @@ export * from './IBalanceFormatterService'; export * from './IEvmAssetsService'; export * from './IAssetsService'; export * from './IZkBridgeService'; +export * from './ILzBridgeService'; export * from './IAccountUnificationService'; export * from './IIdentityService'; diff --git a/src/v2/symbols.ts b/src/v2/symbols.ts index 458ed2f4d..02e5c6443 100644 --- a/src/v2/symbols.ts +++ b/src/v2/symbols.ts @@ -31,8 +31,10 @@ export const Symbols = { PolkadotWalletService: Symbol.for('PolkadotWalletService'), AssetsRepository: Symbol.for('AssetsRepository'), ZkBridgeRepository: Symbol.for('ZkBridgeRepository'), + LzBridgeRepository: Symbol.for('LzBridgeRepository'), AssetsService: Symbol.for('AssetsService'), ZkBridgeService: Symbol.for('ZkBridgeService'), + LzBridgeService: Symbol.for('LzBridgeService'), AccountUnificationService: Symbol.for('AccountUnificationService'), IdentityRepository: Symbol.for('IdentityRepository'), IdentityService: Symbol.for('IdentityService'), diff --git a/yarn.lock b/yarn.lock index 940c7b887..89871715f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2596,6 +2596,11 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@layerzerolabs/scan-client@^0.0.8": + version "0.0.8" + resolved "https://registry.yarnpkg.com/@layerzerolabs/scan-client/-/scan-client-0.0.8.tgz#38316cde50c06556bb81b74f18d10a36b637eefb" + integrity sha512-V9vvt9GW0+AHoWXfOSNmZ9WUa28fVBmC93J/f9RLeDMEy5VR8srW2Du5pf1mMAg6ncEL0kQ1xkVCu+X6ARFBtQ== + "@ledgerhq/devices@^8.0.1": version "8.0.1" resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-8.0.1.tgz#4c475f6ae249daf00ef08f5098924206233f3179"
+ {{ $t('bridge.astarBridge.text2') }} +
{{ time }}
[{{ tx.status }}]
{{ tx.note }}