Skip to content

Commit

Permalink
Providers patch (#602)
Browse files Browse the repository at this point in the history
* update: usages of the composables which now rely on a provider

* update: move composable content to a top level global provider pattern

* fix: linting errors

* update: uptick version

* update: shuffle providers to its own folder in src

* fix: imports

* update: provider structure change

* update: provider is kill

* update: uptick version

* fix: type and lint errors

* fix: patch overidden registry change

* fix: linting errors
  • Loading branch information
arb000r authored Jul 27, 2021
1 parent 0ba8464 commit 5f2ef2f
Show file tree
Hide file tree
Showing 16 changed files with 570 additions and 356 deletions.
31 changes: 31 additions & 0 deletions src/Root.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { defineComponent, h } from 'vue';
import App from './App.vue';
import * as providerMap from './providers';

const providers = Object.values(providerMap);

export default defineComponent({
components: {
App,
...providerMap
},

render() {
function renderProviders(providers) {
if (!providers.length) return h(App);

const [provider, ...remainingProviders] = providers;
return h(
provider,
{},
{
default() {
return [renderProviders(remainingProviders)];
}
}
);
}

return renderProviders(providers);
}
});
13 changes: 8 additions & 5 deletions src/components/modals/SelectTokenModal/SelectTokenModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ import { defineComponent, reactive, toRefs, computed } from 'vue';
import { useStore } from 'vuex';
import { useI18n } from 'vue-i18n';
import { isAddress, getAddress } from '@ethersproject/address';
import useTokenLists from '@/composables/useTokensStore';
import useTokenStore from '@/composables/useTokensStore';
// import useTokenLists2 from '@/composables/useTokenLists2';
import TokenListItem from '@/components/lists/TokenListItem.vue';
import TokenListsListItem from '@/components/lists/TokenListsListItem.vue';
Expand Down Expand Up @@ -147,15 +147,18 @@ export default defineComponent({
isActiveList,
listMap,
activeTokenLists
} = useTokenLists();
const { tokens: tokenMap } = useTokens(data);
const tokens = computed(() => Object.values(tokenMap.value));
} = useTokenStore();
const { tokens: tokenMap } = useTokens(toRefs(data));
const tokens = computed(() => {
return Object.values(tokenMap.value);
});
// const {
// approvedTokenLists,
// toggleList,
// toggled: toggledTokenLists,
// isToggled: isToggledList
// } = useTokenLists2();
// } = useTokenStore2();
// COMPOSABLES
const store = useStore();
Expand Down
4 changes: 2 additions & 2 deletions src/composables/trade/useTokenApproval.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { computed, ComputedRef, Ref, ref, watch } from 'vue';
import { computed, Ref, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { parseUnits } from '@ethersproject/units';
import { TransactionResponse } from '@ethersproject/providers';
Expand All @@ -18,7 +18,7 @@ import { TokenMap } from '@/types';
export default function useTokenApproval(
tokenInAddress: Ref<string>,
amount: Ref<string>,
tokens: ComputedRef<TokenMap>
tokens: Ref<TokenMap>
) {
const approving = ref(false);
const approved = ref(false);
Expand Down
4 changes: 2 additions & 2 deletions src/composables/trade/useValidation.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { computed, ComputedRef, Ref } from 'vue';
import { computed, Ref } from 'vue';

import useWeb3 from '@/services/web3/useWeb3';
import { configService } from '@/services/config/config.service';
Expand All @@ -21,7 +21,7 @@ export default function useValidation(
tokenInAmount: Ref<string>,
tokenOutAddress: Ref<string>,
tokenOutAmount: Ref<string>,
tokens: ComputedRef<TokenMap>
tokens: Ref<TokenMap>
) {
const { isWalletReady } = useWeb3();

Expand Down
87 changes: 9 additions & 78 deletions src/composables/useAccountBalances.ts
Original file line number Diff line number Diff line change
@@ -1,90 +1,21 @@
import getProvider from '@/lib/utils/provider';
import { useQuery } from 'vue-query';
import { computed, reactive } from 'vue';
import { getBalances } from '@/lib/utils/balancer/tokens';
import { formatEther, formatUnits } from '@ethersproject/units';
import { getAddress } from '@ethersproject/address';
import QUERY_KEYS from '@/constants/queryKeys';
import { ETHER } from '@/constants/tokenlists';
import useWeb3 from '@/services/web3/useWeb3';
import useTokenStore from './useTokensStore';
import {
BalancesProviderPayload,
BalancesProviderSymbol
} from '@/providers/balances.provider';
import { inject } from 'vue';

// THE CONTENTS OF THIS WILL BE REPLACED/ALTERED WITH THE REGISTRY REFACTOR
export default function useAccountBalances() {
const { account, userNetworkConfig, isWalletReady } = useWeb3();
const { allTokens: tokens, isLoading: isLoadingTokens } = useTokenStore();

const isQueryEnabled = computed(
() =>
account.value !== null &&
Object.keys(tokens).length !== 0 &&
isWalletReady.value &&
!isLoadingTokens.value
);

const {
data,
balances,
hasBalance,
error,
isLoading,
isIdle,
isError,
isFetching,
refetch: refetchBalances
} = useQuery(
reactive(QUERY_KEYS.Balances.All(account, userNetworkConfig, tokens)),
() => {
return Promise.all([
getBalances(
String(userNetworkConfig.value?.chainId),
getProvider(userNetworkConfig.value?.key),
account.value,
Object.values(tokens.value)
.map(token => token.address)
.filter(token => token !== ETHER.address)
),
getProvider(userNetworkConfig.value?.key).getBalance(
account.value.toLowerCase()
)
]);
},
reactive({
enabled: isQueryEnabled,
keepPreviousData: isWalletReady
})
);

const balances = computed(() => {
if (data.value) {
const balances = {};
Object.keys(data.value[0]).forEach((tokenAddress: string) => {
const balance = formatUnits(
data.value[0][tokenAddress],
tokens.value[getAddress(tokenAddress)]?.decimals || 18
);
// not concerned with tokens which have a 0 balance
if (balance === '0.0') return;
balances[tokenAddress] = {
balance,
symbol: tokens.value[getAddress(tokenAddress)].symbol,
address: getAddress(tokenAddress)
};
});

// separate case for native ether
balances[ETHER.address.toLowerCase()] = {
balance: formatEther(data.value[1] || 0),
symbol: ETHER.symbol,
address: ETHER.address
};
return balances;
}
return null;
});

function hasBalance(address: string): boolean {
return !!(balances.value || {})[address];
}

refetchBalances
} = inject(BalancesProviderSymbol) as BalancesProviderPayload;
return {
balances,
hasBalance,
Expand Down
93 changes: 17 additions & 76 deletions src/composables/useAllowances.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,29 @@
import useWeb3 from '@/services/web3/useWeb3';
import { useQuery } from 'vue-query';
import { getAllowances } from '@/lib/utils/balancer/tokens';
import getProvider from '@/lib/utils/provider';
import { computed, reactive, Ref, ref } from 'vue';
import { ETHER } from '@/constants/tokenlists';
import { isAddress } from 'web3-utils';
import QUERY_KEYS from '@/constants/queryKeys';
import useTokens from './useTokens';
import { inject, onBeforeMount, Ref } from 'vue';
import {
AllowancesProviderSymbol,
AllowancesProviderPayload
} from '@/providers/allowances.provider';

type UseAccountPayload = {
tokens?: Ref<string[]>;
dstList?: Ref<string[]>;
};

const dstAllowanceMap = ref({});

// THE CONTENTS OF THIS WILL BE REPLACED/ALTERED WITH THE REGISTRY REFACTOR
export default function useAllowances(payload?: UseAccountPayload) {
const { userNetworkConfig, account } = useWeb3();
const { tokens: allTokens } = useTokens();
const provider = getProvider(String(userNetworkConfig.value?.chainId));
// filter out ether and any bad addresses
const tokens = computed(() =>
(payload?.tokens?.value || Object.keys(allTokens.value)).filter(
t => t !== ETHER.address && isAddress(t)
)
);
const dstList = computed(() => [
...(payload?.dstList?.value || []),
userNetworkConfig.value?.addresses.vault
]);

const isQueryEnabled = computed(
() => account.value != '' && tokens.value.length > 0
);
const {
data: allowances,
isLoading,
isFetching,
refetch: refetchAllowances
} = useQuery(
QUERY_KEYS.Account.Allowances(userNetworkConfig, account, dstList, tokens),
() =>
Promise.all(
dstList.value.map(async dst =>
getAllowances(
String(userNetworkConfig.value?.chainId),
provider,
account.value,
dst,
tokens.value
)
)
),
reactive({
enabled: isQueryEnabled,
onSuccess: allowances => {
allowances.forEach((allowance, i) => {
dstAllowanceMap.value[dstList.value[i]] = allowance;
});
}
})
);

const isLoadingOrFetching = computed(
() => isLoading.value || isFetching.value
);

const getRequiredAllowances = query => {
const tokens = query.tokens;
const amounts = query.amounts;
const dst = query.dst || userNetworkConfig.value?.addresses.vault;

const requiredAllowances = tokens.filter((token, index) => {
const amount = amounts[index];
if (parseFloat(amount) == 0) return false;
if (!dstAllowanceMap.value) return false;
if (!dstAllowanceMap.value[dst]) return true;
if (!dstAllowanceMap.value[dst][token.toLowerCase()]) return true;
return dstAllowanceMap.value[dst][token.toLowerCase()].lt(amount);
});

return requiredAllowances;
};
allowances,
getRequiredAllowances,
isLoading: isLoadingOrFetching,
refetchAllowances,
updateAllowanceRequest
} = inject(AllowancesProviderSymbol) as AllowancesProviderPayload;

onBeforeMount(() => {
if (payload) {
updateAllowanceRequest(payload);
}
});

return {
allowances,
Expand Down
81 changes: 15 additions & 66 deletions src/composables/useTokens.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,22 @@
import { Token, TokenMap } from '@/types';
import { getAddress } from '@ethersproject/address';
import { keyBy, orderBy, uniqBy } from 'lodash';
import { computed } from 'vue';
import { useStore } from 'vuex';
import useAccountBalances from './useAccountBalances';
import useTokenStore from './useTokensStore';

type TokenRequest = {
query?: string;
queryAddress?: string;
};
import {
TokenRequest,
TokensProviderPayload,
TokensProviderSymbol
} from '@/providers/tokens.provider';
import { inject, onBeforeMount } from 'vue';

export default function useTokens(request?: TokenRequest) {
const store = useStore();
const prices = computed(() => store.state.market.prices);
const { allTokens: _allTokens } = useTokenStore();
const { balances } = useAccountBalances();

const tokensList = computed(() => {
const _tokens = uniqBy<Token>(
orderBy(
// populate token data into list of tokens
Object.values(_allTokens.value).map(token => {
const balance =
(balances.value || {})[token.address.toLowerCase()]?.balance || '0';
const price = prices.value[token.address.toLowerCase()]?.price || 0;
const value = balance * price;
const price24HChange =
prices.value[token.address.toLowerCase()]?.price24HChange || 0;
const value24HChange = (value / 100) * price24HChange;
return {
...token,
address: getAddress(token.address), // Enforce that we use checksummed addresses
value,
price,
price24HChange,
balance,
value24HChange
};
}),
['value', 'balance'],
['desc', 'desc']
),
'address'
);

if (request?.queryAddress) {
const queryAddressLC = request?.queryAddress?.toLowerCase();

return _tokens.filter(
token => token.address?.toLowerCase() === queryAddressLC
);
}

// search functionality, this can be better
if (request?.query) {
const queryLC = request?.query?.toLowerCase();
const { tokens, updateTokenRequest } = inject(
TokensProviderSymbol
) as TokensProviderPayload;

return _tokens.filter(
token =>
token.name.toLowerCase().includes(queryLC) ||
token.symbol.toLowerCase().includes(queryLC)
);
onBeforeMount(() => {
if (request) {
updateTokenRequest(request);
}

return _tokens;
});

const tokens = computed(() => keyBy(tokensList.value, 'address') as TokenMap);

return { tokens };
return {
tokens
};
}
Loading

4 comments on commit 5f2ef2f

@vercel
Copy link

@vercel vercel bot commented on 5f2ef2f Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 5f2ef2f Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 5f2ef2f Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

beta-polygon – ./

beta-polygon.vercel.app
beta-polygon-balancer.vercel.app
beta-polygon-git-develop-balancer.vercel.app

@vercel
Copy link

@vercel vercel bot commented on 5f2ef2f Jul 27, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.