vega-frontend-monorepo/apps/token/src/hooks/use-transaction.ts
Sam Keen 9591687a80
Feat/224 move token app into monorepo (#229)
* moved TFE into monorepo with some remaining errors

* moved TFE into monorepo with some remaining errors - further files

* add tailwind config, use etherscan link from toolkit, use web3 from lib

* make app compatible with react router 6

* remove vega keys from app state and use from state from lib

* comment out crowdin script injection

* convert all buttons to use ui toolkit buttons

* remove blueprint inputs and selects and replace with ui-toolkit

* remove css resets

* tidy button styles in wallet replace splash-screen with version from ui-toolkit

* various style fixes

* tidy up proposal list

* add valid key to route children

* Set custom port and config for token e2e tests

* added env title e2e test

* started some styling fixes - nav and home route

* Added 'h-auto' to button height regex check

* Added 'h-auto' to regex check to allow desired TFE button height

* Removed scss and used tailwind for heading component

* Woff files not woof :)

* Proper nav h1 font size

* Wallet card headings

* Vega wallet button styles

* Set project to use static hosted alpha font (cors being fixed separately)

* Eth wallet button styles (unfinished)

* Home route styles

* Staking route styles and title calculation

* Rewards route styles

* Vega wallet container button style

* Eth wallet disconnect button

* Connect dialog title colour and spacing

* Splash screen layout

* Fixed a bunch of linting errors

* Used 'Object.entries' instead of 'Array.from' to create iterable from object in 'use-search-params'

* Removed use of 'any' from 'use-search-params'

* Better simplification of 'use-search-params'

* Removed package.json duplication errors, set most up-to-date version from duplicate options

* Elvis for possible undefined in 'use-add-asset-to-wallet'

* Removed redundant files

* Removed old todo

* Removed package.json redundant packages

* Added dark class for dialog h1 text colour (required as the current scss gives a wrong default for this element)

* update useAddAsset to use new provider

* Ensure Jest has required methods

* tidy up package.json

* remove ts-ignores and use casts for dynamic grid imports

* remove unused code from token-e2e

* update to latest types from react 17

* Removed vegag wallet not running component as it should be handled by wallet lib

* fix typing of contract addresses

* type cast network string to Network enum in reduce

* remove comment, issue 270 created instead

* default associated wallet amounts to zero

* update comment

* delete unused staking-overview component, add note about withTranslation types to comment

* re add proposal dates

* enable source maps for build

* add rest of env files for networks

* remove crowdin script tags from index.html

* add testing-library/jest-dom to types in test tsconfig

* setup i18n for tests so that translations are used, proposal change table test

* delete unused translation files and config

* set sentry release to use commit ref

* delete dex liquidity pages

* remove unused useVegaLPStaking hook

* use found id so no non null assertion needed

* remove mocked graphql provider

* remove commented out breadcrumb component

* add comment and link to issue for syntax highlighter changes

* fix any types in token-input, add link to ui-toolkit input changes

* dont default allowance to zero as it affects rendering logic

* fix spacing between callouts on associate page

* adjust spacing between callout for association callout

* fix alignment of ethereum splash screen

* use ethereum connect dialog state for connect dialog

* add infura provider as default

* change from infura provider to JsonRpcProvider

* remove unused Ethereum config

* add custom webpack config to inject sentry plugin

* delete commented out code for pending stake

* add comment linking input elements issue for eth-address-input

* move useEagerConnect to libs/wallet, add logic for connecting state so token app can load after connection has succeeded or failed

* remove unused storage files, update web3 connector to render children if not actively connected

Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2022-04-20 12:37:44 -07:00

130 lines
3.2 KiB
TypeScript

import React from 'react';
import * as Sentry from '@sentry/react';
import { useTranslation } from 'react-i18next';
import type { ethers } from 'ethers';
import { isUnexpectedError, isUserRejection } from '../lib/web3-utils';
import {
initialState,
TransactionActionType,
transactionReducer,
} from './transaction-reducer';
export const useTransaction = (
performTransaction: () => Promise<ethers.ContractTransaction>,
requiredConfirmations = 1
) => {
const { t } = useTranslation();
const [state, dispatch] = React.useReducer(transactionReducer, {
...initialState,
requiredConfirmations,
});
const handleError = React.useCallback(
(err: Error) => {
if (isUnexpectedError(err)) {
Sentry.captureException(err);
}
if (isUserRejection(err)) {
dispatch({ type: TransactionActionType.TX_RESET });
return;
} else {
Sentry.captureException(err);
}
const defaultMessage = t('Something went wrong');
const errorSubstitutions = {
unknown: defaultMessage,
'Transaction has been reverted by the EVM': defaultMessage,
};
dispatch({
type: TransactionActionType.TX_ERROR,
error: err,
errorSubstitutions,
});
},
[dispatch, t]
);
const perform = React.useCallback(async () => {
dispatch({
type: TransactionActionType.TX_REQUESTED,
});
Sentry.addBreadcrumb({
type: 'Transaction',
level: Sentry.Severity.Log,
message: 'Transaction requested',
timestamp: Date.now(),
});
try {
const tx = await performTransaction();
dispatch({
type: TransactionActionType.TX_SUBMITTED,
txHash: tx.hash,
});
Sentry.addBreadcrumb({
type: 'Transaction',
level: Sentry.Severity.Log,
message: 'Transaction submitted',
data: {
hash: tx.hash,
from: tx.from,
gasLimit: tx.gasLimit.toString(),
nonce: tx.nonce,
},
timestamp: Date.now(),
});
let receipt: ethers.ContractReceipt | null = null;
for (let i = 1; i <= requiredConfirmations; i++) {
receipt = await tx.wait(i);
dispatch({
type: TransactionActionType.TX_CONFIRMATION,
confirmations: receipt.confirmations,
});
}
if (!receipt) {
throw new Error('No receipt after confirmations are met');
}
dispatch({
type: TransactionActionType.TX_COMPLETE,
receipt,
confirmations: receipt.confirmations,
});
Sentry.addBreadcrumb({
type: 'Transaction',
level: Sentry.Severity.Log,
message: 'Transaction complete',
data: {
blockNumber: receipt.blockNumber,
confirmations: receipt.confirmations,
from: receipt.from,
to: receipt.to,
transactionHash: receipt.transactionHash,
},
timestamp: Date.now(),
});
} catch (err) {
handleError(err as Error);
}
}, [performTransaction, requiredConfirmations, handleError]);
const reset = () => {
dispatch({ type: TransactionActionType.TX_RESET });
};
return {
state,
dispatch,
perform,
reset,
};
};