mirror of https://github.com/certusone/oyster.git
feat: push notifications
This commit is contained in:
parent
3a78e670ab
commit
d926ee2425
|
@ -1,8 +1,8 @@
|
|||
import React, { useCallback, useState } from 'react';
|
||||
import { Button, Card } from 'antd';
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { Card, notification, Spin, Button } from 'antd';
|
||||
import { LAMPORTS_PER_SOL } from '@solana/web3.js';
|
||||
import { LABELS } from '../../constants';
|
||||
import { contexts, utils, ConnectButton, programIds } from '@oyster/common';
|
||||
import { contexts, utils, ConnectButton, programIds, formatAmount } from '@oyster/common';
|
||||
import { useHistory, useLocation } from "react-router-dom";
|
||||
import { SolanaInput, EthereumInput } from "./../Input";
|
||||
|
||||
|
@ -13,7 +13,6 @@ import { BigNumber } from 'ethers/utils';
|
|||
import { Erc20Factory } from '../../contracts/Erc20Factory';
|
||||
import { ProgressUpdate, transfer, TransferRequest } from '../../models/bridge';
|
||||
import { useEthereum } from '../../contexts';
|
||||
import { Spin } from 'antd';
|
||||
|
||||
const { useConnection } = contexts.Connection;
|
||||
const { useWallet } = contexts.Wallet;
|
||||
|
@ -39,7 +38,6 @@ export const Transfer = () => {
|
|||
from: ASSET_CHAIN.Ethereum,
|
||||
toChain: ASSET_CHAIN.Solana,
|
||||
});
|
||||
const [steps, setSteps] = useState<ProgressUpdate[]>([]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -67,41 +65,68 @@ export const Transfer = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
let activeSteps: ProgressUpdate[] = [];
|
||||
try {
|
||||
await transfer(connection, wallet, request, provider, (update) => {
|
||||
if(update.replace) {
|
||||
activeSteps.pop();
|
||||
activeSteps = [...activeSteps, update];
|
||||
} else {
|
||||
activeSteps = [...activeSteps, update];
|
||||
}
|
||||
const NotificationContent = () => {
|
||||
const [activeSteps, setActiveSteps] = useState<ProgressUpdate[]>([]);
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
let steps: ProgressUpdate[] = [];
|
||||
try {
|
||||
await transfer(connection, wallet, request, provider, (update) => {
|
||||
if(update.replace) {
|
||||
steps.pop();
|
||||
steps = [...steps, update];
|
||||
} else {
|
||||
steps = [...steps, update];
|
||||
}
|
||||
|
||||
setActiveSteps(steps);
|
||||
});
|
||||
} catch {
|
||||
// TODO...
|
||||
}
|
||||
})();
|
||||
}, [setActiveSteps]);
|
||||
|
||||
return <div>
|
||||
<div>
|
||||
<div>
|
||||
<h6>{`ETH Mainnet -> Solana Mainnet`}</h6>
|
||||
<h2>{formatAmount(request.amount || 0, 2)} {request.info?.name}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ textAlign: 'left', display: 'flex', flexDirection: 'column' }}>
|
||||
{(() => {
|
||||
let group = '';
|
||||
return activeSteps.map((step, i) => {
|
||||
let prevGroup = group;
|
||||
group = step.group;
|
||||
let newGroup = prevGroup !== group;
|
||||
return (
|
||||
<>
|
||||
{newGroup && <span>{group}</span>}
|
||||
<span style={{ marginLeft: 15 }}>{typeToIcon(step.type, (activeSteps.length - 1) === i)} {step.message}</span>
|
||||
</>);
|
||||
});
|
||||
})()}
|
||||
</div>
|
||||
</div>;
|
||||
};
|
||||
|
||||
notification.open({
|
||||
message: '',
|
||||
duration: 0,
|
||||
placement: 'bottomLeft',
|
||||
description: <NotificationContent />,
|
||||
className: 'custom-class',
|
||||
style: {
|
||||
width: 600,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
setSteps(activeSteps);
|
||||
});
|
||||
} catch {
|
||||
setTimeout(() => setSteps([]), 5000);
|
||||
}
|
||||
}}>
|
||||
Transfer
|
||||
</ConnectButton>
|
||||
<div style={{ textAlign: 'left', display: 'flex', flexDirection: 'column' }}>
|
||||
{(() => {
|
||||
let group = '';
|
||||
return steps.map((step, i) => {
|
||||
let prevGroup = group;
|
||||
group = step.group;
|
||||
let newGroup = prevGroup !== group;
|
||||
return (
|
||||
<>
|
||||
{newGroup && <span>{group}</span>}
|
||||
<span style={{ marginLeft: 15 }}>{typeToIcon(step.type, (steps.length - 1) === i)} {step.message}</span>
|
||||
</>);
|
||||
});
|
||||
|
||||
return null;
|
||||
})()}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -203,34 +203,32 @@ export const useWormholeAccounts = () => {
|
|||
const assetsToQueryNames: WrappedAssetMeta[] = [];
|
||||
|
||||
const ids = externalAssets.map(asset => {
|
||||
// TODO: add different nets/clusters
|
||||
asset.explorer = `https://etherscan.io/address/0x${asset.address}`;
|
||||
// TODO: add
|
||||
asset.wrappedExplorer = `https://explorer.solana.com/address/${asset.mintKey}`;
|
||||
|
||||
let knownToken = tokenMap.get(asset.mintKey);
|
||||
if(knownToken) {
|
||||
if (knownToken) {
|
||||
asset.logo = knownToken.logoURI;
|
||||
asset.symbol = knownToken.symbol;
|
||||
asset.name = knownToken.name;
|
||||
}
|
||||
|
||||
|
||||
let token = ethTokens.get(`0x${asset.address || ''}`);
|
||||
if(!token) {
|
||||
assetsToQueryNames.push(asset);
|
||||
return;
|
||||
if (token) {
|
||||
asset.logo = token.logoURI;
|
||||
asset.symbol = token.symbol;
|
||||
asset.name = token.name;
|
||||
}
|
||||
|
||||
asset.logo = token.logoURI;
|
||||
asset.symbol = token.symbol;
|
||||
asset.name = token.name;
|
||||
if (asset.symbol) {
|
||||
let coinInfo = coinList.get(asset.symbol.toLowerCase());
|
||||
|
||||
let coinInfo = coinList.get(token.symbol.toLowerCase());
|
||||
|
||||
if(coinInfo) {
|
||||
idToAsset.set(coinInfo.id, asset);
|
||||
addressToId.set(asset.address, coinInfo.id);
|
||||
return coinInfo.id;
|
||||
if(coinInfo) {
|
||||
idToAsset.set(coinInfo.id, asset);
|
||||
addressToId.set(asset.address, coinInfo.id);
|
||||
return coinInfo.id;
|
||||
}
|
||||
}
|
||||
}).filter(_ => _);
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
cache,
|
||||
TokenAccountParser,
|
||||
ParsedAccount,
|
||||
TokenAccount,
|
||||
} from '@oyster/common';
|
||||
|
||||
import { ethers } from 'ethers';
|
||||
|
@ -16,11 +15,7 @@ import { ASSET_CHAIN } from '../../utils/assets';
|
|||
import { BigNumber } from 'ethers/utils';
|
||||
import { Erc20Factory } from '../../contracts/Erc20Factory';
|
||||
import { WormholeFactory } from '../../contracts/WormholeFactory';
|
||||
import {
|
||||
AssetMeta,
|
||||
createWrappedAssetInstruction,
|
||||
WrappedMetaLayout,
|
||||
} from './meta';
|
||||
import { AssetMeta, createWrappedAssetInstruction } from './meta';
|
||||
import { bridgeAuthorityKey, wrappedAssetMintKey } from './helpers';
|
||||
import {
|
||||
Account,
|
||||
|
@ -28,13 +23,8 @@ import {
|
|||
PublicKey,
|
||||
TransactionInstruction,
|
||||
} from '@solana/web3.js';
|
||||
import BN from 'bn.js';
|
||||
import { createTokenAccount } from '@oyster/common/dist/lib/actions';
|
||||
import { AccountInfo, AccountLayout, Token } from '@solana/spl-token';
|
||||
|
||||
const { useConnection } = contexts.Connection;
|
||||
const { useWallet } = contexts.Wallet;
|
||||
const { notify } = utils;
|
||||
import { AccountInfo, AccountLayout } from '@solana/spl-token';
|
||||
|
||||
export interface ProgressUpdate {
|
||||
message: string;
|
||||
|
@ -56,6 +46,7 @@ export interface TransferRequestInfo {
|
|||
}
|
||||
|
||||
export interface TransferRequest {
|
||||
nonce?: number;
|
||||
signer?: ethers.Signer;
|
||||
asset?: string;
|
||||
amount?: number;
|
||||
|
@ -81,9 +72,18 @@ export const transfer = async (
|
|||
provider: ethers.providers.Web3Provider,
|
||||
setProgress: (update: ProgressUpdate) => void,
|
||||
) => {
|
||||
if (!request.asset) {
|
||||
return;
|
||||
}
|
||||
|
||||
const walletName = 'MetaMask';
|
||||
request.signer = provider?.getSigner();
|
||||
|
||||
request.nonce = await provider.getTransactionCount(
|
||||
request.signer.getAddress(),
|
||||
'pending',
|
||||
);
|
||||
|
||||
let counter = 0;
|
||||
// check difference between lock/approve (invoke lock if allowance < amount)
|
||||
const steps = {
|
||||
|
@ -108,7 +108,6 @@ export const transfer = async (
|
|||
}
|
||||
|
||||
const group = 'Initiate transfer';
|
||||
|
||||
try {
|
||||
const bridgeId = programIds().wormhole.pubkey;
|
||||
const authority = await bridgeAuthorityKey(bridgeId);
|
||||
|
@ -214,9 +213,7 @@ export const transfer = async (
|
|||
}
|
||||
|
||||
const group = 'Approve assets';
|
||||
|
||||
try {
|
||||
debugger;
|
||||
if (request.info?.allowance.lt(request.amountBN)) {
|
||||
let e = Erc20Factory.connect(request.asset, request.signer);
|
||||
setProgress({
|
||||
|
@ -270,7 +267,8 @@ export const transfer = async (
|
|||
!request.signer ||
|
||||
!request.recipient ||
|
||||
!request.toChain ||
|
||||
!request.info
|
||||
!request.info ||
|
||||
!request.nonce
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -293,7 +291,7 @@ export const transfer = async (
|
|||
request.amountBN,
|
||||
request.recipient,
|
||||
request.toChain,
|
||||
10,
|
||||
request.nonce,
|
||||
false,
|
||||
);
|
||||
setProgress({
|
||||
|
|
Loading…
Reference in New Issue