feat: push notifications

This commit is contained in:
bartosz-lipinski 2021-03-08 12:57:46 -06:00
parent 3a78e670ab
commit d926ee2425
3 changed files with 89 additions and 68 deletions

View File

@ -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>
</>
);
};

View File

@ -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(_ => _);

View File

@ -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({