Skip to content

Commit

Permalink
Support ahUSDT on mainnet and PINK (#18)
Browse files Browse the repository at this point in the history
* Support ahUSDT on mainnet and PINK

* Add dev deploy

* Update website metadata

* Improve no-data style

* Add gap between chain options

* Fix fee asset id
  • Loading branch information
JayJay1024 authored Apr 2, 2024
1 parent e7838a5 commit 462174c
Show file tree
Hide file tree
Showing 28 changed files with 366 additions and 85 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/deploy-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Deploy development

on:
pull_request:
workflow_dispatch:

jobs:
deploy-package:
name: Deploy package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- uses: actions/checkout@v2
with:
repository: darwinia-network/devops
path: .github

- uses: ./.github/actions/smart-vercel
name: Deploy app
with:
vercel_token: ${{ secrets.VERCEL_TOKEN }}
vercel_group: itering
preview_output: true
alias_domain: "crosschain-dev"
project_name: "crosschain-ui"
script_run: false
dist_path: .
enable_notify_slack: true
slack_channel: darwinia-apps
slack_webhook: ${{ secrets.SLACK_INCOMING_WEBHOOK_URL }}
Binary file added public/images/asset/pink.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/images/network/darwinia.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions public/images/warning.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ body {

@layer components {
.border-radius {
@apply rounded-lg;
@apply rounded-2xl;
}

.app-header {
Expand Down
4 changes: 2 additions & 2 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import TransferProvider from "@/providers/transfer-provider";
const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
title: "Darwinia Cross-Chain",
description: "Darwinia USDT Cross-Chain",
title: "Asset Hub Bridge - Darwinia",
description: "Assets cross-chain between Darwinia and Asset Hub.",
};

export default function RootLayout({ children }: { children: React.ReactNode }) {
Expand Down
6 changes: 3 additions & 3 deletions src/components/address-input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default function AddressInput({
clickable={!!options?.length || !canInput}
canInput={canInput}
innerSuffix={<ConnectWallet who={who} height="full" />}
wrapClassName={`h-10 bg-transparent flex items-center justify-between p-1 border border-radius transition-colors duration-200 ${
wrapClassName={`h-12 bg-transparent flex items-center justify-between p-1 border border-radius transition-colors duration-200 ${
value?.valid === false ? "border-alert" : "border-transparent"
}`}
inputClassName="w-full border-radius h-full bg-transparent px-1"
Expand Down Expand Up @@ -100,8 +100,8 @@ export default function AddressInput({
</button>
))
) : (
<div className="px-middle py-small">
<span className="text-sm font-medium">No data</span>
<div className="inline-flex justify-center px-middle py-small">
<span className="text-sm font-medium text-slate-400">No data</span>
</div>
)}
</InputSelect>
Expand Down
17 changes: 9 additions & 8 deletions src/components/asset-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,31 @@ export default function AssetSelect({ value, options, disabled, onChange = () =>
return (
<Select
label={
<div className="flex items-center gap-small truncate">
<Image width={16} height={16} alt="Asset icon" src={getAssetIconSrc(value.icon)} />
<div className="flex items-center gap-small truncate px-1">
<Image width={22} height={22} alt="Asset icon" src={getAssetIconSrc(value.icon)} className="rounded-full" />
<span>{value.symbol}</span>
</div>
}
disabled={disabled}
sameWidth
labelClassName="flex items-center gap-middle shrink-0 w-28 justify-between bg-component h-full border-radius px-1 hover:opacity-80 transition-[transform,color] active:translate-y-1 disabled:translate-y-0 disabled:opacity-100 disabled:cursor-not-allowed"
childClassName="flex flex-col py-small bg-component border-primary border border-radius"
labelClassName="flex items-center gap-middle shrink-0 w-28 justify-between bg-component h-full border-radius px-1 hover:opacity-80 transition-[transform,color] disabled:translate-y-0 disabled:opacity-100 disabled:cursor-not-allowed"
childClassName="flex flex-col py-small bg-component border-primary border border-radius gap-[1px]"
>
{options?.length ? (
options.map((asset) => (
<button
key={asset.symbol}
disabled={asset.id === value.id}
onClick={() => onChange(asset)}
className="flex items-center gap-small px-middle py-2 transition-colors hover:bg-white/10"
className="flex items-center gap-small px-middle py-2 transition-colors hover:bg-white/10 disabled:bg-white/10"
>
<Image width={16} height={16} alt="Asset icon" src={getAssetIconSrc(asset.icon)} />
<Image width={20} height={20} alt="Asset icon" src={getAssetIconSrc(asset.icon)} className="rounded-full" />
<span className="text-sm font-medium">{asset.symbol}</span>
</button>
))
) : (
<div className="px-middle py-2">
<span className="text-sm font-medium">No data</span>
<div className="inline-flex justify-center px-middle py-2">
<span className="text-sm font-medium text-slate-400">No data</span>
</div>
)}
</Select>
Expand Down
17 changes: 11 additions & 6 deletions src/components/balance-input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Asset } from "@/types";
import { Asset, Cross } from "@/types";
import Input from "@/ui/input";
import { BN, BN_ZERO, bnToBn } from "@polkadot/util";
import AssetSelect from "./asset-select";
Expand All @@ -18,7 +18,7 @@ interface Props {
disabled?: boolean;
placeholder?: string;
balance?: BN;
min?: BN;
cross?: Cross;
asset?: Asset;
assetSupply?: BN;
assetLimit?: BN;
Expand All @@ -32,7 +32,7 @@ export default function BalanceInput({
disabled,
placeholder,
balance,
min,
cross,
asset,
assetSupply,
assetLimit,
Expand All @@ -52,6 +52,13 @@ export default function BalanceInput({
return placeholder ?? "Enter an amount";
}, [balance, asset, placeholder]);

const min = useMemo(() => {
if (cross && cross.fee.asset.native) {
return cross.fee.amount;
}
return undefined;
}, [cross]);

const handleInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
(e) => {
if (e.target.value) {
Expand All @@ -77,9 +84,7 @@ export default function BalanceInput({
const inputWidth = inputRef.current?.clientWidth || 1;
const spanWidth = spanRef.current?.clientWidth || 0;
const percent = (spanWidth / inputWidth) * 100;
if (percent < 10) {
setDynamicStyle("text-[3rem] font-extralight");
} else if (percent < 20) {
if (percent < 20) {
setDynamicStyle("text-[2.25rem] font-light");
} else if (percent < 30) {
setDynamicStyle("text-[1.875rem] font-light");
Expand Down
13 changes: 7 additions & 6 deletions src/components/chain-select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,31 @@ export default function ChainSelect({ value, options, disabled, onChange = () =>
<Select
label={
<div className="flex max-w-[140px] items-center gap-small">
<Image width={18} height={18} alt="Chain logo" src={getChainLogoSrc(value.logo)} />
<Image width={20} height={20} alt="Chain logo" src={getChainLogoSrc(value.logo)} />
<span className="truncate text-white/50">{value.name}</span>
</div>
}
disabled={disabled}
sameWidth
labelClassName="flex items-center gap-middle py-[4px] px-[6px] bg-transparent hover:bg-white/10 border-radius"
childClassName="flex flex-col py-small bg-component border-primary border border-radius"
childClassName="flex flex-col py-small bg-component border-primary border border-radius gap-[1px]"
arrowClassName="opacity-50"
>
{options?.length ? (
options.map((chain) => (
<button
key={chain.network}
disabled={chain.network === value.network}
onClick={() => onChange(chain)}
className="flex items-center gap-small px-middle py-2 transition-colors hover:bg-white/10"
className="flex items-center gap-small px-middle py-2 transition-colors hover:bg-white/10 disabled:bg-white/10"
>
<Image width={16} height={16} alt="Chain logo" src={getChainLogoSrc(chain.logo)} />
<Image width={18} height={18} alt="Chain logo" src={getChainLogoSrc(chain.logo)} />
<span className="truncate text-sm font-medium">{chain.name}</span>
</button>
))
) : (
<div className="px-middle py-2">
<span className="text-sm font-medium">No data</span>
<div className="inline-flex justify-center px-middle py-2">
<span className="text-sm font-medium text-slate-400">No data</span>
</div>
)}
</Select>
Expand Down
35 changes: 31 additions & 4 deletions src/components/transfer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Button from "@/ui/button";
import BalanceInput from "./balance-input";
import ChainSelect from "./chain-select";
import TransferSection from "./transfer-section";
import { isAssetExcess, parseCross } from "@/utils";
import { formatBalance, isAssetExcess, parseCross } from "@/utils";
import { useTalisman, useTransfer } from "@/hooks";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import SwitchCross from "./switch-cross";
Expand All @@ -13,6 +13,7 @@ import { useAccount, useNetwork, useSwitchNetwork } from "wagmi";
import { Asset, ChainConfig, WalletID } from "@/types";
import { BN_ZERO } from "@polkadot/util";
import notification from "@/ui/notification";
import Image from "next/image";

const {
defaultSourceChainOptions,
Expand All @@ -33,6 +34,7 @@ export default function Transfer() {
targetChain,
sourceAsset,
targetAsset,
usdtBalance,
sourceBalance,
targetBalance,
transferAmount,
Expand Down Expand Up @@ -76,6 +78,23 @@ export default function Transfer() {
[chain, sourceChain, activeSenderWallet],
);

const alert = useMemo(() => {
const fee = bridgeInstance?.getCrossInfo()?.fee;
const balance = usdtBalance?.asset.value;

if (fee && balance && fee.amount.gt(balance)) {
return (
<div className="flex items-start justify-center gap-small">
<Image alt="Warning" width={15} height={15} src="/images/warning.svg" />
<span className="text-xs text-alert">{`You need at least ${formatBalance(fee.amount, fee.asset.decimals)} ${
fee.asset.symbol
} in your account to cover cross-chain fees.`}</span>
</div>
);
}
return null;
}, [bridgeInstance, usdtBalance?.asset.value]);

const sourceChainRef = useRef(sourceChain);
const targetChainRef = useRef(targetChain);
const sourceAssetRef = useRef(sourceAsset);
Expand Down Expand Up @@ -219,7 +238,7 @@ export default function Transfer() {
: [];

return (
<div className="border-radius mx-auto mt-10 flex w-[30rem] flex-col gap-5 bg-component p-5">
<div className="border-radius mx-auto mt-10 flex w-[30rem] flex-col gap-5 bg-component p-5 pb-8">
{/* From */}
<TransferSection
label="From"
Expand All @@ -229,9 +248,9 @@ export default function Transfer() {
<BalanceInput
value={transferAmount}
asset={sourceAsset}
cross={bridgeInstance?.getCrossInfo()}
assetLimit={assetLimit}
assetSupply={targetAssetDetails?.supply}
min={sourceChain.minCross}
balance={sourceBalance?.asset.value}
assetOptions={sourceAssetOptions}
onChange={setTransferAmount}
Expand Down Expand Up @@ -281,9 +300,17 @@ export default function Transfer() {
</TransferSection>

{/* Send */}
<Button kind="primary" className="py-[7px]" onClick={handleSend} disabled={disabledSend} busy={busy}>
<Button
kind="primary"
className="mt-4 py-middle"
onClick={handleSend}
disabled={disabledSend || !!alert}
busy={busy}
>
{needSwitchNetwork ? "Switch network" : "Send"}
</Button>

{alert}
</div>
);
}
75 changes: 75 additions & 0 deletions src/config/chains/assethub-polkadot-chain.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { ChainConfig, ChainID, ParachainID, WalletID } from "@/types";
import { bnToBn } from "@polkadot/util";

export const assethubPolkadotChain: ChainConfig = {
/**
* Chain
*/
id: ChainID.INVALID,
network: "assethub-polkadot",
name: "Polkadot AssetHub",
nativeCurrency: {
name: "DOT",
symbol: "DOT",
decimals: 10,
},
rpcUrls: {
default: {
http: [],
webSocket: [],
},
public: {
http: [],
webSocket: [],
},
},
blockExplorers: {
default: {
name: "Subscan",
url: "https://assethub-polkadot.subscan.io",
},
},

/**
* Custom
*/
logo: "asset-hub.svg",
assets: [
{
icon: "usdt.svg",
id: 1984,
name: "Tether USD",
symbol: "USDT",
decimals: 6,
cross: [
{
isReserve: true,
target: { network: "darwinia", symbol: "ahUSDT" },
fee: { amount: bnToBn(20000), asset: { id: 1984, decimals: 6, symbol: "USDT", native: true } }, // 0.02 USDT
},
],
},
{
icon: "pink.jpg",
id: 23,
name: "PINK",
symbol: "PINK",
decimals: 10,
cross: [
{
isReserve: true,
target: { network: "darwinia", symbol: "ahPINK" },
fee: { amount: bnToBn(20000), asset: { id: 1984, decimals: 6, symbol: "USDT", native: false } }, // 0.02 USDT
},
],
},
],
wallets: [WalletID.TALISMAN],
addressType: "substrate",

/**
* Substrate
*/
endpoint: "wss://polkadot-asset-hub-rpc.polkadot.io",
parachainId: ParachainID.ASSETHUB_POLKADOT,
};
Loading

0 comments on commit 462174c

Please sign in to comment.