mirror of
https://github.com/trezor/trezor-wallet
synced 2024-12-30 19:00:53 +00:00
handle pending tx from blockchain notification
This commit is contained in:
parent
a32f0faf38
commit
ab4ab8b5a4
@ -3,6 +3,7 @@
|
||||
import TrezorConnect from 'trezor-connect';
|
||||
import BigNumber from 'bignumber.js';
|
||||
import * as BLOCKCHAIN from 'actions/constants/blockchain';
|
||||
import * as PENDING from 'actions/constants/pendingTx';
|
||||
|
||||
import type {
|
||||
TrezorDevice,
|
||||
@ -99,7 +100,6 @@ export const onBlockMined = (payload: $ElementType<BlockchainBlock, 'payload'>):
|
||||
const fee = await TrezorConnect.blockchainGetFee({
|
||||
coin: network,
|
||||
});
|
||||
|
||||
if (!fee.success) return;
|
||||
|
||||
dispatch({
|
||||
@ -141,10 +141,52 @@ export const onBlockMined = (payload: $ElementType<BlockchainBlock, 'payload'>):
|
||||
}
|
||||
};
|
||||
|
||||
export const onNotification = (payload: $ElementType<BlockchainNotification, 'payload'>): PromiseAction<void> => async (dispatch: Dispatch, getState: GetState): Promise<void> => {
|
||||
const { notification } = payload;
|
||||
const account = getState().accounts.find(a => a.address === notification.address);
|
||||
if (!account) return;
|
||||
|
||||
// not used for now, waiting for fix in blockbook
|
||||
export const onNotification = (payload: $ElementType<BlockchainNotification, 'payload'>): PromiseAction<void> => async (/*dispatch: Dispatch, getState: GetState*/): Promise<void> => {
|
||||
console.warn('OnBL', payload);
|
||||
if (notification.status === 'pending') {
|
||||
dispatch({
|
||||
type: PENDING.ADD,
|
||||
payload: {
|
||||
type: notification.type,
|
||||
hash: notification.hash,
|
||||
network: account.network,
|
||||
address: account.address,
|
||||
currency: account.network,
|
||||
amount: notification.amount,
|
||||
total: notification.amount,
|
||||
fee: notification.fee,
|
||||
},
|
||||
});
|
||||
|
||||
// todo: replace "send success" notification with link to explorer
|
||||
} else if (notification.status === 'confirmed') {
|
||||
dispatch({
|
||||
type: PENDING.TX_RESOLVED,
|
||||
hash: notification.hash,
|
||||
});
|
||||
}
|
||||
|
||||
const updatedAccount = await TrezorConnect.rippleGetAccountInfo({
|
||||
account: {
|
||||
address: account.address,
|
||||
block: account.block,
|
||||
history: false,
|
||||
},
|
||||
});
|
||||
if (!updatedAccount.success) return;
|
||||
|
||||
dispatch(AccountsActions.update({
|
||||
...account,
|
||||
balance: updatedAccount.payload.balance,
|
||||
block: updatedAccount.payload.block,
|
||||
sequence: updatedAccount.payload.sequence,
|
||||
}));
|
||||
|
||||
// todo: get transaction history here
|
||||
// console.warn("OnBlAccount", account);
|
||||
// this event can be triggered multiple times
|
||||
// // 1. check if pair [txid + address] is already in reducer
|
||||
// const network: string = payload.coin.shortcut.toLowerCase();
|
||||
|
@ -13,12 +13,11 @@ export type PendingTxAction = {
|
||||
payload: PendingTx
|
||||
} | {
|
||||
type: typeof PENDING.TX_RESOLVED,
|
||||
tx: PendingTx,
|
||||
receipt?: Object,
|
||||
hash: string,
|
||||
} | {
|
||||
type: typeof PENDING.TX_REJECTED,
|
||||
tx: PendingTx,
|
||||
hash: string,
|
||||
} | {
|
||||
type: typeof PENDING.TX_TOKEN_ERROR,
|
||||
tx: PendingTx,
|
||||
hash: string,
|
||||
}
|
@ -137,25 +137,24 @@ export const resolvePendingTransactions = (network: string): PromiseAction<void>
|
||||
const instance: Web3Instance = await dispatch(initWeb3(network));
|
||||
const pending = getState().pending.filter(p => p.network === network);
|
||||
pending.forEach(async (tx) => {
|
||||
const status = await instance.web3.eth.getTransaction(tx.id);
|
||||
const status = await instance.web3.eth.getTransaction(tx.hash);
|
||||
if (!status) {
|
||||
dispatch({
|
||||
type: PENDING.TX_REJECTED,
|
||||
tx,
|
||||
hash: tx.hash,
|
||||
});
|
||||
} else {
|
||||
const receipt = await instance.web3.eth.getTransactionReceipt(tx.id);
|
||||
const receipt = await instance.web3.eth.getTransactionReceipt(tx.hash);
|
||||
if (receipt) {
|
||||
if (status.gas !== receipt.gasUsed) {
|
||||
dispatch({
|
||||
type: PENDING.TX_TOKEN_ERROR,
|
||||
tx,
|
||||
hash: tx.hash,
|
||||
});
|
||||
}
|
||||
dispatch({
|
||||
type: PENDING.TX_RESOLVED,
|
||||
tx,
|
||||
receipt,
|
||||
hash: tx.hash,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -4,59 +4,55 @@ import * as PENDING from 'actions/constants/pendingTx';
|
||||
import * as SEND from 'actions/constants/send';
|
||||
|
||||
import type { TrezorDevice, Action } from 'flowtype';
|
||||
import type { SendTxAction } from 'actions/SendFormActions';
|
||||
|
||||
export type PendingTx = {
|
||||
+type: 'send' | 'receive';
|
||||
+id: string;
|
||||
+network: string;
|
||||
+address: string;
|
||||
+deviceState: string;
|
||||
+currency: string;
|
||||
+amount: string;
|
||||
+total: string;
|
||||
+tx: any;
|
||||
+nonce: number;
|
||||
rejected: boolean;
|
||||
}
|
||||
+type: 'send' | 'recv',
|
||||
+hash: string,
|
||||
+network: string,
|
||||
+address: string,
|
||||
+currency: string,
|
||||
+amount: string,
|
||||
+total: string,
|
||||
+fee: string,
|
||||
rejected?: boolean,
|
||||
};
|
||||
|
||||
export type State = Array<PendingTx>;
|
||||
|
||||
const initialState: State = [];
|
||||
|
||||
const add = (state: State, action: SendTxAction): State => {
|
||||
const newState = [...state];
|
||||
newState.push({
|
||||
type: 'send',
|
||||
id: action.txid,
|
||||
network: action.account.network,
|
||||
address: action.account.address,
|
||||
deviceState: action.account.deviceState,
|
||||
// const add = (state: State, action: SendTxAction): State => {
|
||||
// const newState = [...state];
|
||||
// newState.push({
|
||||
// type: 'send',
|
||||
// id: action.txid,
|
||||
// network: action.account.network,
|
||||
// address: action.account.address,
|
||||
// deviceState: action.account.deviceState,
|
||||
|
||||
currency: action.selectedCurrency,
|
||||
amount: action.amount,
|
||||
total: action.total,
|
||||
tx: action.tx,
|
||||
nonce: action.nonce,
|
||||
rejected: false,
|
||||
});
|
||||
return newState;
|
||||
};
|
||||
// currency: action.selectedCurrency,
|
||||
// amount: action.amount,
|
||||
// total: action.total,
|
||||
// tx: action.tx,
|
||||
// nonce: action.nonce,
|
||||
// rejected: false,
|
||||
// });
|
||||
// return newState;
|
||||
// };
|
||||
|
||||
/*
|
||||
const addFromBloockbokNotifiaction = (state: State, payload: any): State => {
|
||||
|
||||
const addFromNotification = (state: State, payload: PendingTx): State => {
|
||||
const newState = [...state];
|
||||
newState.push(payload);
|
||||
return newState;
|
||||
};
|
||||
*/
|
||||
|
||||
const clear = (state: State, device: TrezorDevice): State => state.filter(tx => tx.deviceState !== device.state);
|
||||
//const clear = (state: State, device: TrezorDevice): State => state.filter(tx => tx.deviceState !== device.state);
|
||||
|
||||
const remove = (state: State, id: string): State => state.filter(tx => tx.id !== id);
|
||||
const remove = (state: State, hash: string): State => state.filter(tx => tx.hash !== hash);
|
||||
|
||||
const reject = (state: State, id: string): State => state.map((tx) => {
|
||||
if (tx.id === id && !tx.rejected) {
|
||||
const reject = (state: State, hash: string): State => state.map((tx) => {
|
||||
if (tx.hash === hash && !tx.rejected) {
|
||||
return { ...tx, rejected: true };
|
||||
}
|
||||
return tx;
|
||||
@ -64,21 +60,21 @@ const reject = (state: State, id: string): State => state.map((tx) => {
|
||||
|
||||
export default function pending(state: State = initialState, action: Action): State {
|
||||
switch (action.type) {
|
||||
case SEND.TX_COMPLETE:
|
||||
return add(state, action);
|
||||
// case SEND.TX_COMPLETE:
|
||||
// return add(state, action);
|
||||
|
||||
case CONNECT.FORGET:
|
||||
case CONNECT.FORGET_SINGLE:
|
||||
case CONNECT.FORGET_SILENT:
|
||||
case CONNECT.RECEIVE_WALLET_TYPE:
|
||||
return clear(state, action.device);
|
||||
// case CONNECT.FORGET:
|
||||
// case CONNECT.FORGET_SINGLE:
|
||||
// case CONNECT.FORGET_SILENT:
|
||||
// case CONNECT.RECEIVE_WALLET_TYPE:
|
||||
// return clear(state, action.device);
|
||||
|
||||
// case PENDING.ADD:
|
||||
// return add(state, action.payload);
|
||||
case PENDING.ADD:
|
||||
return addFromNotification(state, action.payload);
|
||||
case PENDING.TX_RESOLVED:
|
||||
return remove(state, action.tx.id);
|
||||
return remove(state, action.hash);
|
||||
case PENDING.TX_REJECTED:
|
||||
return reject(state, action.tx.id);
|
||||
return reject(state, action.hash);
|
||||
|
||||
case PENDING.FROM_STORAGE:
|
||||
return action.payload;
|
||||
|
@ -140,7 +140,7 @@ class PendingTransactions extends PureComponent<Props> {
|
||||
<H2>Pending transactions</H2>
|
||||
{this.getPendingTransactions().map(tx => (
|
||||
<TransactionWrapper
|
||||
key={tx.id}
|
||||
key={tx.hash}
|
||||
>
|
||||
<TransactionIcon
|
||||
textColor={() => this.getTransactionIconColors(tx).textColor}
|
||||
@ -154,7 +154,7 @@ class PendingTransactions extends PureComponent<Props> {
|
||||
|
||||
<TransactionName>
|
||||
<StyledLink
|
||||
href={`${this.props.network.explorer.tx}${tx.id}`}
|
||||
href={`${this.props.network.explorer.tx}${tx.hash}`}
|
||||
isGray
|
||||
>
|
||||
{this.getTransactionName(tx)}
|
||||
|
Loading…
Reference in New Issue
Block a user