From 60bfb2c8cca963ebb104485f30fbc49cebc8894b Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Fri, 22 Mar 2024 01:34:18 +0700 Subject: [PATCH 01/23] deploy testnet --- .github/workflows/deploy-testnet.yml | 36 ++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 .github/workflows/deploy-testnet.yml diff --git a/.github/workflows/deploy-testnet.yml b/.github/workflows/deploy-testnet.yml new file mode 100644 index 00000000..b0cd5924 --- /dev/null +++ b/.github/workflows/deploy-testnet.yml @@ -0,0 +1,36 @@ +name: Deploy (dev) +on: + pull_request: + branches: [staging] + types: [closed] + push: + branches: [testnet] + repository_dispatch: + types: [deploy-testnet] + workflow_dispatch: + +jobs: + sync: + runs-on: ubuntu-latest + steps: + - id: checkout + name: Checkout + uses: actions/checkout@v3 + with: + ref: testnet + + - id: pull-staging + name: Pull latest 'staging' + run: git pull origin staging + + - id: diff-check + name: Check if 'testnet' is behind 'staging' + run: git diff --exit-code origin/staging + + - id: fast-forward + name: Fast forward 'staging' → 'testnet' + run: git merge --ff-only origin/staging + + - id: push-dev + name: Push latest 'dev' + run: git push --set-upstream origin testnet From e1cead43b7456937c16bca80dc2fe4a6f4ad439c Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Fri, 22 Mar 2024 02:02:28 +0700 Subject: [PATCH 02/23] seperated tests --- .github/workflows/tests.yml | 82 +++++++++++++++++++++- package.json | 5 +- tests/1nobleUSDCToInjectiveINJ.spec.ts | 27 +++++++ tests/2injectiveINJToCosmoshubATOM.spec.ts | 27 +++++++ tests/3cosmoshubAtomToNobleUSDC.spec.ts | 27 +++++++ 5 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 tests/1nobleUSDCToInjectiveINJ.spec.ts create mode 100644 tests/2injectiveINJToCosmoshubATOM.spec.ts create mode 100644 tests/3cosmoshubAtomToNobleUSDC.spec.ts diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8bc4ae9e..aa49ccd2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -26,7 +26,7 @@ jobs: NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }} run: npm test - "e2e-tests": + "e2e-test-noble-usdc-injective-inj": timeout-minutes: 20 runs-on: ubuntu-latest container: @@ -58,7 +58,85 @@ jobs: POLKACHU_PASSWORD: ${{ secrets.POLKACHU_PASSWORD }} NEXT_PUBLIC_EDGE_CONFIG: ${{ secrets.NEXT_PUBLIC_EDGE_CONFIG }} PLAYWRIGHT_TEST_BASE_URL: ${{ steps.waitFor200.outputs.url }} - run: xvfb-run --auto-servernum --server-args='-screen 0, 1920x1080x24' npm run test:e2e + run: xvfb-run --auto-servernum --server-args='-screen 0, 1920x1080x24' npm run test:e2e-1 + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 + "e2e-test-injective-inj-cosmoshub-atom": + timeout-minutes: 20 + runs-on: ubuntu-latest + container: + image: mcr.microsoft.com/playwright:v1.38.0-jammy + steps: + - name: Waiting for 200 from the Vercel Preview + uses: patrickedqvist/wait-for-vercel-preview@v1.3.1 + id: waitFor200 + with: + token: ${{ secrets.GITHUB_TOKEN }} + check_interval: 15 + max_timeout: 1200 + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - run: git config --system --add safe.directory /__w/ibc-dot-fun/ibc-dot-fun + - uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + env: + WORD_PHRASE_KEY: ${{ secrets.WORD_PHRASE_KEY }} + POLKACHU_USER: ${{ secrets.WORD_PHRASE_KEY }} + POLKACHU_PASSWORD: ${{ secrets.POLKACHU_PASSWORD }} + NEXT_PUBLIC_EDGE_CONFIG: ${{ secrets.NEXT_PUBLIC_EDGE_CONFIG }} + PLAYWRIGHT_TEST_BASE_URL: ${{ steps.waitFor200.outputs.url }} + run: xvfb-run --auto-servernum --server-args='-screen 0, 1920x1080x24' npm run test:e2e-2 + - uses: actions/upload-artifact@v3 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 + "e2e-test-cosmoshub-atom-noble-usdc": + timeout-minutes: 20 + runs-on: ubuntu-latest + container: + image: mcr.microsoft.com/playwright:v1.38.0-jammy + steps: + - name: Waiting for 200 from the Vercel Preview + uses: patrickedqvist/wait-for-vercel-preview@v1.3.1 + id: waitFor200 + with: + token: ${{ secrets.GITHUB_TOKEN }} + check_interval: 15 + max_timeout: 1200 + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: true + - run: git config --system --add safe.directory /__w/ibc-dot-fun/ibc-dot-fun + - uses: actions/setup-node@v3 + with: + node-version: 18 + - name: Install dependencies + run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps + - name: Run Playwright tests + env: + WORD_PHRASE_KEY: ${{ secrets.WORD_PHRASE_KEY }} + POLKACHU_USER: ${{ secrets.WORD_PHRASE_KEY }} + POLKACHU_PASSWORD: ${{ secrets.POLKACHU_PASSWORD }} + NEXT_PUBLIC_EDGE_CONFIG: ${{ secrets.NEXT_PUBLIC_EDGE_CONFIG }} + PLAYWRIGHT_TEST_BASE_URL: ${{ steps.waitFor200.outputs.url }} + run: xvfb-run --auto-servernum --server-args='-screen 0, 1920x1080x24' npm run test:e2e-3 - uses: actions/upload-artifact@v3 if: always() with: diff --git a/package.json b/package.json index 3869dbb6..23596ed8 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,10 @@ "postinstall": "patch-package && run-s chains:*", "start": "next start", "test": "node --experimental-vm-modules --no-warnings ./node_modules/.bin/jest", - "test:e2e": "playwright test --project=chromium", + "test:e2e": "playwright test transactions.spec.ts --project=chromium", + "test:e2e-1": "playwright test 1nobleUSDCToInjectiveINJ.spec.spec.ts --project=chromium", + "test:e2e-2": "playwright test 2injectiveINJToCosmoshubATOM.spec.spec.ts --project=chromium", + "test:e2e-3": "playwright test 3cosmoshubAtomToNobleUSDC.spec.spec.ts --project=chromium", "visdeps": "bash ./src/scripts/visdeps.sh" }, "overrides": { diff --git a/tests/1nobleUSDCToInjectiveINJ.spec.ts b/tests/1nobleUSDCToInjectiveINJ.spec.ts new file mode 100644 index 00000000..f9e2da5d --- /dev/null +++ b/tests/1nobleUSDCToInjectiveINJ.spec.ts @@ -0,0 +1,27 @@ +import { test } from "./lib/fixtures"; +import { + connectDestination, + connectSource, + e2eTest, + expectPageLoaded, + fillAmount, + initKeplr, + selectDestination, + selectSource, +} from "./utils"; + +test("Noble USDC -> Injective INJ", async ({ page }) => { + await initKeplr(); + await expectPageLoaded(page); + + await selectSource(page, "noble", "usdc"); + await selectDestination(page, "injective", "inj"); + + await connectSource(page); + + await fillAmount(page, "5"); + + await connectDestination(page); + + await e2eTest(page); +}); diff --git a/tests/2injectiveINJToCosmoshubATOM.spec.ts b/tests/2injectiveINJToCosmoshubATOM.spec.ts new file mode 100644 index 00000000..a424990f --- /dev/null +++ b/tests/2injectiveINJToCosmoshubATOM.spec.ts @@ -0,0 +1,27 @@ +import { test } from "./lib/fixtures"; +import { + connectDestination, + connectSource, + e2eTest, + expectPageLoaded, + fillAmount, + initKeplr, + selectDestination, + selectSource, +} from "./utils"; + +test("Injective INJ -> Cosmoshub ATOM", async ({ page }) => { + await initKeplr(); + await expectPageLoaded(page); + + await selectSource(page, "injective", "inj"); + await selectDestination(page, "cosmos hub", "atom"); + + await connectSource(page); + + await fillAmount(page, "0.13"); + + await connectDestination(page); + + await e2eTest(page); +}); diff --git a/tests/3cosmoshubAtomToNobleUSDC.spec.ts b/tests/3cosmoshubAtomToNobleUSDC.spec.ts new file mode 100644 index 00000000..a34c12d2 --- /dev/null +++ b/tests/3cosmoshubAtomToNobleUSDC.spec.ts @@ -0,0 +1,27 @@ +import { test } from "./lib/fixtures"; +import { + connectDestination, + connectSource, + e2eTest, + expectPageLoaded, + fillAmount, + initKeplr, + selectDestination, + selectSource, +} from "./utils"; + +test("Cosmoshub ATOM -> Noble USDC", async ({ page }) => { + await initKeplr(); + await expectPageLoaded(page); + + await selectSource(page, "cosmos hub", "atom"); + await selectDestination(page, "noble", "usdc"); + + await connectSource(page); + + await fillAmount(page, "0.45"); + + await connectDestination(page); + + await e2eTest(page); +}); From b342639eba2d5b5a6da0a03c50dfb3a8a9e4b589 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Fri, 22 Mar 2024 02:10:27 +0700 Subject: [PATCH 03/23] fix typo --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 23596ed8..08a3496d 100644 --- a/package.json +++ b/package.json @@ -13,9 +13,9 @@ "start": "next start", "test": "node --experimental-vm-modules --no-warnings ./node_modules/.bin/jest", "test:e2e": "playwright test transactions.spec.ts --project=chromium", - "test:e2e-1": "playwright test 1nobleUSDCToInjectiveINJ.spec.spec.ts --project=chromium", - "test:e2e-2": "playwright test 2injectiveINJToCosmoshubATOM.spec.spec.ts --project=chromium", - "test:e2e-3": "playwright test 3cosmoshubAtomToNobleUSDC.spec.spec.ts --project=chromium", + "test:e2e-1": "playwright test 1nobleUSDCToInjectiveINJ.spec.ts --project=chromium", + "test:e2e-2": "playwright test 2injectiveINJToCosmoshubATOM.spec.ts --project=chromium", + "test:e2e-3": "playwright test 3cosmoshubAtomToNobleUSDC.spec.ts --project=chromium", "visdeps": "bash ./src/scripts/visdeps.sh" }, "overrides": { From ba48afa85981b08a3fda94e2810250f341e5499a Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Fri, 22 Mar 2024 02:35:58 +0700 Subject: [PATCH 04/23] add fallback localhost --- tests/utils.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/utils.ts b/tests/utils.ts index f8b57498..cd63e9f3 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -54,8 +54,7 @@ export async function expectPageLoaded(page: Page) { height: 1080, width: 1920, }); - // @ts-expect-error - playwright types are not up to date - await page.goto(process.env.PLAYWRIGHT_TEST_BASE_URL); + await page.goto(process.env.PLAYWRIGHT_TEST_BASE_URL || "http://localhost:3000"); await test.expect(page.getByRole("button", { name: "Cosmos Hub" })).toBeVisible({ timeout: 5000, }); From f88fde76844dc6270be9bc39965991e564d07893 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Tue, 26 Mar 2024 00:51:02 +0700 Subject: [PATCH 05/23] remove evm to evm warning --- src/components/SwapWidget/SwapWidget.tsx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/components/SwapWidget/SwapWidget.tsx b/src/components/SwapWidget/SwapWidget.tsx index 1e0c9b69..14f69219 100644 --- a/src/components/SwapWidget/SwapWidget.tsx +++ b/src/components/SwapWidget/SwapWidget.tsx @@ -73,7 +73,6 @@ export function SwapWidget() { const destAccount = useAccount("destination"); const isWalletConnected = srcAccount?.isWalletConnected && destAccount?.isWalletConnected; - const isEvmtoEvm = srcAccount?.chainType === "evm" && destAccount?.chainType === "evm"; function promptDestAsset() { document.querySelector("[data-testid='destination'] button")?.click(); @@ -238,16 +237,6 @@ export function SwapWidget() {

)} - {isEvmtoEvm && ( -
-

- WARNING: - ibc.fun only supports swapping/transferring to, from, and within the Cosmos ecosystem at this time. If - you're not transferring to or from a Cosmos chain, we recommend{" "} - jumper.exchange -

-
- )} {!isWalletConnected && ( - {wallet.isWalletConnected && ( + > - )} - - ))} + {wallet.isWalletConnected && ( + + )} + {chainType === "svm" && wallet.isAvailable !== true && ( +
+ Not Installed +
+ )} + + ); + })} { @@ -167,7 +184,10 @@ function WalletModalWithContext() { }, }, }); + // cosmos const { getWalletRepo } = useManager(); + // solana + const { wallets: solanaWallets } = useWallet(); const { setIsOpen } = useWalletModal(); @@ -239,6 +259,33 @@ function WalletModalWithContext() { } } + if (chainType === "svm") { + for (const wallet of solanaWallets) { + const minimalWallet: MinimalWallet = { + walletName: wallet.adapter.name, + walletPrettyName: wallet.adapter.name, + walletInfo: { + logo: wallet.adapter.icon, + }, + connect: async () => { + try { + await wallet.adapter.connect(); + context && trackWallet.track(context, chainID, wallet.adapter.name, chainType); + } catch (error) { + console.error(error); + } + }, + disconnect: async () => { + await wallet.adapter.disconnect(); + context && trackWallet.untrack(context); + }, + isWalletConnected: wallet.adapter.connected, + isAvailable: wallet.readyState === "Installed", + }; + wallets.push(minimalWallet); + } + } + return ( { /** @type {string | undefined} */ let endpoint; + if (chainID === "solana-devnet") { + return { + endpoint: "https://devnet.helius-rpc.com", + isPrivate: false, + isApiKey: true, + }; + } + if (chainID === "solana-mainnet") { + return { + endpoint: "https://mainnet.helius-rpc.com", + isPrivate: false, + isApiKey: true, + }; + } + if (type === "api") { endpoint = exports.CUSTOM_API_CHAIN_IDS[chainID]; } else { diff --git a/src/hooks/useAccount.ts b/src/hooks/useAccount.ts index a29463da..8164ae21 100644 --- a/src/hooks/useAccount.ts +++ b/src/hooks/useAccount.ts @@ -1,5 +1,6 @@ import { WalletClient } from "@cosmos-kit/core"; import { useManager as useCosmosManager } from "@cosmos-kit/react"; +import { useWallet } from "@solana/wallet-adapter-react"; import { useQuery } from "@tanstack/react-query"; import { useMemo } from "react"; import { useAccount as useWagmiAccount } from "wagmi"; @@ -22,6 +23,8 @@ export function useAccount(context: TrackWalletCtx) { const wagmiAccount = useWagmiAccount(); + const { wallets } = useWallet(); + const getIsLedger = async (client: WalletClient, chainId: string) => { const isLedger = await isWalletClientUsingLedger(client, chainId); return isLedger; @@ -107,7 +110,43 @@ export function useAccount(context: TrackWalletCtx) { }, }; } - }, [chain, context, cosmosWallet, trackedWallet, wagmiAccount, cosmosWalletIsLedgerQuery.data]); - + if (chain.chainType === "svm") { + const solanaWallet = wallets.find((w) => w.adapter.name === trackedWallet?.walletName); + return { + address: solanaWallet?.adapter.publicKey?.toBase58(), + isWalletConnected: solanaWallet?.adapter.connected && !solanaWallet.adapter.connecting, + wallet: solanaWallet + ? { + walletName: solanaWallet.adapter.name, + walletPrettyName: solanaWallet.adapter.name, + walletInfo: { + logo: solanaWallet.adapter.icon, + }, + } + : undefined, + chainType: chain.chainType, + connect: () => { + return solanaWallet?.adapter.connect().then(() => { + trackWallet.track(context, chain.chainID, solanaWallet.adapter.name, chain.chainType); + }); + }, + disconnect: () => { + return solanaWallet?.adapter.disconnect().then(() => { + trackWallet.untrack(context); + }); + }, + }; + } + }, [ + trackedWallet, + chain, + cosmosWallet, + cosmosWalletIsLedgerQuery.data, + context, + wagmiAccount.address, + wagmiAccount.isConnected, + wagmiAccount.connector, + wallets, + ]); return account; } diff --git a/src/hooks/useBalancesByChain.ts b/src/hooks/useBalancesByChain.ts index 3861a677..490ecd5c 100644 --- a/src/hooks/useBalancesByChain.ts +++ b/src/hooks/useBalancesByChain.ts @@ -1,8 +1,11 @@ import { Asset, SkipRouter } from "@skip-router/core"; +import * as token from "@solana/spl-token"; +import { Connection, PublicKey } from "@solana/web3.js"; import { useQuery } from "@tanstack/react-query"; import { createPublicClient, erc20Abi, http, PublicClient } from "viem"; import { multicall3ABI } from "@/constants/abis"; +import { appUrl } from "@/constants/api"; import { EVM_CHAINS } from "@/constants/wagmi"; import { Chain } from "@/hooks/useChains"; import { useSkipClient } from "@/solve"; @@ -36,8 +39,12 @@ export function useBalancesByChain({ address, chain, assets, enabled = true }: A }); return getEvmChainBalances(skipClient, publicClient, address, chain.chainID); } - - return getBalancesByChain(address, chain.chainID, assets ?? []); + if (chain.chainType === "cosmos") { + return getBalancesByChain(address, chain.chainID, assets ?? []); + } + if (chain.chainType === "svm") { + return getSvmChainBalances(address, chain.chainID, assets ?? []); + } }, enabled: !!chain && !!address && enabled, }); @@ -121,3 +128,49 @@ export async function getEvmChainBalances( {}, ); } + +export const getSvmChainBalances = async (address: string, chainID: string, assets: Asset[]) => { + const rpc = `${appUrl}/api/rpc/${chainID}`; + const connection = new Connection(rpc); + // get SOL balance + const solBalance = await connection.getBalance(new PublicKey(address)); + // solana-devnet + const allBalances: Record = {}; + if (chainID === "solana-devnet") { + allBalances["solana-devnet-native"] = solBalance.toString(); + } + + const _splTokenBalances = await Promise.all( + assets + .filter((i) => i.denom !== "solana-devnet-native") + .map(async (asset) => { + try { + const tokenAddress = await token.getAssociatedTokenAddress( + new PublicKey(asset.denom), + new PublicKey(address), + ); + const tokenBalance = await token.getAccount(connection, tokenAddress); + return { + denom: asset.denom, + amount: tokenBalance.amount.toString(), + }; + } catch (e) { + return e; + } + }), + ); + console.log("sss", _splTokenBalances); + const splTokenBalances = _splTokenBalances.filter((result) => !(result instanceof Error)) as { + denom: string; + amount: string; + }[]; + + console.log("spl", splTokenBalances); + + splTokenBalances.forEach((balance) => { + if (balance instanceof Error) return; + allBalances[balance.denom] = balance.amount; + }); + + return allBalances; +}; diff --git a/src/hooks/useChains.ts b/src/hooks/useChains.ts index 8bb81f53..9e2ebd14 100644 --- a/src/hooks/useChains.ts +++ b/src/hooks/useChains.ts @@ -24,6 +24,8 @@ export function useChains(args: UseChainsQueryArgs = {}) { queryFn: async () => { const chains = await skipClient.chains({ includeEVM: true, + includeSVM: true, + includeTestnets: true, }); return chains diff --git a/src/lib/solana-wallet-adapter.ts b/src/lib/solana-wallet-adapter.ts new file mode 100644 index 00000000..9e4322e6 --- /dev/null +++ b/src/lib/solana-wallet-adapter.ts @@ -0,0 +1,15 @@ +import { + CoinbaseWalletAdapter, + LedgerWalletAdapter, + PhantomWalletAdapter, + SolflareWalletAdapter, + TrustWalletAdapter, +} from "@solana/wallet-adapter-wallets"; + +export const solanaWallets = [ + new PhantomWalletAdapter(), + new SolflareWalletAdapter(), + new CoinbaseWalletAdapter(), + new TrustWalletAdapter(), + new LedgerWalletAdapter(), +]; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index c9e49f9e..54954416 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -3,6 +3,7 @@ import "@/styles/globals.css"; import "@interchain-ui/react/styles"; import { ChainProvider } from "@cosmos-kit/react"; +import { WalletProvider } from "@solana/wallet-adapter-react"; import { PersistQueryClientProvider } from "@tanstack/react-query-persist-client"; import { Analytics } from "@vercel/analytics/react"; import { AppProps } from "next/app"; @@ -14,6 +15,7 @@ import { DefaultSeo } from "@/components/DefaultSeo"; import { metadata } from "@/constants/seo"; import { wallets } from "@/lib/cosmos-kit"; import { persister, queryClient } from "@/lib/react-query"; +import { solanaWallets } from "@/lib/solana-wallet-adapter"; import { config } from "@/lib/wagmi"; type ChainProviderProps = ComponentProps; @@ -26,34 +28,39 @@ export default function App({ Component, pageProps }: AppProps) { <> - - - - - - - + + + + + + + + ); } diff --git a/src/solve/queries.ts b/src/solve/queries.ts index 87088018..f9acedfd 100644 --- a/src/solve/queries.ts +++ b/src/solve/queries.ts @@ -27,6 +27,7 @@ export function useAssets(options: AssetsRequest = {}) { return skipClient.assets({ includeEvmAssets: true, includeCW20Assets: true, + includeSvmAssets: true, ...options, }); }, diff --git a/src/utils/api.ts b/src/utils/api.ts index 8bd28b62..96806619 100644 --- a/src/utils/api.ts +++ b/src/utils/api.ts @@ -20,6 +20,15 @@ export function createProxyHandler(type: "api" | "rpc", fallbackFn?: FallbackEnd return new Response(null, { status: 404 }); // Not Found } + if (data.isApiKey && data.endpoint) { + const url = new URL(data.endpoint); + url.searchParams.set("api-key", process.env.HELIUS_API_KEY!); + return fetch(url, { + body: req.body, + method: req.method, + }); + } + const headers = new Headers(); if (data.isPrivate) { headers.set("authorization", getPrivateAuthHeader()); From ca2e7a7c70680bdffabfa4312a90c3e598e2af1e Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Sun, 24 Mar 2024 12:30:44 +0700 Subject: [PATCH 11/23] add more testnet --- src/components/SwapWidget/useSwapWidget.ts | 3 ++- .../TransactionDialog/TransactionDialogContent.tsx | 1 - src/config/endpoints.js | 2 +- src/hooks/useBalancesByChain.ts | 7 ++++--- src/lib/wagmi.ts | 9 +++++++++ 5 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/components/SwapWidget/useSwapWidget.ts b/src/components/SwapWidget/useSwapWidget.ts index 0db21dab..1e2fcc33 100644 --- a/src/components/SwapWidget/useSwapWidget.ts +++ b/src/components/SwapWidget/useSwapWidget.ts @@ -121,7 +121,7 @@ export function useSwapWidget() { assets: srcAssets, enabled: !isAnyDisclosureOpen, }); - console.log("srcAssets", srcAssets); + console.log("balances", isAnyDisclosureOpen, balances); const customGasAmount = useSettingsStore((state) => state.customGasAmount); @@ -143,6 +143,7 @@ export function useSwapWidget() { if (!amountIn || !balances || !srcAsset) { return false; } + console.log("isAmountError", amountIn, srcAsset, balances); const parsedAmount = BigNumber(amountIn || "0"); const parsedBalance = BigNumber(balances[srcAsset.denom] ?? "0").shiftedBy(-(srcAsset.decimals ?? 6)); diff --git a/src/components/TransactionDialog/TransactionDialogContent.tsx b/src/components/TransactionDialog/TransactionDialogContent.tsx index 2bfe678f..2eb5ebe0 100644 --- a/src/components/TransactionDialog/TransactionDialogContent.tsx +++ b/src/components/TransactionDialog/TransactionDialogContent.tsx @@ -161,7 +161,6 @@ function TransactionDialogContent({ route, onClose, isAmountError, transactionCo } const estimatedFinalityTime = useFinalityTimeEstimate(route); - if (isTxComplete && txStatus.data?.isSuccess) { return ( { isApiKey: true, }; } - if (chainID === "solana-mainnet") { + if (chainID === "solana") { return { endpoint: "https://mainnet.helius-rpc.com", isPrivate: false, diff --git a/src/hooks/useBalancesByChain.ts b/src/hooks/useBalancesByChain.ts index 490ecd5c..1b71e1ce 100644 --- a/src/hooks/useBalancesByChain.ts +++ b/src/hooks/useBalancesByChain.ts @@ -139,6 +139,10 @@ export const getSvmChainBalances = async (address: string, chainID: string, asse if (chainID === "solana-devnet") { allBalances["solana-devnet-native"] = solBalance.toString(); } + // solana-mainnet + if (chainID === "solana") { + allBalances["solana-native"] = solBalance.toString(); + } const _splTokenBalances = await Promise.all( assets @@ -159,14 +163,11 @@ export const getSvmChainBalances = async (address: string, chainID: string, asse } }), ); - console.log("sss", _splTokenBalances); const splTokenBalances = _splTokenBalances.filter((result) => !(result instanceof Error)) as { denom: string; amount: string; }[]; - console.log("spl", splTokenBalances); - splTokenBalances.forEach((balance) => { if (balance instanceof Error) return; allBalances[balance.denom] = balance.amount; diff --git a/src/lib/wagmi.ts b/src/lib/wagmi.ts index c546043e..e7c91f49 100644 --- a/src/lib/wagmi.ts +++ b/src/lib/wagmi.ts @@ -3,7 +3,9 @@ import { createConfig } from "wagmi"; import { arbitrum, avalanche, + avalancheFuji, base, + baseSepolia, bsc, celo, fantom, @@ -16,6 +18,7 @@ import { optimism, polygon, polygonMumbai, + sepolia, } from "wagmi/chains"; export const config = createConfig({ @@ -35,6 +38,9 @@ export const config = createConfig({ optimism, polygon, polygonMumbai, + sepolia, + avalancheFuji, + baseSepolia, ], transports: { [arbitrum.id]: http(), @@ -52,5 +58,8 @@ export const config = createConfig({ [optimism.id]: http(), [polygon.id]: http(), [polygonMumbai.id]: http(), + [sepolia.id]: http(), + [avalancheFuji.id]: http(), + [baseSepolia.id]: http(), }, }); From 27683596556bb2fc1eb10d1d24ccd22c54c07460 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Fri, 22 Mar 2024 02:51:21 +0700 Subject: [PATCH 12/23] rapid relay --- package-lock.json | 53 +++++++++++++++++++++++ package.json | 2 + src/components/SimpleTooltip.tsx | 11 ++++- src/components/SwapWidget/SwapDetails.tsx | 52 +++++++++++++++++++--- src/solve/queries.ts | 5 ++- tailwind.config.js | 4 ++ 6 files changed, 118 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1c14879e..df617acd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35,10 +35,12 @@ "@injectivelabs/sdk-ts": "^1.14.5", "@injectivelabs/utils": "^1.14.5", "@keplr-wallet/types": "^0.12.66", + "@radix-ui/colors": "^3.0.0", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", "@skip-router/core": "2.0.0-rc.1", @@ -9741,6 +9743,11 @@ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, + "node_modules/@radix-ui/colors": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-3.0.0.tgz", + "integrity": "sha512-FUOsGBkHrYJwCSEtWRCIfQbZG7q1e6DgxCIOe1SUQzDe/7rXXeA47s8yCn6fuTNQAj1Zq4oTFi9Yjp3wzElcxg==" + }, "node_modules/@radix-ui/number": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", @@ -10192,6 +10199,35 @@ } } }, + "node_modules/@radix-ui/react-switch": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.0.3.tgz", + "integrity": "sha512-mxm87F88HyHztsI7N+ZUmEoARGkC22YVW5CaC+Byc+HRpuvCrOBPTAnXgf+tZ/7i0Sg/eOePGdMhUKhPaQEqow==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-use-size": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-tooltip": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.0.7.tgz", @@ -10296,6 +10332,23 @@ } } }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", + "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-use-rect": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz", diff --git a/package.json b/package.json index a6e38adc..d1cb2923 100644 --- a/package.json +++ b/package.json @@ -56,10 +56,12 @@ "@injectivelabs/sdk-ts": "^1.14.5", "@injectivelabs/utils": "^1.14.5", "@keplr-wallet/types": "^0.12.66", + "@radix-ui/colors": "^3.0.0", "@radix-ui/react-accordion": "^1.1.2", "@radix-ui/react-collapsible": "^1.0.3", "@radix-ui/react-dialog": "^1.0.5", "@radix-ui/react-scroll-area": "^1.0.5", + "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", "@skip-router/core": "2.0.0-rc.1", diff --git a/src/components/SimpleTooltip.tsx b/src/components/SimpleTooltip.tsx index 68530a26..d43a4197 100644 --- a/src/components/SimpleTooltip.tsx +++ b/src/components/SimpleTooltip.tsx @@ -4,7 +4,7 @@ import { ComponentPropsWithoutRef, ReactNode } from "react"; import { cn } from "@/utils/ui"; type Props = Tooltip.TooltipProps & { - type?: "default" | "warning"; + type?: "default" | "warning" | "brand"; enabled?: boolean; label: ReactNode; children: ReactNode; @@ -30,11 +30,18 @@ export const SimpleTooltip = (props: Props) => { "animate-slide-up-and-fade", type === "warning" && "bg-[#fbeef1] text-[#FF486E]", type === "warning" && "font-medium", + type === "brand" && "bg-[#FF486E] text-white", _content?.className, )} > {label} - + diff --git a/src/components/SwapWidget/SwapDetails.tsx b/src/components/SwapWidget/SwapDetails.tsx index f2e65f1c..ab1e88e4 100644 --- a/src/components/SwapWidget/SwapDetails.tsx +++ b/src/components/SwapWidget/SwapDetails.tsx @@ -69,6 +69,33 @@ export const SwapDetails = ({ } }, [axelarTransferOperation, hyperlaneTransferOperation]); + const isRapidRelay = route.estimatedFees?.some((fee) => fee.feeType === "RAPID_RELAY"); + + const rapidRelayFee = useMemo(() => { + if (!isRapidRelay) return; + const fee = route.estimatedFees.filter((fee) => fee.feeType === "RAPID_RELAY"); + const sameAsset = fee.every((fee, i, arr) => fee.originAsset.symbol === arr[0].originAsset.symbol); + if (!sameAsset) return; + const computedAmount = fee.reduce((acc, fee) => acc + Number(fee.amount), 0); + const computedUsd = fee.reduce((acc, fee) => acc + Number(fee.usdAmount), 0); + const inAsset = (computedAmount / Math.pow(10, fee[0].originAsset.decimals || 6)).toLocaleString("en-US", { + maximumFractionDigits: 6, + }); + + return { + amount: Number(inAsset), + inAsset: `${inAsset} ${fee[0].originAsset.symbol}`, + inUSD: `${formatUSD(computedUsd)}`, + }; + }, [isRapidRelay, route.estimatedFees]); + + const totalAmountOut = useMemo(() => { + if (isRapidRelay) { + return String(parseFloat(amountOut) + (rapidRelayFee?.amount || 0)); + } + return amountOut; + }, [amountOut, isRapidRelay, rapidRelayFee?.amount]); + if (!(sourceChain && sourceAsset && destinationChain && destinationAsset)) { return null; } @@ -89,7 +116,7 @@ export const SwapDetails = ({ srcAsset={sourceAsset} destAsset={destinationAsset} amountIn={amountIn} - amountOut={amountOut} + amountOut={totalAmountOut} > {({ left, right, conversion, toggle }) => (
@@ -195,11 +222,24 @@ export const SwapDetails = ({ {parseFloat(gasAmount).toLocaleString()} */} -
Bridging Fee
-
- {bridgingFee?.inAsset ?? "-"}{" "} - {bridgingFee?.inUSD ?? "-"} -
+ {bridgingFee && ( + <> +
Bridging Fee
+
+ {bridgingFee?.inAsset ?? "-"}{" "} + {bridgingFee?.inUSD ?? "-"} +
+ + )} + {rapidRelayFee && ( + <> +
Relayer Fee
+
+ {rapidRelayFee?.inAsset ?? "-"}{" "} + {rapidRelayFee?.inUSD ?? "-"} +
+ + )} diff --git a/src/solve/queries.ts b/src/solve/queries.ts index f9acedfd..6d378a3d 100644 --- a/src/solve/queries.ts +++ b/src/solve/queries.ts @@ -120,6 +120,7 @@ export function useRoute({ allowMultiTx: true, allowUnsafe: true, experimentalFeatures, + rapidRelay: true, } : { amountOut: amount, @@ -131,6 +132,7 @@ export function useRoute({ allowMultiTx: true, allowUnsafe: true, experimentalFeatures, + rapidRelay: true, }, ); @@ -140,7 +142,8 @@ export function useRoute({ return route; }, - refetchInterval: refetchCount < 10 ? 1000 * 5 : false, + refetchInterval: refetchCount < 10 ? 1000 * 10 : false, + retry: 1, enabled: enabled && !!sourceAsset && diff --git a/tailwind.config.js b/tailwind.config.js index 7f403f50..fa4579ab 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/no-var-requires */ +const { blackA } = require("@radix-ui/colors"); const defaultTheme = require("tailwindcss/defaultTheme"); const plugin = require("tailwindcss/plugin"); @@ -32,6 +33,9 @@ module.exports = { "slide-left-and-fade": `slide-left-and-fade 300ms cubic-bezier(0.16, 1, 0.3, 1)`, "spin-swap": `spin 0.5s cubic-bezier(0.18, 0.89, 0.32, 1.27)`, }, + colors: { + ...blackA, + }, fontFamily: { sans: ["Jost", ...defaultTheme.fontFamily.sans], }, From 035d406f2e5345e39ce9d9e28db90b54d0964c23 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Mon, 25 Mar 2024 03:30:59 +0700 Subject: [PATCH 13/23] cleanup --- src/components/RouteDisplay/TransferStep.tsx | 4 ++++ src/components/SwapWidget/useSwapWidget.ts | 5 +---- src/hooks/useBalancesByChain.ts | 2 -- src/hooks/useWalletAddresses.ts | 14 ++++++++++++++ src/solve/context.tsx | 18 +++++++++++++++++- 5 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/components/RouteDisplay/TransferStep.tsx b/src/components/RouteDisplay/TransferStep.tsx index 6d5c4db8..940c3764 100644 --- a/src/components/RouteDisplay/TransferStep.tsx +++ b/src/components/RouteDisplay/TransferStep.tsx @@ -172,6 +172,7 @@ export const TransferStep = ({ action, actions, statusData }: TransferStepProps) Transfer from to {bridge.name.toLowerCase() !== "ibc" && ( state.customGasAmount); @@ -143,7 +141,6 @@ export function useSwapWidget() { if (!amountIn || !balances || !srcAsset) { return false; } - console.log("isAmountError", amountIn, srcAsset, balances); const parsedAmount = BigNumber(amountIn || "0"); const parsedBalance = BigNumber(balances[srcAsset.denom] ?? "0").shiftedBy(-(srcAsset.decimals ?? 6)); diff --git a/src/hooks/useBalancesByChain.ts b/src/hooks/useBalancesByChain.ts index 1b71e1ce..3b82482f 100644 --- a/src/hooks/useBalancesByChain.ts +++ b/src/hooks/useBalancesByChain.ts @@ -22,7 +22,6 @@ export function useBalancesByChain({ address, chain, assets, enabled = true }: A // const publicClient = usePublicClient({ // chainId: chain?.chainType === "evm" ? parseInt(chain.chainID) : undefined, // }); - const skipClient = useSkipClient(); return useQuery({ @@ -31,7 +30,6 @@ export function useBalancesByChain({ address, chain, assets, enabled = true }: A if (!chain || !address) { return {}; } - if (chain.chainType === "evm") { const publicClient = createPublicClient({ chain: EVM_CHAINS.find((i) => i.id === Number(chain.chainID)), diff --git a/src/hooks/useWalletAddresses.ts b/src/hooks/useWalletAddresses.ts index f8586dd5..75c8d06d 100644 --- a/src/hooks/useWalletAddresses.ts +++ b/src/hooks/useWalletAddresses.ts @@ -1,4 +1,5 @@ import { useManager } from "@cosmos-kit/react"; +import { useWallet } from "@solana/wallet-adapter-react"; import { useQuery } from "@tanstack/react-query"; import { useMemo } from "react"; import { useAccount as useWagmiAccount } from "wagmi"; @@ -11,6 +12,7 @@ export function useWalletAddresses(chainIDs: string[]) { const { address: evmAddress } = useWagmiAccount(); const { getWalletRepo } = useManager(); + const { wallets } = useWallet(); const srcAccount = useAccount("source"); const dstAccount = useAccount("destination"); @@ -79,6 +81,18 @@ export function useWalletAddresses(chainIDs: string[]) { } record[currentChainID] = evmAddress; } + + if (chain.chainType === "svm") { + const solanaWallet = wallets.find( + (w) => + w.adapter.name === srcAccount?.wallet?.walletName || w.adapter.name === dstAccount?.wallet?.walletName, + ); + + if (!solanaWallet?.adapter.publicKey) { + throw new Error(`useWalletAddresses error: svm wallet not connected`); + } + record[currentChainID] = solanaWallet.adapter.publicKey.toBase58(); + } } return record; diff --git a/src/solve/context.tsx b/src/solve/context.tsx index 262d8e95..21a6f5f1 100644 --- a/src/solve/context.tsx +++ b/src/solve/context.tsx @@ -1,7 +1,8 @@ import { useManager } from "@cosmos-kit/react"; import { SkipRouter } from "@skip-router/core"; +import { useWallet } from "@solana/wallet-adapter-react"; import { getWalletClient } from "@wagmi/core"; -import { createContext, ReactNode } from "react"; +import { createContext, ReactNode, useMemo } from "react"; import { WalletClient } from "viem"; import { chainIdToName } from "@/chains/types"; @@ -14,6 +15,7 @@ export const SkipContext = createContext<{ skipClient: SkipRouter } | undefined> export function SkipProvider({ children }: { children: ReactNode }) { const { getWalletRepo } = useManager(); + const { wallets } = useWallet(); const skipClient = new SkipRouter({ clientID: process.env.NEXT_PUBLIC_CLIENT_ID, @@ -66,6 +68,20 @@ export function SkipProvider({ children }: { children: ReactNode }) { return evmWalletClient; }, + getSVMSigner: async () => { + const walletName = (() => { + const { source, destination } = trackWallet.get(); + if (source?.chainType === "svm") return source.walletName; + if (destination?.chainType === "svm") return destination.walletName; + })(); + const solanaWallet = wallets.find((w) => w.adapter.name === walletName); + + if (!solanaWallet?.adapter) { + throw new Error(`getSVMSigner error: no wallet client available`); + } + + return solanaWallet.adapter; + }, endpointOptions: { getRpcEndpointForChain: async (chainID) => { return `${appUrl}/api/rpc/${chainID}`; From b077eca5418796b86a615ca849709a09adcede9a Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Mon, 25 Mar 2024 23:43:48 +0700 Subject: [PATCH 14/23] router sdk rc version --- chain-registry | 2 +- package-lock.json | 10 ++++++---- package.json | 2 +- src/solve/context.tsx | 2 +- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/chain-registry b/chain-registry index 89a91fac..d4d44ed9 160000 --- a/chain-registry +++ b/chain-registry @@ -1 +1 @@ -Subproject commit 89a91facc3e71b819b45340b0667db65d5ded409 +Subproject commit d4d44ed97dd8ef3355b69a48e568736346a82f62 diff --git a/package-lock.json b/package-lock.json index df617acd..d499bb83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.1", + "@skip-router/core": "2.0.0-rc.5", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", @@ -13438,9 +13438,9 @@ } }, "node_modules/@skip-router/core": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0-rc.1.tgz", - "integrity": "sha512-6Rd6LhDTqhmujg7uwjErPoP/yroTdmgWJPsKtCkGGsw3N5x+v2POElesCmQzlIPnG2954bIVPg/NDxzzOvaxVw==", + "version": "2.0.0-rc.5", + "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0-rc.5.tgz", + "integrity": "sha512-hi9CRGQjf06Eck6rZDj5MepHqBTBsbBCBAIegVKntRXUxW9d1lK030ViPT28sldMDot+crhNGbNEZXUf0o5ErQ==", "dependencies": { "@cosmjs/amino": "0.31.x", "@cosmjs/cosmwasm-stargate": "0.31.x", @@ -13452,6 +13452,8 @@ "@injectivelabs/core-proto-ts": "0.0.x", "@injectivelabs/sdk-ts": "1.x", "@keplr-wallet/unit": "^0.12.67", + "@solana/wallet-adapter-base": "^0.9.23", + "@solana/web3.js": "^1.91.1", "axios": "1.x", "cosmjs-types": "0.8.x", "keccak256": "1.x", diff --git a/package.json b/package.json index d1cb2923..91a20e5f 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.1", + "@skip-router/core": "2.0.0-rc.5", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", diff --git a/src/solve/context.tsx b/src/solve/context.tsx index 21a6f5f1..3cebc87e 100644 --- a/src/solve/context.tsx +++ b/src/solve/context.tsx @@ -2,7 +2,7 @@ import { useManager } from "@cosmos-kit/react"; import { SkipRouter } from "@skip-router/core"; import { useWallet } from "@solana/wallet-adapter-react"; import { getWalletClient } from "@wagmi/core"; -import { createContext, ReactNode, useMemo } from "react"; +import { createContext, ReactNode } from "react"; import { WalletClient } from "viem"; import { chainIdToName } from "@/chains/types"; From e62ca16a678849a058468351be721a3c9e60304c Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Mon, 25 Mar 2024 23:59:56 +0700 Subject: [PATCH 15/23] bump sdk rc version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index d499bb83..94bbd6b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.5", + "@skip-router/core": "2.0.0-rc.6", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", @@ -13438,9 +13438,9 @@ } }, "node_modules/@skip-router/core": { - "version": "2.0.0-rc.5", - "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0-rc.5.tgz", - "integrity": "sha512-hi9CRGQjf06Eck6rZDj5MepHqBTBsbBCBAIegVKntRXUxW9d1lK030ViPT28sldMDot+crhNGbNEZXUf0o5ErQ==", + "version": "2.0.0-rc.6", + "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0-rc.6.tgz", + "integrity": "sha512-IrDPS5G0/7vay1iX0H9JUmbWuR3vfP/gxRv5mJcSWCYiBHoLyJNecfxgvgIFtXMO0DIKPy25Z6JM7lQdEBbJpw==", "dependencies": { "@cosmjs/amino": "0.31.x", "@cosmjs/cosmwasm-stargate": "0.31.x", diff --git a/package.json b/package.json index 91a20e5f..86ca5ba9 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.5", + "@skip-router/core": "2.0.0-rc.6", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", From 2f2549d929db0fb0db413213b96b6b38fe22ab0a Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Tue, 26 Mar 2024 01:17:36 +0700 Subject: [PATCH 16/23] add solana explorer link in api --- src/pages/api/explorer/[chainId].ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/pages/api/explorer/[chainId].ts b/src/pages/api/explorer/[chainId].ts index a59a5928..00d49b01 100644 --- a/src/pages/api/explorer/[chainId].ts +++ b/src/pages/api/explorer/[chainId].ts @@ -17,6 +17,15 @@ export default async function handler(req: NextRequest) { const parsedIntId = parseInt(chainId); const isEvmChain = typeof parsedIntId === "number" && !isNaN(parsedIntId); + const isSvmChain = chainId === "solana-devnet" || chainId === "solana"; + + if (isSvmChain) { + baseUrl = + chainId === "solana-devnet" + ? "https://solscan.io/tx/${txHash}?cluster=devnet" + : "https://solscan.io/tx/${txHash}"; + } + if (isEvmChain) { const { EVM_CHAINS } = await import("@/constants/wagmi"); const chain = EVM_CHAINS.find((chain) => chain.id === parseInt(chainId)); From c1d4de487f7f0f9c698d6ecd6c90c4ea8acb3486 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Tue, 26 Mar 2024 05:21:13 +0700 Subject: [PATCH 17/23] bump sdk rc version --- chain-registry | 2 +- package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/chain-registry b/chain-registry index d4d44ed9..1a0d0526 160000 --- a/chain-registry +++ b/chain-registry @@ -1 +1 @@ -Subproject commit d4d44ed97dd8ef3355b69a48e568736346a82f62 +Subproject commit 1a0d05265b714dbb56983df366775e3fcc2f6cec diff --git a/package-lock.json b/package-lock.json index 94bbd6b5..c80538e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.6", + "@skip-router/core": "2.0.0-rc.7", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", @@ -13438,9 +13438,9 @@ } }, "node_modules/@skip-router/core": { - "version": "2.0.0-rc.6", - "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0-rc.6.tgz", - "integrity": "sha512-IrDPS5G0/7vay1iX0H9JUmbWuR3vfP/gxRv5mJcSWCYiBHoLyJNecfxgvgIFtXMO0DIKPy25Z6JM7lQdEBbJpw==", + "version": "2.0.0-rc.7", + "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0-rc.7.tgz", + "integrity": "sha512-FmdgD6s7NofaEss6J2CtMzf/4G2iewUAug043oMuuaGJLYdlxWe5h+BaXe4c2u+6IpINGyyqlm0zWJMnXvdm4w==", "dependencies": { "@cosmjs/amino": "0.31.x", "@cosmjs/cosmwasm-stargate": "0.31.x", diff --git a/package.json b/package.json index 86ca5ba9..e7437794 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.6", + "@skip-router/core": "2.0.0-rc.7", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", From bcf6dbab04380f632efeab727e4fc89b44006cf5 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Tue, 26 Mar 2024 05:47:03 +0700 Subject: [PATCH 18/23] add evm testnets --- src/constants/wagmi.ts | 28 +++++++++++++++++++--------- src/lib/wagmi.ts | 6 ++++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/src/constants/wagmi.ts b/src/constants/wagmi.ts index f710bb8c..b52bb7e6 100644 --- a/src/constants/wagmi.ts +++ b/src/constants/wagmi.ts @@ -1,7 +1,10 @@ import { arbitrum, + arbitrumSepolia, avalanche, + avalancheFuji, base, + baseSepolia, bsc, celo, Chain, @@ -13,24 +16,31 @@ import { manta, moonbeam, optimism, + optimismSepolia, polygon, polygonMumbai, + sepolia, } from "wagmi/chains"; export const EVM_CHAINS: Chain[] = [ - mainnet, arbitrum, - base, - filecoin, - polygonMumbai, - polygon, - linea, - moonbeam, avalanche, - celo, + base, bsc, - optimism, + celo, fantom, + filecoin, kava, + linea, + mainnet, manta, + moonbeam, + optimism, + polygon, + polygonMumbai, + sepolia, + avalancheFuji, + baseSepolia, + optimismSepolia, + arbitrumSepolia, ]; diff --git a/src/lib/wagmi.ts b/src/lib/wagmi.ts index e7c91f49..43fa9c60 100644 --- a/src/lib/wagmi.ts +++ b/src/lib/wagmi.ts @@ -2,6 +2,7 @@ import { http } from "viem"; import { createConfig } from "wagmi"; import { arbitrum, + arbitrumSepolia, avalanche, avalancheFuji, base, @@ -16,6 +17,7 @@ import { manta, moonbeam, optimism, + optimismSepolia, polygon, polygonMumbai, sepolia, @@ -41,6 +43,8 @@ export const config = createConfig({ sepolia, avalancheFuji, baseSepolia, + optimismSepolia, + arbitrumSepolia, ], transports: { [arbitrum.id]: http(), @@ -61,5 +65,7 @@ export const config = createConfig({ [sepolia.id]: http(), [avalancheFuji.id]: http(), [baseSepolia.id]: http(), + [optimismSepolia.id]: http(), + [arbitrumSepolia.id]: http(), }, }); From b39922b236e5671c69b4848a16cf7d05a1416f65 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Tue, 26 Mar 2024 10:29:13 +0700 Subject: [PATCH 19/23] bump rc sdk version --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index c80538e6..8cce75a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.7", + "@skip-router/core": "2.0.0-rc.8", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", @@ -13438,9 +13438,9 @@ } }, "node_modules/@skip-router/core": { - "version": "2.0.0-rc.7", - "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0-rc.7.tgz", - "integrity": "sha512-FmdgD6s7NofaEss6J2CtMzf/4G2iewUAug043oMuuaGJLYdlxWe5h+BaXe4c2u+6IpINGyyqlm0zWJMnXvdm4w==", + "version": "2.0.0-rc.8", + "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0-rc.8.tgz", + "integrity": "sha512-PwlnJT8fbflnJ8FITSkmuiS/zjACd5Qx5YBgX+dDjQSgE4pA8Ngn4TqVljqmb9K7jqihTxPPts2T0GHlyvTMWg==", "dependencies": { "@cosmjs/amino": "0.31.x", "@cosmjs/cosmwasm-stargate": "0.31.x", diff --git a/package.json b/package.json index e7437794..b2aca611 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.7", + "@skip-router/core": "2.0.0-rc.8", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", From be588fe051e0654f67ab7e7e837d4990c411b4b4 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Tue, 26 Mar 2024 12:11:00 +0700 Subject: [PATCH 20/23] remove testnet --- src/hooks/useChains.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hooks/useChains.ts b/src/hooks/useChains.ts index 9e2ebd14..c5d8a467 100644 --- a/src/hooks/useChains.ts +++ b/src/hooks/useChains.ts @@ -25,7 +25,6 @@ export function useChains(args: UseChainsQueryArgs = {}) { const chains = await skipClient.chains({ includeEVM: true, includeSVM: true, - includeTestnets: true, }); return chains From 0a2ddfce32698fba3833dbb8d742012b679e15de Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Tue, 26 Mar 2024 12:11:18 +0700 Subject: [PATCH 21/23] bump sdk version 2.0.0 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8cce75a0..6802680f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,7 +43,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.8", + "@skip-router/core": "2.0.0", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", @@ -13438,9 +13438,9 @@ } }, "node_modules/@skip-router/core": { - "version": "2.0.0-rc.8", - "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0-rc.8.tgz", - "integrity": "sha512-PwlnJT8fbflnJ8FITSkmuiS/zjACd5Qx5YBgX+dDjQSgE4pA8Ngn4TqVljqmb9K7jqihTxPPts2T0GHlyvTMWg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@skip-router/core/-/core-2.0.0.tgz", + "integrity": "sha512-kqRvzs+RzxKsiLOKEZH5TkkQxZC74G/WbuQPs2QbD7SIZnyB0RnKVM0BBI1EIYSudCCXHvnhofaqbYnwOE0SKg==", "dependencies": { "@cosmjs/amino": "0.31.x", "@cosmjs/cosmwasm-stargate": "0.31.x", diff --git a/package.json b/package.json index b2aca611..331029b0 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.7", "@sentry/nextjs": "^7.99.0", - "@skip-router/core": "2.0.0-rc.8", + "@skip-router/core": "2.0.0", "@solana/spl-token": "^0.4.1", "@solana/wallet-adapter-react": "^0.15.35", "@solana/wallet-adapter-wallets": "^0.19.31", From ab9922d600045d8703302716deb86a7c491a4ebe Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Tue, 26 Mar 2024 12:33:12 +0700 Subject: [PATCH 22/23] fix(test): update jest config --- jest.config.js | 1 + src/test/index.tsx | 37 ++++++++++++++++++++++--------------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/jest.config.js b/jest.config.js index d86a1ccb..22cdc56d 100644 --- a/jest.config.js +++ b/jest.config.js @@ -13,6 +13,7 @@ const customJestConfig = { moduleNameMapper: { isows: "/node_modules/isows/_cjs/index.js", // https://github.com/wagmi-dev/viem/issues/1329 tinykeys: "/node_modules/tinykeys/dist/tinykeys.js", + uuid: require.resolve("uuid"), }, setupFiles: ["/jest.polyfills.js"], setupFilesAfterEnv: ["/jest.setup.js"], diff --git a/src/test/index.tsx b/src/test/index.tsx index d742df60..889f76ef 100644 --- a/src/test/index.tsx +++ b/src/test/index.tsx @@ -1,5 +1,6 @@ import { wallets as keplrWallets } from "@cosmos-kit/keplr-extension"; import { ChainProvider } from "@cosmos-kit/react"; +import { WalletProvider } from "@solana/wallet-adapter-react"; import { QueryClientProvider } from "@tanstack/react-query"; import { Queries, queries, render, RenderOptions } from "@testing-library/react"; import React, { ComponentProps, FC, Fragment, PropsWithChildren } from "react"; @@ -9,6 +10,7 @@ import { getAssetLists, getChains } from "@/chains"; import { WalletModalProvider } from "@/components/WalletModal"; import { AssetsProvider } from "@/context/assets"; import { queryClient } from "@/lib/react-query"; +import { solanaWallets } from "@/lib/solana-wallet-adapter"; import { config } from "@/lib/wagmi"; import { SkipProvider } from "@/solve"; @@ -21,22 +23,27 @@ export const AllTheProviders: FC = ({ children }) => { return ( -
} + - - - - {children} - - - -
+
} + > + + + + {children} + + + +
+
); From 04c71151d0c9f4da420e81502af1f38bd554dbe1 Mon Sep 17 00:00:00 2001 From: Nur Fikri Date: Tue, 26 Mar 2024 12:38:41 +0700 Subject: [PATCH 23/23] testnet env var --- env.d.ts | 1 + src/hooks/useChains.ts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/env.d.ts b/env.d.ts index aca3e5bc..1355c2e2 100644 --- a/env.d.ts +++ b/env.d.ts @@ -12,6 +12,7 @@ declare namespace NodeJS { readonly RESEND_API_KEY?: string; readonly WALLETCONNECT_VERIFY_KEY?: string; readonly WORD_PHRASE_KEY?: string; + readonly NEXT_PUBLIC_IS_TESTNET?: boolean; } } diff --git a/src/hooks/useChains.ts b/src/hooks/useChains.ts index c5d8a467..94f25289 100644 --- a/src/hooks/useChains.ts +++ b/src/hooks/useChains.ts @@ -16,7 +16,6 @@ export type UseChainsQueryArgs = { export function useChains(args: UseChainsQueryArgs = {}) { const { select = (t) => t as T } = args; - const skipClient = useSkipClient(); return useQuery({ @@ -25,6 +24,7 @@ export function useChains(args: UseChainsQueryArgs = {}) { const chains = await skipClient.chains({ includeEVM: true, includeSVM: true, + includeTestnets: process.env.NEXT_PUBLIC_IS_TESTNET ? true : false, }); return chains @@ -36,6 +36,7 @@ export function useChains(args: UseChainsQueryArgs = {}) { logoURI: chain.logoURI || "/logo-fallback.png", }; }) + .filter((chain) => (process.env.NEXT_PUBLIC_IS_TESTNET ? chain.isTestnet : true)) .sort((chainA, chainB) => { return chainA.prettyName.localeCompare(chainB.prettyName); });