{!props.isRoot && (
-
+
+
+
)}
Bridge
-
- FAQ
-
+ {/*
*/}
+ {/* FAQ*/}
+ {/*
*/}
Proof-of-Assets
diff --git a/packages/bridge/src/components/AssetsTable/index.less b/packages/bridge/src/components/AssetsTable/index.less
new file mode 100644
index 0000000..bbd02f1
--- /dev/null
+++ b/packages/bridge/src/components/AssetsTable/index.less
@@ -0,0 +1,45 @@
+@import "_colors";
+
+#recent-tx-container {
+ max-width: 70%;
+ margin: auto;
+ padding-bottom: 70px;
+ .description-text {
+ color: @tungsten-60
+ }
+ .ant-table-pagination.ant-pagination {
+ margin: 16px 100px;
+ }
+ .ant-table {
+ thead {
+ tr > th.ant-table-cell {
+ background-color: @tungsten-100;
+ border: none;
+ }
+ }
+ tbody > tr:nth-child(even) > td.ant-table-cell {
+ background-color: @tungsten-100;
+ border: none;
+ }
+ tbody > tr:nth-child(odd) > td.ant-table-cell {
+ background-color: @tungsten-50;
+ border: none;
+ }
+ }
+}
+
+@media screen and (max-width: 900px) {
+
+ #recent-tx-container {
+ max-width: 100%;
+ }
+}
+
+
+@media screen and (max-width: 1200px) {
+
+ #recent-tx-container {
+ max-width: 90%;
+ }
+
+}
diff --git a/packages/bridge/src/components/AssetsTable/index.tsx b/packages/bridge/src/components/AssetsTable/index.tsx
new file mode 100644
index 0000000..b5c79dd
--- /dev/null
+++ b/packages/bridge/src/components/AssetsTable/index.tsx
@@ -0,0 +1,134 @@
+import { Table } from 'antd';
+import React from 'react';
+
+import './index.less';
+import { Link } from 'react-router-dom';
+import { TokenDisplay } from '../../components/TokenDisplay';
+import { toChainSymbol } from '../../contexts/chainPair';
+import { formatUSD, shortenAddress } from '@oyster/common';
+import { useWormholeAccounts } from '../../hooks/useWormholeAccounts';
+
+export const AssetsTable = () => {
+ const {
+ loading: loadingLockedAccounts,
+ externalAssets,
+ totalInUSD,
+ } = useWormholeAccounts();
+
+ const columns = [
+ {
+ title: 'Symbol',
+ dataIndex: 'symbol',
+ key: 'symbol',
+ render(text: string, record: any) {
+ return {
+ props: {
+ style: {},
+ },
+ children: (
+
+
+ {record.logo && (
+
+ )}{' '}
+ {record.symbol}
+
+
+ ),
+ };
+ },
+ },
+ {
+ title: 'Name',
+ dataIndex: 'name',
+ key: 'name',
+ },
+ {
+ title: 'Amount',
+ dataIndex: 'amount',
+ key: 'amount',
+ },
+ {
+ title: 'Amount ($)',
+ dataIndex: 'amountInUSD',
+ key: 'amountInUSD',
+ },
+ {
+ title: 'Price',
+ dataIndex: 'price',
+ width: 100,
+ key: 'price',
+ render(text: string, record: any) {
+ return {
+ props: {
+ style: { textAlign: 'right' },
+ },
+ children: record.price ? formatUSD.format(record.price) : '--',
+ };
+ },
+ },
+ {
+ title: 'Asset Address',
+ dataIndex: 'address',
+ key: 'address',
+ render(text: string, record: any) {
+ return {
+ props: {
+ style: {},
+ },
+ children: (
+
+ {shortenAddress(text, 6)}
+
+ ),
+ };
+ },
+ },
+ {
+ title: 'Wrapped Address',
+ dataIndex: 'mintKey',
+ key: 'mintKey',
+ render(text: string, record: any) {
+ return {
+ props: {
+ style: {},
+ },
+ children: (
+
+ {shortenAddress(text, 6)}
+
+ ),
+ };
+ },
+ },
+ ];
+
+ return (
+
+
Total Value Locked
+
+ {formatUSD.format(totalInUSD)}
+
+
a.name)}
+ columns={columns}
+ loading={loadingLockedAccounts}
+ />
+
+ );
+};
diff --git a/packages/bridge/src/components/CurrentUserWalletBadge/index.tsx b/packages/bridge/src/components/CurrentUserWalletBadge/index.tsx
new file mode 100644
index 0000000..be4358b
--- /dev/null
+++ b/packages/bridge/src/components/CurrentUserWalletBadge/index.tsx
@@ -0,0 +1,32 @@
+import React from 'react';
+
+import { useWallet, WALLET_PROVIDERS } from '@oyster/common';
+import { shortenAddress } from '@oyster/common';
+
+export const CurrentUserWalletBadge = (props: { showDisconnect?: boolean }) => {
+ const { wallet, disconnect } = useWallet();
+
+ if (!wallet || !wallet.publicKey) {
+ return null;
+ }
+
+ return (
+
+
+
p.name === 'Sollet')[0]?.icon}
+ style={{ marginRight: 8 }}
+ />
+ {shortenAddress(`${wallet.publicKey}`)}
+ {props.showDisconnect && (
+
disconnect()}>
+ X
+
+ )}
+
+
+ );
+};
diff --git a/packages/bridge/src/components/EthereumConnect/index.tsx b/packages/bridge/src/components/EthereumConnect/index.tsx
index fbc14ea..c119e8d 100644
--- a/packages/bridge/src/components/EthereumConnect/index.tsx
+++ b/packages/bridge/src/components/EthereumConnect/index.tsx
@@ -56,7 +56,7 @@ export const EthereumConnect = () => {
) : (
)}
diff --git a/packages/bridge/src/components/Input/input.tsx b/packages/bridge/src/components/Input/input.tsx
index 216c957..5e83ac2 100644
--- a/packages/bridge/src/components/Input/input.tsx
+++ b/packages/bridge/src/components/Input/input.tsx
@@ -1,16 +1,18 @@
-import React, { useState } from 'react';
+import React, { useEffect, useState } from 'react';
import {
ConnectButton,
- CurrentUserWalletBadge,
+ CurrentUserBadge,
NumericInput,
+ useMint,
+ useUserAccounts,
useWallet,
} from '@oyster/common';
import './style.less';
-import { ASSET_CHAIN } from '../../models/bridge/constants';
import { TokenSelectModal } from '../TokenSelectModal';
-import { chainToName } from '../../utils/assets';
+import { ASSET_CHAIN, chainToName } from '../../utils/assets';
import { TokenChain } from '../TokenDisplay/tokenChain';
import { EthereumConnect } from '../EthereumConnect';
+import { CurrentUserWalletBadge } from '../CurrentUserWalletBadge';
export function Input(props: {
title: string;
@@ -32,16 +34,14 @@ export function Input(props: {
{chainToName(props.chain)}
- {typeof props.balance === 'number' && (
-
- props.onInputChange && props.onInputChange(props.balance)
- }
- >
- {props.balance.toFixed(6)}
-
- )}
+
+ props.onInputChange && props.onInputChange(props.balance)
+ }
+ >
+ {props.balance?.toFixed(6)}
+
button.ant-btn:not(.ant-dropdown-trigger) {
+ text-transform: uppercase;
+ color: white;
+ width: 166px;
+ font-size: 14px;
+ background: #E67828;
+ border-radius: 8px;
+ height: 40px;
+ }
+}
+
.wallet-wrapper {
display: flex;
justify-content: center;
diff --git a/packages/bridge/src/components/Layout/index.tsx b/packages/bridge/src/components/Layout/index.tsx
index 4745cf9..02fe182 100644
--- a/packages/bridge/src/components/Layout/index.tsx
+++ b/packages/bridge/src/components/Layout/index.tsx
@@ -1,34 +1,18 @@
-import React, { useEffect, useState } from 'react';
+import React from 'react';
import './../../App.less';
import './index.less';
-import { Layout, Button, Popover } from 'antd';
-import { Link, useLocation } from 'react-router-dom';
+import { Layout } from 'antd';
+import { useLocation } from 'react-router-dom';
import { LABELS } from '../../constants';
import { AppBar } from '../AppBar';
-import Wormhole from '../Wormhole';
-import { Footer as AppFooter } from './../Footer';
-import { EthereumConnect } from '../EthereumConnect';
-import { useEthereum } from '../../contexts';
-import { Settings } from '@oyster/common';
-import { SettingOutlined } from '@ant-design/icons';
const { Header, Content, Footer } = Layout;
export const AppLayout = React.memo((props: any) => {
- const { connected, disconnect } = useEthereum();
const location = useLocation();
- const [wormholeReady, setWormholeReady] = useState(false);
-
- const paths: { [key: string]: string } = {
- '/faucet': '7',
- };
-
const isRoot = location.pathname === '/';
- const current =
- [...Object.keys(paths)].find(key => location.pathname.startsWith(key)) ||
- '';
return (
<>
@@ -40,9 +24,10 @@ export const AppLayout = React.memo((props: any) => {
{props.children}
diff --git a/packages/bridge/src/components/RecentTransactionsTable/index.less b/packages/bridge/src/components/RecentTransactionsTable/index.less
new file mode 100644
index 0000000..c1e9885
--- /dev/null
+++ b/packages/bridge/src/components/RecentTransactionsTable/index.less
@@ -0,0 +1,54 @@
+@import "_colors";
+
+#recent-tx-container {
+ max-width: 70%;
+ margin: auto;
+ padding-bottom: 70px;
+ .completed {
+ color: @surge-30;
+ }
+ .failed {
+ color: @tungsten-60;
+ }
+ .error {
+ color: #6E1080;
+ }
+ .description-text {
+ color: @tungsten-60
+ }
+ .ant-table-pagination.ant-pagination {
+ margin: 16px 100px;
+ }
+ .ant-table {
+ thead {
+ tr > th.ant-table-cell {
+ background-color: @tungsten-100;
+ border: none;
+ }
+ }
+ tbody > tr:nth-child(even) > td.ant-table-cell {
+ background-color: @tungsten-100;
+ border: none;
+ }
+ tbody > tr:nth-child(odd) > td.ant-table-cell {
+ background-color: @tungsten-50;
+ border: none;
+ }
+ }
+}
+
+@media screen and (max-width: 900px) {
+
+ #recent-tx-container {
+ max-width: 100%;
+ }
+}
+
+
+@media screen and (max-width: 1200px) {
+
+ #recent-tx-container {
+ max-width: 90%;
+ }
+
+}
diff --git a/packages/bridge/src/components/RecentTransactionsTable/index.tsx b/packages/bridge/src/components/RecentTransactionsTable/index.tsx
index 0c29740..86466f7 100644
--- a/packages/bridge/src/components/RecentTransactionsTable/index.tsx
+++ b/packages/bridge/src/components/RecentTransactionsTable/index.tsx
@@ -1,29 +1,56 @@
-import { Table } from 'antd';
-import React from 'react';
+import { Button, Table, notification } from 'antd';
+import React, { useEffect, useMemo, useState } from 'react';
+
+import './index.less';
+
+import TimeAgo from 'javascript-time-ago';
+import en from 'javascript-time-ago/locale/en';
+
import { Link } from 'react-router-dom';
-import { useWormholeAccounts } from '../../hooks/useWormholeAccounts';
import { TokenDisplay } from '../../components/TokenDisplay';
import { toChainSymbol } from '../../contexts/chainPair';
-import { formatUSD, shortenAddress } from '@oyster/common';
+import {
+ formatUSD,
+ shortenAddress,
+ Identicon,
+ programIds,
+ TokenAccount,
+} from '@oyster/common';
+import { useWormholeTransactions } from '../../hooks/useWormholeTransactions';
+import { ASSET_CHAIN } from '../../utils/assets';
+import { TokenChain } from '../TokenDisplay/tokenChain';
+import bs58 from 'bs58';
+import { SyncOutlined } from '@ant-design/icons';
+import { typeToIcon } from '../Transfer';
+import { ProgressUpdate } from '@solana/bridge-sdk';
+import { WormholeFactory } from '@solana/bridge-sdk';
+import { useEthereum } from '../../contexts';
+import { useBridge } from '../../contexts/bridge';
-export const RecentTransactionsTable = () => {
- const {
- loading: loadingLockedAccounts,
- externalAssets,
- totalInUSD,
- } = useWormholeAccounts();
+TimeAgo.addDefaultLocale(en);
+const timeAgo = new TimeAgo('en-US');
- const columns = [
+export const RecentTransactionsTable = (props: {
+ showUserTransactions?: boolean;
+ tokenAccounts: TokenAccount[];
+}) => {
+ const { loading: loadingTransfers, transfers } = useWormholeTransactions(
+ props.tokenAccounts,
+ );
+ const { provider } = useEthereum();
+ const bridge = useBridge();
+
+ const [completedVAAs, setCompletedVAAs] = useState>([]);
+
+ const baseColumns = [
{
- title: 'Symbol',
- dataIndex: 'symbol',
- key: 'symbol',
+ title: '',
+ dataIndex: 'logo',
+ key: 'logo',
render(text: string, record: any) {
return {
- props: {
- style: {},
- },
- children: (
+ props: { style: {} },
+ children: record.logo ? (
{
{record.logo && (
- )}{' '}
- {record.symbol}
+ )}
+ ) : (
+
+
+
+
),
};
},
},
{
- title: 'Name',
- dataIndex: 'name',
- key: 'name',
- },
- {
- title: 'Amount',
- dataIndex: 'amount',
- key: 'amount',
- },
- {
- title: 'Amount ($)',
- dataIndex: 'amountInUSD',
- key: 'amountInUSD',
- },
- {
- title: 'Price',
- dataIndex: 'price',
- width: 100,
- key: 'price',
+ title: 'Asset',
+ dataIndex: 'symbol',
+ key: 'symbol',
render(text: string, record: any) {
+ const urlText = record.symbol || record.address;
return {
- props: {
- style: { textAlign: 'right' },
- },
- children: record.price ? formatUSD.format(record.price) : '--',
+ props: { style: {} },
+ children:
+ record.lockup.assetChain === ASSET_CHAIN.Solana ? (
+
+ {record.symbol || shortenAddress(urlText, 5)}
+
+ ) : (
+
+ {record.symbol || shortenAddress(urlText, 5)}
+
+ ),
};
},
},
{
- title: 'Asset Address',
- dataIndex: 'address',
- key: 'address',
+ title: 'Tokens moved',
+ dataIndex: 'amount',
+ key: 'amount',
+ },
+ {
+ title: '$, value',
+ dataIndex: 'value',
+ key: 'value',
render(text: string, record: any) {
return {
- props: {
- style: {},
- },
+ props: { style: {} },
+ children: record.value ? formatUSD.format(record.value) : '--',
+ };
+ },
+ },
+ {
+ title: 'TX hash',
+ dataIndex: 'txhash',
+ key: 'txhash',
+ render(text: string, record: any) {
+ return {
+ props: { style: {} },
children: (
{shortenAddress(text, 6)}
@@ -87,41 +141,208 @@ export const RecentTransactionsTable = () => {
},
},
{
- title: 'Wrapped Address',
- dataIndex: 'mintKey',
- key: 'mintKey',
+ title: 'Date',
+ dataIndex: 'date',
+ key: 'date',
render(text: string, record: any) {
return {
- props: {
- style: {},
- },
- children: (
-
- {shortenAddress(text, 6)}
-
- ),
+ props: { style: {} },
+ children: timeAgo.format(new Date(record.date * 1000)),
};
},
},
];
+
+ const userColumns = useMemo(
+ () => [
+ ...baseColumns,
+ {
+ title: 'Status',
+ dataIndex: 'status',
+ key: 'status',
+ render(text: string, record: any) {
+ const status =
+ completedVAAs.indexOf(record.txhash) > 0
+ ? 'Completed'
+ : record.status;
+ return {
+ props: { style: {} },
+ children: (
+ <>
+
+ {status}
+
+ {status === 'Failed' ? (
+