Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CCIP integration #1431

Merged
merged 8 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.DS_Store
.thumbs.db
node_modules
.env

# Quasar core related directories
.quasar
Expand Down Expand Up @@ -52,3 +53,4 @@ astar-collator

# Chopstick binaries
db.sqlite*
.vercel
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
"@types/validator": "^13.7.11",
"@typescript-eslint/eslint-plugin": "^4.16.1",
"@typescript-eslint/parser": "^4.16.1",
"dotenv": "^16.4.7",
"eslint": "^7.14.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-jest": "^25.2.2",
Expand Down
11 changes: 10 additions & 1 deletion quasar.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const { configure } = require('quasar/wrappers');
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const path = require('path');
require('dotenv').config()


module.exports = configure(function (ctx) {
return {
Expand Down Expand Up @@ -53,7 +55,14 @@ module.exports = configure(function (ctx) {
// Full list of options: https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-build
build: {
vueRouterMode: 'history', // available values: 'hash', 'history'

env: {
SONEIUM_RPC_URL: process.env.SONEIUM_RPC_URL,
SONEIUM_EXPLORER_URL: process.env.SONEIUM_EXPLORER_URL,
SONEIUM_CHAIN_ID:process.env.SONEIUM_CHAIN_ID,
SONEIUM_CCIP_CHAIN_SELECTOR:process.env.SONEIUM_CCIP_CHAIN_SELECTOR,
SONEIUM_CCIP_ROUTER:process.env.SONEIUM_CCIP_ROUTER,
SONEIUM_ASTR_CONTRACT:process.env.SONEIUM_ASTR_CONTRACT,
},
// transpile: false,

// Add dependencies for transpiling with Babel (Array of string/regex)
Expand Down
49 changes: 40 additions & 9 deletions src/components/assets/EvmNativeToken.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@

<div class="box--ccip">
<custom-router-link
v-if="isShibuyaEvm"
v-if="isShibuyaEvm || isAstarEvm"
:to="buildCcipBridgePageLink()"
:is-disabled="!ccipMinatoBridgeEnabled"
:is-disabled="!isEnableCcipBridge"
>
<button class="btn btn--icon">
<img
Expand Down Expand Up @@ -163,7 +163,12 @@ import {
} from 'src/router/routes';
import { useStore } from 'src/store';
import { computed, defineComponent, ref, watch, watchEffect } from 'vue';
import { nativeBridgeEnabled, layerZeroBridgeEnabled, ccipMinatoBridgeEnabled } from 'src/features';
import {
nativeBridgeEnabled,
layerZeroBridgeEnabled,
ccipMinatoBridgeEnabled,
ccipSoneiumBridgeEnabled,
} from 'src/features';
import CustomRouterLink from '../common/CustomRouterLink.vue';
import Balloon from 'src/components/common/Balloon.vue';
import { LOCAL_STORAGE } from 'src/config/localStorage';
Expand All @@ -188,8 +193,15 @@ export default defineComponent({
const isCcipBalloon = ref<boolean>(false);
const isBalloonClosing = ref<boolean>(false);

const { currentNetworkName, nativeTokenSymbol, isZkEvm, isZkyoto, isAstar, isShibuyaEvm } =
useNetworkInfo();
const {
currentNetworkName,
nativeTokenSymbol,
isZkEvm,
isZkyoto,
isAstar,
isShibuyaEvm,
isAstarEvm,
} = useNetworkInfo();

const closeCcipBalloon = () => {
isCcipBalloon.value = false;
Expand Down Expand Up @@ -239,16 +251,34 @@ export default defineComponent({

const isTruncate = !nativeTokenSymbol.value.toUpperCase().includes('BTC');

const isEnableCcipBridge = computed<boolean>(() => {
return (
(isShibuyaEvm.value && ccipMinatoBridgeEnabled) ||
(isAstarEvm.value && ccipSoneiumBridgeEnabled)
);
});

// Memo: display the balloon animation
watch(
[isShibuyaEvm],
[isShibuyaEvm, isAstarEvm],
async () => {
const isBallonDisplayed = Boolean(localStorage.getItem(LOCAL_STORAGE.BALLOON_CCIP_SHIBUYA));
if (isShibuyaEvm.value && !isBallonDisplayed) {
const isBallonShibuyaDisplayed = Boolean(
localStorage.getItem(LOCAL_STORAGE.BALLOON_CCIP_SHIBUYA)
);
const isBallonAstarDisplayed = Boolean(
localStorage.getItem(LOCAL_STORAGE.BALLOON_CCIP_ASTAR)
);
if (isShibuyaEvm.value && !isBallonShibuyaDisplayed) {
await wait(1000);
isCcipBalloon.value = true;
localStorage.setItem(LOCAL_STORAGE.BALLOON_CCIP_SHIBUYA, 'true');
}

if (isAstarEvm.value && !isBallonAstarDisplayed) {
await wait(1000);
isCcipBalloon.value = true;
localStorage.setItem(LOCAL_STORAGE.BALLOON_CCIP_ASTAR, 'true');
}
},
{ immediate: true }
);
Expand All @@ -272,9 +302,10 @@ export default defineComponent({
nativeBridgeEnabled,
layerZeroBridgeEnabled,
isShibuyaEvm,
ccipMinatoBridgeEnabled,
isEnableCcipBridge,
isCcipBalloon,
isBalloonClosing,
isAstarEvm,
closeCcipBalloon,
buildCcipBridgePageLink,
truncate,
Expand Down
44 changes: 34 additions & 10 deletions src/components/bridge/BridgeSelection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
</div>
<div class="container--selection">
<div class="column--selection">
<button :disabled="!isEnableMinatoBridge">
<button :disabled="!isEnableCcipBridge">
<component
:is="isEnableMinatoBridge ? 'router-link' : 'div'"
:is="isEnableCcipBridge ? 'router-link' : 'div'"
:to="buildCcipBridgePageLink()"
class="button--bridge"
>
Expand All @@ -24,20 +24,38 @@
<div class="row--bridge-title">
<div class="text--bridge-tag">
<q-chip outline>
{{ $t('bridge.ccipMinatoBridge.tag') }}
{{
$t(
isShibuyaEvm
? 'bridge.ccipMinatoBridge.tag'
: 'bridge.ccipSoneiumBridge.tag'
)
}}
</q-chip>
</div>
<span class="text--bridge-title">{{ $t('bridge.ccipMinatoBridge.title') }}</span>
<span class="text--bridge-title">{{
$t(
isShibuyaEvm
? 'bridge.ccipMinatoBridge.title'
: 'bridge.ccipSoneiumBridge.title'
)
}}</span>
<div class="box--text-bridge">
<span class="text--bridge">
{{ $t('bridge.ccipMinatoBridge.text') }}
{{
$t(
isShibuyaEvm
? 'bridge.ccipMinatoBridge.text'
: 'bridge.ccipSoneiumBridge.text'
)
}}
</span>
</div>
</div>
</component>
</button>
<p v-if="!isShibuyaEvm" class="text--bridge-details">
{{ $t('bridge.ccipMinatoBridge.remark') }}
<p v-if="!isAstarEvm && !isShibuyaEvm" class="text--bridge-details">
{{ $t('bridge.ccipSoneiumBridge.remark') }}
</p>
</div>
<div class="column--selection">
Expand Down Expand Up @@ -241,6 +259,7 @@ import {
nativeBridgeEnabled,
layerZeroBridgeEnabled,
ccipMinatoBridgeEnabled,
ccipSoneiumBridgeEnabled,
} from 'src/features';
import { navigateInNewTab } from 'src/util-general';

Expand All @@ -257,6 +276,7 @@ export default defineComponent({
isAstar,
isH160,
isShibuyaEvm,
isAstarEvm,
} = useNetworkInfo();

const l1Name = computed<string>(() => {
Expand All @@ -277,8 +297,11 @@ export default defineComponent({
return isH160.value && (isAstar.value || isAstarZkEvm.value);
});

const isEnableMinatoBridge = computed<boolean>(() => {
return isShibuyaEvm.value && ccipMinatoBridgeEnabled;
const isEnableCcipBridge = computed<boolean>(() => {
return (
(isShibuyaEvm.value && ccipMinatoBridgeEnabled) ||
(isAstarEvm.value && ccipSoneiumBridgeEnabled)
);
});

return {
Expand All @@ -298,8 +321,9 @@ export default defineComponent({
layerSwapBridgeEnabled,
nativeBridgeEnabled,
layerZeroBridgeEnabled,
isEnableMinatoBridge,
isEnableCcipBridge,
isShibuyaEvm,
isAstarEvm,
buildEthereumBridgePageLink,
buildLzBridgePageLink,
navigateInNewTab,
Expand Down
7 changes: 7 additions & 0 deletions src/config/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Memo: This is temporary
export const SONEIUM_RPC_URL = String(process.env.SONEIUM_RPC_URL);
export const SONEIUM_EXPLORER_URL = String(process.env.SONEIUM_EXPLORER_URL);
export const SONEIUM_CHAIN_ID = Number(process.env.SONEIUM_CHAIN_ID);
export const SONEIUM_CCIP_CHAIN_SELECTOR = String(process.env.SONEIUM_CCIP_CHAIN_SELECTOR);
export const SONEIUM_CCIP_ROUTER = String(process.env.SONEIUM_CCIP_ROUTER);
export const SONEIUM_ASTR_CONTRACT = String(process.env.SONEIUM_ASTR_CONTRACT);
1 change: 1 addition & 0 deletions src/config/localStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export enum LOCAL_STORAGE {
XVM_TX_HISTORIES = 'xvmTxHistories',
BALLOON_NATIVE_TOKEN = 'balloonNativeToken',
BALLOON_CCIP_SHIBUYA = 'balloonCcipShibuya',
BALLOON_CCIP_ASTAR = 'balloonCcipAstar',
THEME_COLOR = 'themeColor',
MULTISIG = 'multisig',
CLOSE_DAPP_STAKING_V3_ONBOARDING = 'closeDappStakingV3Onboarding',
Expand Down
7 changes: 4 additions & 3 deletions src/config/web3/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { providerEndpoints, endpointKey } from 'src/config/chainEndpoints';
import { SONEIUM_CHAIN_ID, SONEIUM_EXPLORER_URL, SONEIUM_RPC_URL } from '../env';
export {
getChainData,
setupNetwork,
Expand Down Expand Up @@ -50,7 +51,7 @@ export enum EVM {
MOONBEAM = 1284,
SONEIUM_MINATO_TESTNET = 1946,
// Todo: update
SONEIUM = 9999,
SONEIUM = SONEIUM_CHAIN_ID,
}

export const chainName = {
Expand Down Expand Up @@ -167,7 +168,7 @@ export const rpcUrls = {
[EVM.MOONBEAM]: ['https://rpc.api.moonbeam.network'],
[EVM.SONEIUM_MINATO_TESTNET]: ['https://rpc.minato.soneium.org'],
// Todo: update
[EVM.SONEIUM]: ['https://rpc.minato.soneium.org'],
[EVM.SONEIUM]: [SONEIUM_RPC_URL],
};

export const blockExplorerUrls = {
Expand All @@ -185,7 +186,7 @@ export const blockExplorerUrls = {
[EVM.MOONBEAM]: ['https://moonbeam.moonscan.io'],
[EVM.SONEIUM_MINATO_TESTNET]: ['https://soneium-minato.blockscout.com'],
// Todo: update
[EVM.SONEIUM]: ['https://soneium-minato.blockscout.com'],
[EVM.SONEIUM]: [SONEIUM_EXPLORER_URL],
};

export const CHAIN_INFORMATION = {
Expand Down
1 change: 1 addition & 0 deletions src/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const layerSwapBridgeEnabled = true;
export const celerBridgeEnabled = true;
export const omniBridgeEnabled = true;
export const ccipMinatoBridgeEnabled = true;
export const ccipSoneiumBridgeEnabled = true;
const stargateBridgeEnabled = true;
const stakeStoneBridgeEnabled = true;
const arthSwapBridgeEnabled = true;
Expand Down
3 changes: 2 additions & 1 deletion src/hooks/bridge/useCcipBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
CCIP_TOKEN,
CCIP_SBY,
ccipBridgeAddress,
CCIP_ASTR,
} from 'src/modules/ccip-bridge';
import { showLoading } from 'src/modules/extrinsic/utils';
import { useStore } from 'src/store';
Expand All @@ -24,7 +25,7 @@ import { astarNativeTokenErcAddr } from 'src/modules/xcm';
export const useCcipBridge = () => {
const { isShibuya, nativeTokenSymbol } = useNetworkInfo();

const selectedToken = ref<CCIP_TOKEN>(CCIP_SBY);
const selectedToken = ref<CCIP_TOKEN>(isShibuya.value ? CCIP_SBY : CCIP_ASTR);
const bridgeAmt = ref<string | null>(null);
const toBridgeBalance = ref<number>(0);
const fromBridgeBalance = ref<number>(0);
Expand Down
4 changes: 4 additions & 0 deletions src/hooks/useNetworkInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ export function useNetworkInfo() {
const isShibuyaEvm = computed<boolean>(() => {
return isH160.value && isShibuya.value;
});
const isAstarEvm = computed<boolean>(() => {
return isH160.value && isAstar.value;
});

const currentNetworkChain = computed<ASTAR_CHAIN>(() => {
if (isZkEvm.value) {
Expand Down Expand Up @@ -135,5 +138,6 @@ export function useNetworkInfo() {
nativeTokenImg,
isShibuya,
isShibuyaEvm,
isAstarEvm,
};
}
6 changes: 6 additions & 0 deletions src/i18n/en-US/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,12 @@ export default {
text: 'Transfer SBY between Soneium Minato and Shibuya EVM. Powered by CCIP.',
remark: 'Available on Shibuya EVM. Switch the network to use it.',
},
ccipSoneiumBridge: {
title: 'Soneium Bridge',
tag: 'ASTR',
text: 'Transfer ASTR between Soneium and Astar EVM. Powered by CCIP.',
remark: 'Available on Astar EVM. Switch the network to use it.',
},
astarBridge: {
title: 'LayerZero',
tag: 'ASTR',
Expand Down
Loading
Loading