Skip to content

Commit

Permalink
feat(subbridge): ethereum astar bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
kingsleydon committed Aug 4, 2023
1 parent 3258160 commit 142ff73
Show file tree
Hide file tree
Showing 20 changed files with 247 additions and 143 deletions.
6 changes: 2 additions & 4 deletions apps/subbridge/components/BridgeBody/Action/EvmAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const EvmAction: FC<{onConfirm: () => void}> = ({onConfirm}) => {
mx: 'auto',
}}
>
{needApproval && (
{needApproval && bridgeErrorMessage == null && (
<LoadingButton
loading={!approved && approveLoading}
size="large"
Expand All @@ -142,9 +142,7 @@ const EvmAction: FC<{onConfirm: () => void}> = ({onConfirm}) => {
disabled={(!approved && needApproval) || bridgeErrorMessage != null}
onClick={onConfirm}
>
{(approved || !needApproval) && bridgeErrorMessage != null
? bridgeErrorMessage
: 'Transfer'}
{bridgeErrorMessage != null ? bridgeErrorMessage : 'Transfer'}
</Button>
</Stack>
)
Expand Down
8 changes: 3 additions & 5 deletions apps/subbridge/components/BridgeBody/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const BridgeBody: FC<BoxProps> = (props) => {
)
const destinationAccount = useAtomValue(destinationAccountAtom)
const bridgeLimit = useBridgeLimit()
const bridgeInfo = useAtomValue(bridgeInfoAtom)
const bridge = useAtomValue(bridgeInfoAtom)

const handleSelectFromChain = (newFromChainId: ChainId): void => {
setFromChain(newFromChainId)
Expand Down Expand Up @@ -150,8 +150,7 @@ const BridgeBody: FC<BoxProps> = (props) => {
{toChain.kind !== 'evm' && (
<DestinationAccountWarning sx={{mb: 3}} />
)}
{(bridgeInfo.kind === 'evmSygma' ||
bridgeInfo.kind === 'phalaSygma') &&
{(bridge.kind === 'evmSygma' || bridge.kind === 'phalaSygma') &&
Boolean(amount) &&
bridgeLimit != null &&
new Decimal(amount).gt(bridgeLimit) && (
Expand All @@ -160,8 +159,7 @@ const BridgeBody: FC<BoxProps> = (props) => {
<ExtraInfo sx={{mb: 3}} />
</Collapse>

{(bridgeInfo.kind === 'evmSygma' ||
bridgeInfo.kind === 'phalaSygma') && (
{(bridge.kind === 'evmSygma' || bridge.kind === 'phalaSygma') && (
<PoweredBySygma sx={{mb: 3}} />
)}

Expand Down
3 changes: 3 additions & 0 deletions apps/subbridge/config/asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export interface Asset {
}
destChainTransactionFee: Partial<Record<ChainId, Decimal>>
existentialDeposit: Partial<Record<ChainId, Decimal>>
sygmaResourceId?: string
}

export const ASSETS: Readonly<Record<AssetId, Asset>> = {
Expand Down Expand Up @@ -129,6 +130,8 @@ export const ASSETS: Readonly<Record<AssetId, Asset>> = {
phala: '5EYCAe5jLbHcAAMKvLFSXgCTbPrLgBJusvPwfKcaKzuf5X5e',
khala: '5EYCAe5jLbHcAAMKvLFSXgCTbPrLgBJusvPwfKcaKzuf5X5e',
},
sygmaResourceId:
'0x0000000000000000000000000000000000000000000000000000000000000001',
},
movr: {
id: 'movr',
Expand Down
23 changes: 19 additions & 4 deletions apps/subbridge/config/bridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type AssetsConfig = Array<{
assetId: AssetId
estimatedTime: string
kind: BridgeKind
isThroughKhala?: boolean
proxy?: ChainId
disabled?: boolean
}>

Expand Down Expand Up @@ -68,7 +68,7 @@ const moonriverToBifrostAssets: AssetsConfig = [
assetId: 'zlk',
estimatedTime: '< 3 mins',
kind: 'evmChainBridge',
isThroughKhala: true,
proxy: 'khala',
},
]

Expand All @@ -77,7 +77,7 @@ const bifrostToMoonriverAssets: AssetsConfig = [
assetId: 'zlk',
estimatedTime: '~ 5 mins',
kind: 'polkadotXTokens',
isThroughKhala: true,
proxy: 'khala',
},
]

Expand All @@ -93,6 +93,10 @@ export const BRIDGES: Readonly<Bridge[]> = [
id: 'khala',
assets: [{assetId: 'pha', estimatedTime: '~ 5 mins', kind: 'evmSygma'}],
},
{
id: 'astar',
assets: [{assetId: 'pha', estimatedTime: '~ 5 mins', kind: 'evmSygma'}],
},
],
},
{
Expand Down Expand Up @@ -340,6 +344,17 @@ export const BRIDGES: Readonly<Bridge[]> = [
{assetId: 'pha', estimatedTime: '< 1 min', kind: 'polkadotXcm'},
],
},
{
id: 'ethereum',
assets: [
{
assetId: 'pha',
estimatedTime: '~ 5 mins',
kind: 'polkadotXcm',
proxy: 'phala',
},
],
},
],
},
{
Expand All @@ -363,5 +378,5 @@ export const BRIDGES: Readonly<Bridge[]> = [
]

export const ALL_FROM_CHAINS = BRIDGES.filter((bridge) =>
bridge.toChains.some((x) => x.assets.length > 0)
bridge.toChains.some((x) => x.assets.length > 0),
).map((bridge) => bridge.fromChain)
26 changes: 23 additions & 3 deletions apps/subbridge/hooks/useBridgeFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Decimal from 'decimal.js'
import {useAtomValue} from 'jotai'
import useSWR from 'swr'
import {useEthersWeb3Provider} from './useEthersProvider'
import {useCurrentPolkadotApi} from './usePolkadotApi'
import {useCurrentPolkadotApi, usePolkadotApi} from './usePolkadotApi'

const ALICE = '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'
const zlkChainBridgeFee = new Decimal('0.25')
Expand All @@ -21,13 +21,17 @@ export const useBridgeFee = (): Decimal | undefined => {
const asset = useAtomValue(assetAtom)
const bridge = useAtomValue(bridgeInfoAtom)
const api = useCurrentPolkadotApi()
const phalaApi = usePolkadotApi('phala')
const provider = useEthersWeb3Provider()
const evmAccount = useAtomValue(evmAccountAtom)
const isTransferringZlkThroughChainBridge =
const isTransferringZlkProxiedByChainBridge =
fromChain.kind === 'polkadot' &&
toChain.kind === 'evm' &&
asset.id === 'zlk'

const isProxiedByPhalaSygma =
bridge.proxy === 'phala' && toChain.id === 'ethereum'

const {data: evmSygmaFee} = useSWR(
bridge.kind === 'evmSygma' &&
provider != null &&
Expand Down Expand Up @@ -67,6 +71,22 @@ export const useBridgeFee = (): Decimal | undefined => {
},
)

const {data: phalaProxySygmaFee} = useSWR(
isProxiedByPhalaSygma &&
phalaApi != null && [phalaApi, 'phalaProxySygmaFee'],
async ([api]) => {
const fee = await api.query.sygmaBasicFeeHandler.assetFees([
1,
{concrete: {parents: 0, interior: 'Here'}},
])
return new Decimal(fee.toString()).div(Decimal.pow(10, 12))
},
)

if (isProxiedByPhalaSygma) {
return phalaProxySygmaFee
}

if (bridge.kind === 'phalaSygma') {
return phalaSygmaFee
}
Expand All @@ -75,7 +95,7 @@ export const useBridgeFee = (): Decimal | undefined => {
return evmSygmaFee
}

if (isTransferringZlkThroughChainBridge) {
if (isTransferringZlkProxiedByChainBridge) {
return zlkChainBridgeFee
}

Expand Down
12 changes: 8 additions & 4 deletions apps/subbridge/hooks/useBridgeLimit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ export const useBridgeLimit = (): Decimal | undefined => {
((fromChain.id === 'moonriver' || toChain.id === 'moonriver') &&
asset.id === 'zlk') ||
bridge.kind === 'evmSygma' ||
bridge.kind === 'phalaSygma'
bridge.kind === 'phalaSygma' ||
(toChain.id === 'ethereum' &&
(bridge.proxy === 'phala' || bridge.proxy === 'khala'))

const {data: moonriverReservedZlk} = useSWR(
toChain.id === 'moonriver' &&
Expand Down Expand Up @@ -75,9 +77,11 @@ export const useBridgeLimit = (): Decimal | undefined => {

const {data: ethereumReservedPha} = useSWR(
ethereumPhaContract != null &&
(bridge.kind === 'phalaSygma' ||
bridge.proxy === 'phala' ||
bridge.proxy === 'khala') &&
toChain.id === 'ethereum' &&
asset.id === 'pha' &&
bridge.kind === 'phalaSygma' && [
asset.id === 'pha' && [
ethereumPhaContract,
asset.reservedAddress?.ethereum,
asset.decimals.ethereum ?? asset.decimals.default,
Expand All @@ -88,7 +92,7 @@ export const useBridgeLimit = (): Decimal | undefined => {

const {data: phalaReservedPha} = useSWR(
phalaApi != null &&
toChain.id === 'phala' &&
(toChain.id === 'phala' || bridge.proxy === 'phala') &&
asset.id === 'pha' &&
fromChain.id === 'ethereum' && [phalaApi, asset.reservedAddress?.phala],
polkadotAvailableBalanceFetcher,
Expand Down
26 changes: 16 additions & 10 deletions apps/subbridge/hooks/useEstimatedGasFee.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const useEstimatedGasFee = (): Decimal | undefined => {
toChain.id === 'phala' || toChain.id === 'thala' ? toChain.id : 'khala',
)
const polkadotApi = useCurrentPolkadotApi()
const {kind: bridgeKind, isThroughKhala} = useAtomValue(bridgeInfoAtom)
const bridge = useAtomValue(bridgeInfoAtom)
const resourceId =
typeof asset.chainBridgeResourceId === 'string'
? asset.chainBridgeResourceId
Expand All @@ -51,7 +51,7 @@ export const useEstimatedGasFee = (): Decimal | undefined => {
ethersGasPriceFetcher,
)
const {data: evmChainBridgeEstimatedGas} = useSWR(
bridgeKind === 'evmChainBridge' &&
bridge.kind === 'evmChainBridge' &&
ethersChainBridgeContract != null &&
khalaApi != null &&
resourceId != null && [
Expand All @@ -64,7 +64,7 @@ export const useEstimatedGasFee = (): Decimal | undefined => {
)

const {data: evmXTokensEstimatedGas} = useSWR(
bridgeKind === 'evmXTokens' &&
bridge.kind === 'evmXTokens' &&
ethersXTokensContract != null &&
toChain.paraId != null &&
asset.xc20Address?.[fromChain.id] != null && [
Expand All @@ -77,7 +77,7 @@ export const useEstimatedGasFee = (): Decimal | undefined => {
)

const {data: evmSygmaEstimatedGas} = useSWR(
bridgeKind === 'evmSygma' &&
bridge.kind === 'evmSygma' &&
ethersWeb3Provider != null &&
evmAccount != null && [
ethersWeb3Provider,
Expand Down Expand Up @@ -105,32 +105,38 @@ export const useEstimatedGasFee = (): Decimal | undefined => {
)

const {data: xTokensPartialFee} = useSWR(
bridgeKind === 'polkadotXTokens' &&
bridge.kind === 'polkadotXTokens' &&
polkadotApi != null && [
polkadotApi,
fromChain.id,
toChain.id,
asset.id,
isThroughKhala,
bridge.proxy,
],
xTokensPartialFeeFetcher,
)

const {data: phalaPartialFee} = useSWR(
(bridgeKind === 'phalaChainBridge' || bridgeKind === 'phalaSygma') &&
(bridge.kind === 'phalaChainBridge' || bridge.kind === 'phalaSygma') &&
polkadotApi != null && [
polkadotApi,
fromChain.id,
toChain.id,
asset.id,
bridgeKind,
bridge.kind,
],
phalaXTransferPartialFeeFetcher,
)

const {data: polkadotXcmPartialFee} = useSWR(
bridgeKind === 'polkadotXcm' &&
polkadotApi != null && [polkadotApi, fromChain.id, toChain.id, asset.id],
bridge.kind === 'polkadotXcm' &&
polkadotApi != null && [
polkadotApi,
fromChain.id,
toChain.id,
asset.id,
bridge.proxy,
],
polkadotXcmTransferPartialFeeFetcher,
)

Expand Down
19 changes: 10 additions & 9 deletions apps/subbridge/hooks/useTransfer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const useTransfer = (): (({
const decimals = useAtomValue(decimalsAtom)
const evmAccount = useAtomValue(evmAccountAtom)
const polkadotAccount = useAtomValue(polkadotAccountAtom)
const {kind: bridgeKind, isThroughKhala} = useAtomValue(bridgeInfoAtom)
const bridge = useAtomValue(bridgeInfoAtom)
const khalaApi = usePolkadotApi(
toChain.id === 'phala' || toChain.id === 'thala' ? toChain.id : 'khala',
)
Expand All @@ -61,7 +61,7 @@ export const useTransfer = (): (({
)

return async ({onReady}: {onReady: () => void}) => {
if (bridgeKind === 'evmChainBridge') {
if (bridge.kind === 'evmChainBridge') {
if (ethersChainBridgeContract == null || khalaApi == null) {
throw new Error('Transfer missing required parameters')
}
Expand All @@ -79,7 +79,7 @@ export const useTransfer = (): (({
})
}

if (bridgeKind === 'polkadotXTokens') {
if (bridge.kind === 'polkadotXTokens') {
if (polkadotApi == null || polkadotAccount?.wallet?.signer == null) {
throw new Error('Transfer missing required parameters')
}
Expand All @@ -90,7 +90,7 @@ export const useTransfer = (): (({
fromChainId: fromChain.id,
toChainId: toChain.id,
destinationAccount,
isThroughKhala,
proxy: bridge.proxy,
})
return await waitSignAndSend({
api: polkadotApi,
Expand All @@ -101,7 +101,7 @@ export const useTransfer = (): (({
})
}

if (bridgeKind === 'phalaChainBridge' || bridgeKind === 'phalaSygma') {
if (bridge.kind === 'phalaChainBridge' || bridge.kind === 'phalaSygma') {
if (polkadotApi == null || polkadotAccount?.wallet?.signer == null) {
throw new Error('Transfer missing required parameters')
}
Expand All @@ -113,7 +113,7 @@ export const useTransfer = (): (({
amount: rawAmount,
destinationAccount,
assetId: asset.id,
kind: bridgeKind,
kind: bridge.kind,
})

return await waitSignAndSend({
Expand All @@ -125,7 +125,7 @@ export const useTransfer = (): (({
})
}

if (bridgeKind === 'evmXTokens') {
if (bridge.kind === 'evmXTokens') {
if (ethersXTokensBridgeContract == null) {
throw new Error('Transfer missing required parameters')
}
Expand All @@ -144,7 +144,7 @@ export const useTransfer = (): (({
})
}

if (bridgeKind === 'polkadotXcm') {
if (bridge.kind === 'polkadotXcm') {
if (polkadotApi == null || polkadotAccount?.wallet?.signer == null) {
throw new Error('Transfer missing required parameters')
}
Expand All @@ -155,6 +155,7 @@ export const useTransfer = (): (({
fromChainId: fromChain.id,
toChainId: toChain.id,
destinationAccount,
proxy: bridge.proxy,
})
return await waitSignAndSend({
api: polkadotApi,
Expand All @@ -165,7 +166,7 @@ export const useTransfer = (): (({
})
}

if (bridgeKind === 'evmSygma') {
if (bridge.kind === 'evmSygma') {
if (ethersWeb3Provider == null || evmAccount == null) {
throw new Error('Transfer missing required parameters')
}
Expand Down
Loading

0 comments on commit 142ff73

Please sign in to comment.