vega-frontend-monorepo/apps/token/src/lib/apollo-client.ts
Dexter Edwards bcaab22891
Feat/dockerize frontends (#388)
* feat: unhardcode contract addresses

* fix: linting and tests

* feat: switch contract usage in token app to use unhardcoded addresses

* chore: remove other usage of hard coded contract addresses

* feat: convert contracts to classes, update claim contract to fix circular dependency

* feat: add hard coded contract addresses to contracts page

* fix: misc tidy up

* chore: rename ethers big num conversion func

* fix: remove pending transactions modal

* chore: add single toBigNum function that can accept number string or EthersBignNumber

* chore: delete unused tranche helpers and decimals functions from smart contracts lib

* feat: add faucetable token class

* fix: reset tx state after early exit from approve tx

* feat: re add transaction modal using zustand store

* fix: loader colors for eth wallet

* fix: pass ethereum config to gurantee existence before tx execution

* add docker image for building explorer

* add arg

* env file changes

* add docker file to build env file

* add requirement for env file in explorer

* fix env file syntax

* containers functional

* default to testnet

* make env flag logic consistent in all places

* pre populate env file

* ensure working for all projects

* address PR comment

* generalising env for token

* invert config dependency from ui toolkit

* fix: merge issues

* docs: running containers documentation

* style: lint

* fix: env varibales not being added properly

* chore: fix merge issues

* chore: fix docker file to support new exectutors

* chore: set address on all contracts as a property

* feat: pull token from contract rather than relying on env var

* chore: fix typing

* chore: remove duplicated prop

* chore: don't use chainId

* style: lint

* style: lint

* Merge branch 'master' into feat/dockerize-frontends

* Merge remote-tracking branch 'origin/master' into feat/dockerize-frontends

* test: revert changes to explorer e2e file

* fix: creating client without base causing token to error

* test: fix tests erroring in before hook due to file not being found

* chore: remove node env from configurable flags

Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
2022-06-13 15:39:17 +01:00

175 lines
4.9 KiB
TypeScript

import type { FieldFunctionOptions, Reference } from '@apollo/client';
import { ApolloClient, from, HttpLink, InMemoryCache } from '@apollo/client';
import { onError } from '@apollo/client/link/error';
import { RetryLink } from '@apollo/client/link/retry';
import sortBy from 'lodash/sortBy';
import uniqBy from 'lodash/uniqBy';
import { BigNumber } from './bignumber';
import { addDecimal } from './decimals';
import { deterministicShuffle } from './deterministic-shuffle';
// Create seed in memory. Validator list order will remain the same
// until the page is refreshed.
const VALIDATOR_RANDOMISER_SEED = (
Math.floor(Math.random() * 1000) + 1
).toString();
export function createClient(base?: string) {
if (!base) {
throw new Error('Base must be passed into createClient!');
}
const formatUintToNumber = (amount: string, decimals = 18) =>
addDecimal(new BigNumber(amount), decimals).toString();
const createReadField = (fieldName: string) => ({
[`${fieldName}Formatted`]: {
read(_: string, options: FieldFunctionOptions) {
const amount = options.readField(fieldName) as string;
return amount ? formatUintToNumber(amount) : '0';
},
},
});
const cache = new InMemoryCache({
typePolicies: {
Query: {
fields: {
nodes: {
// Merge function to make the validator list random but remain consistent
// as the user navigates around the site. If the user refreshes the list
// will be randomised.
merge: (existing = [], incoming) => {
// uniqBy will take the first of any matches
const uniq = uniqBy([...incoming, ...existing], 'id');
// sort result so that the input is consistent
const sorted = sortBy(uniq, 'id');
// randomise based on seed string
const random = deterministicShuffle(
VALIDATOR_RANDOMISER_SEED,
sorted
);
return random;
},
},
},
},
Account: {
keyFields: false,
fields: {
balanceFormatted: {
read(_: string, options: FieldFunctionOptions) {
const balance = options.readField('balance');
const asset = options.readField('asset');
const decimals = options.readField(
'decimals',
asset as Reference
);
if (typeof balance !== 'string') return '0';
if (typeof decimals !== 'number') return '0';
return balance && decimals
? formatUintToNumber(balance, decimals)
: '0';
},
},
},
},
Delegation: {
keyFields: false,
// Only get full updates
merge(_, incoming) {
return incoming;
},
fields: {
...createReadField('amount'),
},
},
Reward: {
keyFields: false,
fields: {
...createReadField('amount'),
},
},
RewardPerAssetDetail: {
keyFields: false,
fields: {
...createReadField('totalAmount'),
},
},
Node: {
keyFields: false,
fields: {
...createReadField('pendingStake'),
...createReadField('stakedByOperator'),
...createReadField('stakedByDelegates'),
...createReadField('stakedTotal'),
},
},
NodeData: {
merge: (existing = {}, incoming) => {
return { ...existing, ...incoming };
},
fields: {
...createReadField('stakedTotal'),
},
},
Party: {
fields: {
stake: {
merge(existing, incoming) {
return {
...existing,
...incoming,
};
},
read(stake) {
if (stake) {
return {
...stake,
currentStakeAvailableFormatted: formatUintToNumber(
stake.currentStakeAvailable
),
};
}
return stake;
},
},
},
},
Withdrawal: {
fields: {
pendingOnForeignChain: {
read: (isPending = false) => isPending,
},
},
},
},
});
const retryLink = new RetryLink({
delay: {
initial: 300,
max: 10000,
jitter: true,
},
});
const httpLink = new HttpLink({
uri: base,
credentials: 'same-origin',
});
const errorLink = onError(({ graphQLErrors, networkError }) => {
// eslint-disable-next-line no-console
console.log(graphQLErrors);
// eslint-disable-next-line no-console
console.log(networkError);
});
return new ApolloClient({
connectToDevTools: process.env['NODE_ENV'] === 'development',
link: from([errorLink, retryLink, httpLink]),
cache,
});
}