diff --git a/package.json b/package.json index 325a85d..95a3940 100644 --- a/package.json +++ b/package.json @@ -26,17 +26,16 @@ "deploy": "gh-pages -d example/build" }, "dependencies": { - "@apollo/client": "^3.6.2", "@fortawesome/free-regular-svg-icons": "^6.1.0", "@fortawesome/free-solid-svg-icons": "^6.1.0", "@polkadot/extension-dapp": "^0.40.4", "@polkadot/react-identicon": "^0.86.4", + "@reef-chain/ui-kit": "^1.1.2", "@reef-chain/util-lib": "^1.0.0-rc7", "@reef-defi/evm-provider": "^1.0.9", "@reef-defi/extension-base": "^1.0.14", "@reef-defi/extension-dapp": "^1.0.14", "@reef-defi/extension-inject": "^1.0.14", - "@reef-chain/ui-kit": "^1.1.2", "@types/react-router-dom": "^5.3.0", "axios": "^0.21.4", "bignumber.js": "^9.0.2", @@ -44,7 +43,6 @@ "eslint-import-resolver-typescript": "^2.4.0", "ethers": "^5.7.0", "graphql": "^16.2.0", - "graphql-ws": "^5.11.2", "process": "^0.11.10", "react-copy-to-clipboard": "^5.0.4", "react-router-dom": "^5.3.0", diff --git a/src/appState/accountState.ts b/src/appState/accountState.ts index 5d70022..bf35e26 100644 --- a/src/appState/accountState.ts +++ b/src/appState/accountState.ts @@ -22,21 +22,27 @@ import { filter } from 'rxjs/operators'; import { AccountJson } from '@reef-defi/extension-base/background/types'; import type { InjectedAccountWithMeta } from '@reef-defi/extension-inject/types'; import type { Signer as InjectedSigningKey } from '@polkadot/api/types'; -// import { graphql } from '@reef-chain/util-lib'; import { UpdateDataCtx } from './updateStateModel'; import { replaceUpdatedSigners, updateSignersEvmBindings } from './accountStateUtil'; -import { currentProvider$ } from './providerState'; +import { ACTIVE_NETWORK_LS_KEY, currentProvider$ } from './providerState'; import { ReefSigner } from '../state'; -// import { apolloExplorerClientInstance$, zenToRx, } from '../graphql/apollo'; import { accountJsonToMeta, metaAccountToSigner } from '../rpc/accounts'; -import { graphqlRequest } from '../graphql/gqlUtils'; -import axios from 'axios'; +import axios, { AxiosInstance } from 'axios'; +import {reefState} from "@reef-chain/util-lib"; export const accountsSubj = new ReplaySubject(1); + export const accountsJsonSubj = new ReplaySubject(1); export const accountsJsonSigningKeySubj = new ReplaySubject(1); export const reloadSignersSubj = new Subject>(); +const graphqlUrls = { + explorerTestnet:'https://squid.subsquid.io/reef-explorer-testnet/graphql', + dexTestnet:'https://squid.subsquid.io/reef-swap-testnet/graphql', + explorerMainnet:'https://squid.subsquid.io/reef-explorer/graphql', + dexMainnet:'https://squid.subsquid.io/reef-swap/graphql' +} + const signersFromJson$: Observable = combineLatest([accountsJsonSubj, currentProvider$, accountsJsonSigningKeySubj]).pipe( switchMap(([jsonAccounts, provider, signingKey]: [(AccountJson[] | InjectedAccountWithMeta[] | null), Provider, InjectedSigningKey]) => { let accounts = jsonAccounts || []; @@ -182,21 +188,6 @@ const signersWithUpdatedBalances$ = combineLatest([ }), ); -// const EVM_ADDRESS_UPDATE_GQL = graphql.EVM_ADDRESS_UPDATE_GQL; -/* -const EVM_ADDRESS_UPDATE_GQL = gql` - subscription query($accountIds: [String!]!) { - account( - where: { address: { _in: $accountIds } } - order_by: { timestamp: asc, address: asc } - ) { - address - evm_address - } - } -`; -*/ - // eslint-disable-next-line camelcase interface AccountEvmAddrData { address: string; @@ -205,7 +196,7 @@ interface AccountEvmAddrData { isEvmClaimed?: boolean; } -export const EVM_ADDRESS_UPDATE_GQL = ` +const EVM_ADDRESS_UPDATE_GQL = ` query query($accountIds: [String!]!) { accounts(where: {id_in: $accountIds}, orderBy: timestamp_DESC) { id @@ -214,46 +205,67 @@ export const EVM_ADDRESS_UPDATE_GQL = ` } `; -export const getAllAccounts = (accountIds:any) => ({ +const getGraphqlEndpoint = (network:string,isExplorer:boolean):string=>{ + if(isExplorer){ + if(network=='testnet'){ + return graphqlUrls.explorerTestnet + }else{ + return graphqlUrls.explorerMainnet + } + }else{ + if(network=='testnet'){ + return graphqlUrls.dexTestnet; + } + } + return graphqlUrls.dexMainnet; +} + +export const graphqlRequest = ( + httpClient: AxiosInstance, + queryObj: { query: string; variables: any }, + isExplorer?:boolean +) => { + let selectedNetwork:string="mainnet"; + try { + let storedNetwork = localStorage.getItem(ACTIVE_NETWORK_LS_KEY); + if(storedNetwork){ + let parsedStoredNetwork = JSON.parse(storedNetwork); + selectedNetwork = parsedStoredNetwork.name; + } + } catch (error) { + console.log(error); + } + const graphql = JSON.stringify(queryObj); + if(isExplorer){ + let url = getGraphqlEndpoint(selectedNetwork!,true); + return httpClient.post(url, graphql, { + headers: { 'Content-Type': 'application/json' }, + }); +} +let url = getGraphqlEndpoint(selectedNetwork!,false); +return httpClient.post(url, graphql, { + headers: { 'Content-Type': 'application/json' }, +}); +}; + +const getAllAccountsQuery = (accountIds:any) => ({ query: EVM_ADDRESS_UPDATE_GQL, variables: {accountIds} }); const indexedAccountValues$ = combineLatest([ signersInjected$, -]).pipe( - switchMap(([signers]) => { - try { - console.log("signers:", signers); - - - if (!signers) { - return []; - } else { - return graphqlRequest(axios,getAllAccounts(signers.map((s: any) => s.address)),true); - // apollo.subscribe({ - // query: EVM_ADDRESS_UPDATE_GQL, - // variables: { accountIds: signers.map((s: any) => s.address) }, - // fetchPolicy: 'network-only', - // }) - } - } catch (error) { - console.log("error", error); - return []; - } - }), - map((result: any): AccountEvmAddrData[] =>{ - console.log("result==",result); - return result.data?.data.accounts.map((a) => ({ - address: a.id, - evmAddress: a.evmAddress, - isEvmClaimed: !!a.evmAddress, - } as AccountEvmAddrData)) - } - ), - filter((v) => !!v), - startWith([]) -); +]) + .pipe( + switchMap(([ signers]) => (!signers + ? [] + : graphqlRequest(axios,getAllAccountsQuery(signers.map((s: any) => s.address)),true))), + map((result: any): AccountEvmAddrData[] => + { + return result.data.data.accounts.map((a) => ({ address: a.id, evmAddress: a.evmAddress, isEvmClaimed: !!a.evmAddress } as AccountEvmAddrData))}), + filter((v) => !!v), + startWith([]), + ); const signersWithUpdatedData$ = combineLatest([ signersWithUpdatedBalances$, @@ -321,14 +333,9 @@ const signersWithUpdatedData$ = combineLatest([ ); export const signers$: Observable = signersWithUpdatedData$; -const currentAddressSubj: Subject = new Subject(); -export const setCurrentAddress = (address: string|undefined) => currentAddressSubj.next(address); -export const currentAddress$: Observable = currentAddressSubj.asObservable() - .pipe( - startWith(''), - distinctUntilChanged(), - shareReplay(1), - ); + +export const setCurrentAddress:(address: string | undefined) => void = reefState.setSelectedAddress; +export const currentAddress$: Observable = reefState.selectedAddress$; // setting default signer (when signers exist) if no selected address exists combineLatest([signers$, currentAddress$]) @@ -386,4 +393,4 @@ export const selectedSigner$: Observable = combin return of(null); }), shareReplay(1), - ); + ); \ No newline at end of file diff --git a/src/appState/nftTokenState.ts b/src/appState/nftTokenState.ts index 81162a7..784cca0 100644 --- a/src/appState/nftTokenState.ts +++ b/src/appState/nftTokenState.ts @@ -1,63 +1,41 @@ import { - combineLatest, map, Observable, switchMap, + combineLatest, from, map, Observable, switchMap, } from 'rxjs'; import { BigNumber } from 'ethers'; import { NFT } from '../state'; import { currentProvider$ } from './providerState'; -import { queryGql$, selectedSignerAddressUpdate$ } from './tokenState'; +import { selectedSignerAddressUpdate$ } from './tokenState'; import { resolveNftImageLinks } from '../utils/nftUtil'; import { _NFT_IPFS_RESOLVER_FN } from './util'; -import axios from 'axios'; +import axios, { AxiosInstance } from 'axios'; +import { graphqlRequest } from './accountState'; const SIGNER_NFTS_GQL = ` - query query($accountId: String) { - tokenHolders( - orderBy: balance_DESC - where: {AND: {nftId_isNull: false, token: {id_isNull: false}, signer: {id_eq: $accountId}, balance_gt: "0"}, type_eq: Account}, - limit:100 - ) { - token { - id - type - } - balance - nftId +query query($accountId: String) { + tokenHolders( + orderBy: balance_DESC + limit:199 + where: {AND: {nftId_isNull: false, token: {id_isNull: false}, signer: {id_eq: $accountId}, balance_gt: "0"}, type_eq: Account} +) { + token { + id + type } - }`; + balance + nftId +} +}`; + - export const getSignerNftsQry = (accountId: string) => { +const getSignerNfts = (accountId: string) => { return { query: SIGNER_NFTS_GQL, variables: { - accountId, + accountId }, }; }; -/* -const SIGNER_NFTS_GQL = gql` - subscription query($accountId: String) { - token_holder( - order_by: { balance: desc } - where: { - _and: [{ nft_id: { _is_null: false } }, { signer: { _eq: $accountId } }] - type: { _eq: "Account" } - } - ) { - token_address - balance - nft_id - info - contract { - verified_contract { - type - contract_data - } - } - } - }`; -*/ - export interface VerifiedNft { token_address: string; balance: string; @@ -82,77 +60,20 @@ const parseTokenHolderArray = (resArr: VerifiedNft[]): NFT[] => resArr.map(({ iconUrl: '', } as NFT)); -/* async function getSqwidContractNfts(queryResult: any[] | undefined, signer: ReefSigner, provider: Provider) { - const mainnetGHash = '0x7834781d38e4798d548e34ec947d19deea29df148a7bf32484b7b24dacf8d4b7'; - const network = await provider.api.genesisHash.toHuman(); - const isMainnet = mainnetGHash === network; - - if (queryResult?.length || !isMainnet) { - return queryResult; - } - - const sqwid1155Address = '0x0601202b75C96A61CDb9A99D4e2285E43c6e60e4' - - const nftItemsABI = [{ - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "getTokensByOwner", - "outputs": [ - { - "internalType": "uint256[]", - "name": "", - "type": "uint256[]" - } - ], - "stateMutability": "view", - "type": "function" - }]; - const sqwid1155Contract = new Contract(sqwid1155Address, nftItemsABI, signer.signer); - const allTokens: BigNumber[] = await sqwid1155Contract.getTokensByOwner(signer.evmAddress); - const signerIds = allTokens.reduce((signerTokens:({ amt: string, nftId: string })[],tknAmt:BigNumber, i:number)=>{ - let amt = tknAmt.toString(); - if(amt !== '0'){ - signerTokens.push({amt, nftId:i.toString()}) - } - - return signerTokens; - },[]); - return signerIds.map(nftIdAmt=>({ - token_address: sqwid1155Address, - balance: nftIdAmt.amt, - nft_id: nftIdAmt.nftId, - info: { symbol: '' }, - contract: { - verified_contract: { - type: 'ERC1155', - contract_data: {type:ContractType.ERC1155} - } - } - } as VerifiedNft)); -} */ +const queryGql$ = ( + client: AxiosInstance, + queryObj: { query: string; variables: any } +) => + from(graphqlRequest(client as AxiosInstance, queryObj,true).then(res => res.data)); export const selectedSignerNFTs$: Observable = combineLatest([ selectedSignerAddressUpdate$, currentProvider$, ]) .pipe( - switchMap(([signer]) => (!signer + switchMap(([ signer]) => (!signer ? [] - : - - // apollo.subscribe({ - // query: SIGNER_NFTS_GQL, - // variables: { - // accountId: signer.address, - // }, - // fetchPolicy: 'network-only', - // }), - queryGql$(axios,getSignerNftsQry(signer.address)) + :queryGql$(axios,getSignerNfts(signer.address)) .pipe( map(({ data }) => { const verNfts = data && Array.isArray(data.tokenHolders) @@ -166,9 +87,7 @@ export const selectedSignerNFTs$: Observable = combineLatest([ : null; return verNfts; }), - // indexer fallback, loading directly from sqwid contract - // switchMap((res: VerifiedNft[] | undefined) => getSqwidContractNfts(res, signer as ReefSigner, provider)), map((res: VerifiedNft[] | undefined) => parseTokenHolderArray(res || [])), switchMap((nfts: NFT[]) => (resolveNftImageLinks(nfts, signer.signer, _NFT_IPFS_RESOLVER_FN) as Observable)), ))), - ); + ); \ No newline at end of file diff --git a/src/appState/providerState.ts b/src/appState/providerState.ts index aafda18..8d43b35 100644 --- a/src/appState/providerState.ts +++ b/src/appState/providerState.ts @@ -1,23 +1,11 @@ -import { ReplaySubject, shareReplay } from 'rxjs'; +import { Observable } from 'rxjs'; import { Provider } from '@reef-defi/evm-provider'; +import { + reefState, +} from '@reef-chain/util-lib'; import { Network } from '../state'; -const providerSubj: ReplaySubject = new ReplaySubject(1); -const selectedNetworkSubj: ReplaySubject = new ReplaySubject(); - export const ACTIVE_NETWORK_LS_KEY = 'reef-app-active-network'; -export const currentProvider$ = providerSubj.asObservable().pipe(shareReplay(1)); -export const setCurrentProvider = (provider: Provider): void => providerSubj.next(provider); - -export const currentNetwork$ = selectedNetworkSubj.asObservable(); -export const setCurrentNetwork = (network: Network): void => { - if (network != null) { - try { - localStorage.setItem(ACTIVE_NETWORK_LS_KEY, JSON.stringify(network)); - } catch (e) { - // when cookies disabled localStorage can throw - } - } - selectedNetworkSubj.next(network); -}; -currentNetwork$.subscribe((network) => console.log('SELECTED NETWORK=', network)); +export const currentProvider$ = reefState.selectedProvider$ as Observable; +export const currentNetwork$ = reefState.selectedNetwork$ as Observable; +export const setCurrentNetwork = reefState.setSelectedNetwork; \ No newline at end of file diff --git a/src/appState/tokenState.ts b/src/appState/tokenState.ts index 589e96a..3376363 100644 --- a/src/appState/tokenState.ts +++ b/src/appState/tokenState.ts @@ -13,9 +13,8 @@ import { } from 'rxjs'; import { BigNumber, FixedNumber, utils } from 'ethers'; import { filter } from 'rxjs/operators'; -import { graphql } from '@reef-chain/util-lib'; import { _NFT_IPFS_RESOLVER_FN, combineTokensDistinct, toTokensWithPrice } from './util'; -import { selectedSigner$ } from './accountState'; +import { graphqlRequest, selectedSigner$ } from './accountState'; import { currentNetwork$, currentProvider$ } from './providerState'; import { getIconUrl, getTransferUrl } from '../utils'; import { getReefCoinBalance } from '../rpc'; @@ -26,8 +25,8 @@ import { import { Network, NFT, ReefSigner } from '../state'; import { resolveNftImageLinks } from '../utils/nftUtil'; import { PoolReserves, POOLS_RESERVES_GQL } from '../graphql/pools'; -import { graphqlRequest } from '../graphql/gqlUtils'; import axios, { AxiosInstance } from 'axios'; + // TODO replace with our own from lib and remove const toPlainString = (num: number): string => `${+num}`.replace( /(-?)(\d*)\.?(\d*)e([+-]\d+)/, @@ -46,39 +45,90 @@ export const reefPrice$: Observable = timer(0, 60000).pipe( ); export const validatedTokens$ = of(validatedTokens.tokens as Token[]); -export const { SIGNER_TOKENS_GQL } = graphql; -export const CONTRACT_DATA_GQL = ` - query contract_data_query($addresses: String!) { - verifiedContracts(where: { id_containsInsensitive: $addresses },limit: 1) { - id - contractData - } +const SIGNER_TOKENS_GQL = ` + query tokens_query($accountId: String!) { + tokenHolders( + where: {AND: {nftId_isNull: true, token: {id_isNull: false}, signer: {id_eq: $accountId}}}, + orderBy: balance_DESC, + limit: 320 + ) { + token { + id + } + balance + } + } +`; + +const CONTRACT_DATA_GQL = ` + query contract_data_query($addresses: [String!]!) { + verifiedContracts(where: {id_in: $addresses}, limit:300) { + id + contractData + } } `; -export const getContractDataQry = (addresses:string) => ({ - query: CONTRACT_DATA_GQL, - variables: {addresses} -}); +const TRANSFER_HISTORY_GQL = ` + query query($accountId: String!) { + transfers( + where: { + OR: [ + {from: {id_eq: $accountId}}, + {to: {id_eq: $accountId}} + ] + }, limit: 15, orderBy: timestamp_DESC) + { + timestamp + amount + feeAmount + fromEvmAddress + id + nftId + success + type + toEvmAddress + token{ + id + name + type + contractData + } + event{ + index + } + extrinsic{ + id + index + block{ + id + height + hash + } + } + from{ + id + evmAddress + } + to{ + id + evmAddress + } + } + } +`; // eslint-disable-next-line camelcase const fetchTokensData = ( - axios: AxiosInstance, + // apollo: ApolloClient, + httpClient: AxiosInstance, missingCacheContractDataAddresses: string[], state: { tokens: Token[]; contractData: Token[] }, -): Promise => - graphqlRequest(axios, getContractDataQry(missingCacheContractDataAddresses[0]),true) -// apollo -// .query({ -// query: CONTRACT_DATA_GQL, -// variables: { addresses: missingCacheContractDataAddresses }, -// }) - +): Promise => +graphqlRequest(httpClient,getContractDataQry(missingCacheContractDataAddresses),true) // eslint-disable-next-line camelcase - .then((res) => - { - return res.data.data.verifiedContracts.map( + .then((verContracts) => verContracts.data.data.verifiedContracts.map( // eslint-disable-next-line camelcase (vContract: { id: string; contractData: any }) => ({ address: vContract.id, @@ -87,12 +137,12 @@ const fetchTokensData = ( name: vContract.contractData.name, symbol: vContract.contractData.symbol, } as Token), - )}) + )) .then((newTokens) => newTokens.concat(state.contractData)); // eslint-disable-next-line camelcase // const tokenBalancesWithContractDataCache = (apollo: ApolloClient) => ( -const tokenBalancesWithContractDataCache = (axios:AxiosInstance) => ( +const tokenBalancesWithContractDataCache = (httpClient: any) => ( state: { tokens: Token[]; contractData: Token[] }, // eslint-disable-next-line camelcase tokenBalances: { token_address: string; balance: number }[], @@ -102,9 +152,8 @@ const tokenBalancesWithContractDataCache = (axios:AxiosInstance) => ( (tb) => !state.contractData.some((cd) => cd.address === tb.token_address), ) .map((tb) => tb.token_address); - console.log("anuna===",missingCacheContractDataAddresses) const contractDataPromise = missingCacheContractDataAddresses.length - ? fetchTokensData(axios,missingCacheContractDataAddresses, state) + ? fetchTokensData(httpClient, missingCacheContractDataAddresses, state) : Promise.resolve(state.contractData); return contractDataPromise.then((cData: Token[]) => { @@ -132,39 +181,41 @@ const sortReefTokenFirst = (tokens): Token[] => { return tokens; }; -export const queryGql$ = ( +const queryGql$ = ( client: AxiosInstance, queryObj: { query: string; variables: any } ) => from(graphqlRequest(client as AxiosInstance, queryObj,true).then(res => res.data)); - export const SIGNER_TOKENS_QUERY = ` - query tokens_query($accountId: String!) { - tokenHolders( - where: { - AND: { - nftId_isNull: true - token: { id_isNull: false } - signer: { id_eq: $accountId } - balance_gt: "0" - } - } - orderBy: balance_DESC - limit: 320 - ) { - token { - id - } - balance - } - } -`; - - export const getSignerTokensQuery = (address: string) => { +const getSignerTokensQuery = (accountId: string) => { + return { + query: SIGNER_TOKENS_GQL, + variables: { + accountId + }, + }; + }; +const getTransferHistoryQuery = (accountId: string) => { + return { + query: TRANSFER_HISTORY_GQL, + variables: { + accountId + }, + }; + }; +const getPoolsReserveQry = (tokens: string[]) => { return { - query: SIGNER_TOKENS_QUERY, + query: POOLS_RESERVES_GQL, variables: { - accountId: address, + tokens + }, + }; + }; +const getContractDataQry = (addresses: string[]) => { + return { + query: CONTRACT_DATA_GQL, + variables: { + addresses }, }; }; @@ -175,13 +226,15 @@ export const selectedSignerTokenBalances$: Observable = combineLat ]).pipe( switchMap(([signer, provider]) => (!signer ? [] - : + : queryGql$(axios,getSignerTokensQuery(signer.address)) + // zenToRx( // apollo.subscribe({ // query: SIGNER_TOKENS_GQL, // variables: { accountId: signer.address }, // fetchPolicy: 'network-only', // }), - queryGql$(axios,getSignerTokensQuery(signer.address)).pipe( + // ) + .pipe( map((res: any) => (res.data && res.data.tokenHolders ? res.data.tokenHolders.map((th) => ({ token_address: th.token.id, balance: th.balance })) : undefined)), @@ -228,8 +281,6 @@ export const selectedSignerTokenBalances$: Observable = combineLat })), ); - - export const selectedSignerAddressUpdate$ = selectedSigner$.pipe( filter((v) => !!v), distinctUntilChanged((s1, s2) => s1?.address === s2?.address), @@ -247,22 +298,18 @@ export const pools$: Observable = combineLatest([ shareReplay(1), ); -export const getPoolReservesQry = (tokens:string[]) => ({ - query: POOLS_RESERVES_GQL, - variables: {tokens} -}); - const loadPoolsReserves = async ( tokens: Token[], - httpClient: AxiosInstance, + httpClient:AxiosInstance, ): Promise => { if (tokens.length < 2) return []; - const tokenAddresses = tokens - .map((t) => t.address).filter((address)=>address!=undefined); - console.log(tokenAddresses); - const res = await graphqlRequest(httpClient,getPoolReservesQry(tokenAddresses)); - return res.data.poolsReserves || []; + const tokenAddresses = tokens.map((t) => t.address); + const res = await graphqlRequest(httpClient,getPoolsReserveQry(tokenAddresses)) + // dexClient.query( + // { query: POOLS_RESERVES_GQL, variables: { tokens: tokenAddresses } }, + // ); + return res.data.data.poolsReserves || []; }; export const tokenPrices$: Observable = combineLatest([ @@ -314,7 +361,9 @@ const toTransferToken = (transfer): Token|NFT => (transfer.token.type === Contra contractType: transfer.token.type, } as NFT); -const toTokenTransfers = (resTransferData: any[], signer, network: Network): TokenTransfer[] => resTransferData.map((transferData): TokenTransfer => ({ +const toTokenTransfers = (resTransferData: any[], signer, network: Network): TokenTransfer[] => resTransferData.map((transferData): TokenTransfer => { + return ({ + from: transferData.from.evmAddress || transferData.from.id, to: transferData.to.evmAddress || transferData.to.id, inbound: @@ -322,58 +371,9 @@ const toTokenTransfers = (resTransferData: any[], signer, network: Network): Tok || transferData.to.id === signer.address, timestamp: transferData.timestamp, token: toTransferToken(transferData), - url: getTransferUrl(transferData.extrinsic, network), - extrinsic: { blockId: transferData.extrinsic.block_id, hash: transferData.extrinsic.hash, index: transferData.extrinsic.index }, -})); - -export const TRANSFER_HISTORY_GQL = ` - query query($accountId: String!) { - transfers( - where: { - OR: [{ from: { id_eq: $accountId } }, { to: { id_eq: $accountId } }] - } - limit: 15 - orderBy: timestamp_DESC - ) { - timestamp - amount - feeAmount - fromEvmAddress - id - nftId - success - type - toEvmAddress - token { - id - name - type - contractData - } - extrinsic { - id - block { - id - height - hash - } - } - from { - id - evmAddress - } - to { - id - evmAddress - } - } - } -`; - -export const getTransferHistoryQry = (accountId:string) => ({ - query: TRANSFER_HISTORY_GQL, - variables: {accountId} -}); + url: getTransferUrl(transferData.extrinsic,transferData.event, network), + extrinsic: { blockId: transferData.extrinsic.id, hash: transferData.extrinsic.hash, index: transferData.extrinsic.index }, +})}); export const transferHistory$: Observable< | null @@ -381,13 +381,7 @@ export const transferHistory$: Observable< > = combineLatest([selectedSigner$, currentNetwork$]).pipe( switchMap(([ signer, network]) => (!signer ? [] - : - queryGql$(axios,getTransferHistoryQry(signer.address)) - // apollo.subscribe({ - // query: TRANSFER_HISTORY_GQL, - // variables: { accountId: signer.address }, - // fetchPolicy: 'network-only', - // }), + : queryGql$(axios,getTransferHistoryQuery(signer.address)) .pipe( map((res: any) => { const resHist = res.data && Array.isArray(res.data.transfers) ? res.data.transfers : []; @@ -407,4 +401,4 @@ export const transferHistory$: Observable< ))), startWith(null), shareReplay(1), -); +); \ No newline at end of file diff --git a/src/appState/util.ts b/src/appState/util.ts index 7b97c13..c65b737 100644 --- a/src/appState/util.ts +++ b/src/appState/util.ts @@ -1,30 +1,36 @@ import { ContractInterface } from 'ethers'; +import { Provider } from '@reef-defi/evm-provider'; +import type { Signer as InjectedSigningKey } from '@polkadot/api/types'; +import { AccountJson } from '@reef-defi/extension-base/background/types'; +import type { InjectedAccountWithMeta as InjectedAccountWithMetaReef } from '@reef-defi/extension-inject/types'; +import type { + InjectedAccountWithMeta, +} from '@polkadot/extension-inject/types'; import { ContractType, Token, TokenWithAmount } from '../state/token'; -import { reloadSignersSubj } from './accountState'; +import {reloadSignersSubj, +} from './accountState'; import { UpdateAction } from './updateStateModel'; -import { Network } from '../state'; +import { + Network, ReefSigner, +} from '../state'; import { calculateTokenPrice, TxStatusUpdate } from '../utils'; import { ERC20 } from '../assets/abi/ERC20'; import { ERC721Uri } from '../assets/abi/ERC721Uri'; import { ERC1155Uri } from '../assets/abi/ERC1155Uri'; -import { GQLUrl } from '../graphql'; -import { initProvider } from '../utils/providerUtil'; -import { currentNetwork$, setCurrentNetwork, setCurrentProvider } from './providerState'; import { - apolloDexClientSubj, apolloExplorerClientSubj, GQLUrl, setApolloDexUrls, setApolloExplorerUrls, + axiosDexClientSubj, axiosExplorerClientSubj, GQLUrl, setAxiosDexUrls, setAxiosExplorerUrls, } from '../graphql'; import { ipfsUrlResolverFn } from '../utils/nftUtil'; import { PoolReserves } from '../graphql/pools'; - -// type destroyConnection = ()=>void; +import { AxiosInstance } from 'axios'; type GQLUrlType = 'explorer' | 'dex'; export let _NFT_IPFS_RESOLVER_FN: ipfsUrlResolverFn|undefined; -/* export const setNftIpfsResolverFn = (val?: ipfsUrlResolverFn) => { +export const setNftIpfsResolverFn = (val?: ipfsUrlResolverFn) => { _NFT_IPFS_RESOLVER_FN = val; -}; */ +}; export const combineTokensDistinct = ([tokens1, tokens2]: [ Token[], @@ -104,7 +110,7 @@ export const getGQLUrls = (network: Network): Map => { return gqlUrls; }; -/* export interface State { +export interface State { loading: boolean; signers?: ReefSigner[]; provider?: Provider; @@ -115,89 +121,32 @@ export const getGQLUrls = (network: Network): Map => { export interface StateOptions { network?: Network; signers?: ReefSigner[]; - explorerClient?: ApolloClient; - dexClient?: ApolloClient; + explorerClient?: AxiosInstance; + dexClient?: AxiosInstance; jsonAccounts?:{accounts: AccountJson[] | InjectedAccountWithMeta[] | InjectedAccountWithMetaReef[], injectedSigner: InjectedSigningKey} ipfsHashResolverFn?: ipfsUrlResolverFn; } -export function initApolloClients(selectedNetwork?: Network, explorerClient?: ApolloClient, dexClient?: ApolloClient) { +export function initAxiosClients(selectedNetwork?: Network, explorerClient?: AxiosInstance, dexClient?: AxiosInstance) { if (selectedNetwork) { if (!explorerClient && !dexClient) { const gqlUrls = getGQLUrls(selectedNetwork); + console.log(gqlUrls.get('explorer')!); if (gqlUrls) { if (gqlUrls.get('explorer')) { - setApolloExplorerUrls(gqlUrls.get('explorer')!); + setAxiosExplorerUrls(gqlUrls.get('explorer')!); } if (gqlUrls.get('dex')) { - setApolloDexUrls(gqlUrls.get('dex')!); + setAxiosDexUrls(gqlUrls.get('dex')!); } } } else { if (explorerClient) { - apolloExplorerClientSubj.next(explorerClient); + axiosExplorerClientSubj.next(explorerClient); } if (dexClient) { - apolloDexClientSubj.next(dexClient); + axiosDexClientSubj.next(dexClient); } } } -} - -export const initReefState = ( - { - network, - explorerClient, - dexClient, - signers, - jsonAccounts, - ipfsHashResolverFn, - }: StateOptions, -): destroyConnection => { - const subscription = currentNetwork$.pipe( - switchMap((network) => initProvider(network.rpcUrl) - .then((provider) => ({ - provider, - network, - }))), - scan((state: { provider: Provider }, newVal: { provider: Provider, network }) => { - if (state.provider) { - disconnectProvider(state.provider); - } - return { provider: newVal.provider, network: newVal.network }; - }, {}), - tap((p_n: { provider: Provider, network: Network }) => { - setCurrentProvider(p_n.provider); - }), - tap((p_n) => { - initApolloClients(p_n.network, explorerClient, dexClient); - }), - finalizeWithValue(((p_n) => disconnectProvider(p_n.provider))), - ) - .subscribe({ - error: (e) => { - console.log('initReefState ERR=', e); - }, - }); - setCurrentNetwork(network || availableNetworks.mainnet); - setNftIpfsResolverFn(ipfsHashResolverFn); - if (signers) { - accountsSubj.next(signers || null); - } - if (jsonAccounts) { - accountsJsonSigningKeySubj.next(jsonAccounts.injectedSigner); - accountsJsonSubj.next(jsonAccounts.accounts); - } - return () => subscription.unsubscribe(); -}; - -function finalizeWithValue(callback: (value: T) => void) { - return (source: Observable) => defer(() => { - let lastValue: T; - return source.pipe( - tap((value) => lastValue = value), - finalize(() => callback(lastValue)), - ); - }); -} -*/ +} \ No newline at end of file diff --git a/src/graphql/apollo.ts b/src/graphql/apollo.ts index de5f70b..037200f 100644 --- a/src/graphql/apollo.ts +++ b/src/graphql/apollo.ts @@ -1,13 +1,12 @@ + import { - ApolloClient, ApolloLink, HttpLink, InMemoryCache, split, -} from '@apollo/client'; -import { - distinctUntilChanged, map, merge, Observable, ReplaySubject, shareReplay, + Observable, ReplaySubject, } from 'rxjs'; -import { getMainDefinition } from '@apollo/client/utilities'; +// import { getMainDefinition } from '@apollo/client/utilities'; import { Observable as ZenObservable } from 'zen-observable-ts'; -import { createClient } from 'graphql-ws'; -import { GraphQLWsLink } from '@apollo/client/link/subscriptions'; +// import { createClient } from 'graphql-ws'; +// import { GraphQLWsLink } from '@apollo/client/link/subscriptions'; +import { AxiosInstance } from 'axios'; export interface GQLUrl { http: string; @@ -15,95 +14,57 @@ export interface GQLUrl { } // Explorer -const apolloExplorerUrlsSubj = new ReplaySubject(1); -export const apolloExplorerClientSubj = new ReplaySubject>(1); +export const axiosExplorerClientSubj = new ReplaySubject(1); +export const axiosExplorerUrlsSubj = new ReplaySubject(1); -export const setApolloExplorerUrls = (urls: GQLUrl): void => { - apolloExplorerUrlsSubj.next(urls); +export const setAxiosExplorerUrls = (urls: GQLUrl): void => { + axiosExplorerUrlsSubj.next(urls); }; -const splitExplorerLink$ = apolloExplorerUrlsSubj.pipe( - map((urls: GQLUrl) => { - const httpLink = new HttpLink({ - uri: urls.http, - }); - const wsLink = new GraphQLWsLink(createClient({ - url: urls.ws, - })); - return split( - ({ query }) => { - const definition = getMainDefinition(query); +// const splitExplorerLink$ = apolloExplorerUrlsSubj.pipe( +// map((urls: GQLUrl) => { +// const httpLink = new HttpLink({ +// uri: urls.http, +// }); +// const wsLink = new GraphQLWsLink(createClient({ +// url: urls.ws, +// })); +// return split( +// ({ query }) => { +// const definition = getMainDefinition(query); - return ( - definition.kind === 'OperationDefinition' - && definition.operation === 'subscription' - ); - }, - wsLink, - httpLink, - ); - }), - shareReplay(1), -); -const apolloExplorerLinksClientInstance$: Observable> = splitExplorerLink$.pipe( - map( - (splitLink) => new ApolloClient({ - cache: new InMemoryCache(), - link: ApolloLink.from([splitLink]), - }), - ), - shareReplay(1), -); +// return ( +// definition.kind === 'OperationDefinition' +// && definition.operation === 'subscription' +// ); +// }, +// wsLink, +// httpLink, +// ); +// }), +// shareReplay(1), +// ); +// const apolloExplorerLinksClientInstance$: Observable> = splitExplorerLink$.pipe( +// map( +// (splitLink) => new ApolloClient({ +// cache: new InMemoryCache(), +// link: ApolloLink.from([splitLink]), +// }), +// ), +// shareReplay(1), +// ); -export const apolloExplorerClientInstance$: Observable> = merge(apolloExplorerLinksClientInstance$, apolloExplorerClientSubj).pipe( - distinctUntilChanged(), - shareReplay(1), -); +// export const apolloExplorerClientInstance$: Observable> = merge(apolloExplorerLinksClientInstance$, apolloExplorerClientSubj).pipe( +// distinctUntilChanged(), +// shareReplay(1), +// ); // DEX -const apolloDexUrlsSubj = new ReplaySubject(1); -export const apolloDexClientSubj = new ReplaySubject>(1); +export const axiosDexUrlsSubj = new ReplaySubject(1); +export const axiosDexClientSubj = new ReplaySubject(1); -export const setApolloDexUrls = (urls: GQLUrl): void => { - apolloDexUrlsSubj.next(urls); +export const setAxiosDexUrls = (urls: GQLUrl): void => { + axiosDexUrlsSubj.next(urls); }; -const splitDexLink$ = apolloDexUrlsSubj.pipe( - map((urls: GQLUrl) => { - const httpLink = new HttpLink({ - uri: urls.http, - }); - const wsLink = new GraphQLWsLink(createClient({ - url: urls.ws, - })); - return split( - ({ query }) => { - const definition = getMainDefinition(query); - - return ( - definition.kind === 'OperationDefinition' - && definition.operation === 'subscription' - ); - }, - wsLink, - httpLink, - ); - }), - shareReplay(1), -); -const apolloDexLinksClientInstance$: Observable> = splitDexLink$.pipe( - map( - (splitLink) => new ApolloClient({ - cache: new InMemoryCache(), - link: ApolloLink.from([splitLink]), - }), - ), - shareReplay(1), -); - -export const apolloDexClientInstance$: Observable> = merge(apolloDexLinksClientInstance$, apolloDexClientSubj).pipe( - distinctUntilChanged(), - shareReplay(1), -); - export const zenToRx = (zenObservable: ZenObservable): Observable => new Observable((observer) => zenObservable.subscribe(observer)); diff --git a/src/graphql/evmEvents.ts b/src/graphql/evmEvents.ts index fa61842..79c9ed3 100644 --- a/src/graphql/evmEvents.ts +++ b/src/graphql/evmEvents.ts @@ -1,124 +1,124 @@ -import { ApolloClient, gql, SubscriptionOptions } from '@apollo/client'; -import { utils } from 'ethers'; -import { - from, map, Observable, of, scan, shareReplay, switchMap, -} from 'rxjs'; -import { apolloExplorerClientInstance$, zenToRx } from './apollo'; +// import { ApolloClient, gql, SubscriptionOptions } from '@apollo/client'; +// import { utils } from 'ethers'; +// import { +// from, map, Observable, of, scan, shareReplay, switchMap, +// } from 'rxjs'; +// import { zenToRx } from './apollo'; -const getGqlContractEventsQuery = ( - contractAddress: string, - methodSignature?: string | null, - fromBlockId?: number, - toBlockId?: number, -): SubscriptionOptions => { - const EVM_EVENT_GQL = gql` - query evmEvent( - $address: String_comparison_exp! - $blockId: bigint_comparison_exp! - $topic0: String_comparison_exp - ) { - evm_event( - order_by: [ - { block_id: desc } - { extrinsic_index: desc } - { event_index: desc } - ] - where: { - _and: [ - { contract_address: $address } - { topic_0: $topic0 } - { method: { _eq: "Log" } } - { block_id: $blockId } - ] - } - ) { - contract_address - data_parsed - data_raw - topic_0 - topic_1 - topic_2 - topic_3 - block_id - extrinsic_index - event_index - } - } - `; - return { - query: EVM_EVENT_GQL, - variables: { - address: { _eq: contractAddress }, - topic0: methodSignature - ? { _eq: utils.keccak256(utils.toUtf8Bytes(methodSignature)) } - : {}, - blockId: toBlockId ? { _gte: fromBlockId, _lte: toBlockId } : { _eq: fromBlockId }, - }, - fetchPolicy: 'network-only', - }; -}; +// const getGqlContractEventsQuery = ( +// contractAddress: string, +// methodSignature?: string | null, +// fromBlockId?: number, +// toBlockId?: number, +// ): SubscriptionOptions => { +// const EVM_EVENT_GQL = gql` +// query evmEvent( +// $address: String_comparison_exp! +// $blockId: bigint_comparison_exp! +// $topic0: String_comparison_exp +// ) { +// evm_event( +// order_by: [ +// { block_id: desc } +// { extrinsic_index: desc } +// { event_index: desc } +// ] +// where: { +// _and: [ +// { contract_address: $address } +// { topic_0: $topic0 } +// { method: { _eq: "Log" } } +// { block_id: $blockId } +// ] +// } +// ) { +// contract_address +// data_parsed +// data_raw +// topic_0 +// topic_1 +// topic_2 +// topic_3 +// block_id +// extrinsic_index +// event_index +// } +// } +// `; +// return { +// query: EVM_EVENT_GQL, +// variables: { +// address: { _eq: contractAddress }, +// topic0: methodSignature +// ? { _eq: utils.keccak256(utils.toUtf8Bytes(methodSignature)) } +// : {}, +// blockId: toBlockId ? { _gte: fromBlockId, _lte: toBlockId } : { _eq: fromBlockId }, +// }, +// fetchPolicy: 'network-only', +// }; +// }; -const getGqlLastFinalizedBlock = (): SubscriptionOptions => { - const FINALISED_BLOCK_GQL = gql` - subscription finalisedBlock { - block(order_by: {id: desc}, limit: 1, where: {finalized: {_eq: true}}) { - id - } - } - `; - return { - query: FINALISED_BLOCK_GQL, - variables: {}, - fetchPolicy: 'network-only', - }; -}; +// const getGqlLastFinalizedBlock = (): SubscriptionOptions => { +// const FINALISED_BLOCK_GQL = gql` +// subscription finalisedBlock { +// block(order_by: {id: desc}, limit: 1, where: {finalized: {_eq: true}}) { +// id +// } +// } +// `; +// return { +// query: FINALISED_BLOCK_GQL, +// variables: {}, +// fetchPolicy: 'network-only', +// }; +// }; -export function getEvmEvents$(contractAddress: string, methodSignature?: string, fromBlockId?: number, toBlockId?: number): Observable<{ fromBlockId:number, toBlockId:number, evmEvents:any[] }|null> { - if (!contractAddress) { - console.warn('getEvmEvents$ expects contractAddress'); - return of(null); - } - if (!fromBlockId) { - return apolloExplorerClientInstance$.pipe( - switchMap((apolloClient: ApolloClient) => zenToRx(apolloClient.subscribe(getGqlLastFinalizedBlock())).pipe( - scan((state, res: any) => { - const block = res?.data?.block?.length ? res.data.block[0] : null; - if (!block) { - console.warn('getEvmEvents$ NO FINALISED BLOCK RESULT', res); - return state; - } - const newBlockId = block.id; - const diff = state.prevBlockId ? newBlockId - state.prevBlockId : 1; - let fromBlockId = newBlockId; - let toBlockId; - if (diff > 1 && state.prevBlockId) { - toBlockId = newBlockId; - fromBlockId = state.prevBlockId + 1; - } - return { prevBlockId: newBlockId, fromBlockId, toBlockId }; - }, { prevBlockId: undefined, fromBlockId: undefined, toBlockId: undefined }), - switchMap((res: { fromBlockId: number, toBlockId: number | undefined }) => from(apolloClient?.query( - getGqlContractEventsQuery(contractAddress, methodSignature, res.fromBlockId, res.toBlockId), - )).pipe( - map((events) => ({ - fromBlockId: res.fromBlockId, - toBlockId: res.toBlockId || res.fromBlockId, - evmEvents: events.data.evm_event, - })), - )), - ) as Observable), - shareReplay(1), - ); - } - return apolloExplorerClientInstance$.pipe( - switchMap((apolloClient: ApolloClient) => from(apolloClient?.query( - getGqlContractEventsQuery(contractAddress, methodSignature, fromBlockId, toBlockId), - ))), - map((events) => ({ - fromBlockId, - toBlockId: toBlockId || fromBlockId, - evmEvents: events.data.evm_event, - })), - shareReplay(1), - ); -} +// export function getEvmEvents$(contractAddress: string, methodSignature?: string, fromBlockId?: number, toBlockId?: number): Observable<{ fromBlockId:number, toBlockId:number, evmEvents:any[] }|null> { +// if (!contractAddress) { +// console.warn('getEvmEvents$ expects contractAddress'); +// return of(null); +// } +// if (!fromBlockId) { +// return apolloExplorerClientInstance$.pipe( +// switchMap((apolloClient: ApolloClient) => zenToRx(apolloClient.subscribe(getGqlLastFinalizedBlock())).pipe( +// scan((state, res: any) => { +// const block = res?.data?.block?.length ? res.data.block[0] : null; +// if (!block) { +// console.warn('getEvmEvents$ NO FINALISED BLOCK RESULT', res); +// return state; +// } +// const newBlockId = block.id; +// const diff = state.prevBlockId ? newBlockId - state.prevBlockId : 1; +// let fromBlockId = newBlockId; +// let toBlockId; +// if (diff > 1 && state.prevBlockId) { +// toBlockId = newBlockId; +// fromBlockId = state.prevBlockId + 1; +// } +// return { prevBlockId: newBlockId, fromBlockId, toBlockId }; +// }, { prevBlockId: undefined, fromBlockId: undefined, toBlockId: undefined }), +// switchMap((res: { fromBlockId: number, toBlockId: number | undefined }) => from(apolloClient?.query( +// getGqlContractEventsQuery(contractAddress, methodSignature, res.fromBlockId, res.toBlockId), +// )).pipe( +// map((events) => ({ +// fromBlockId: res.fromBlockId, +// toBlockId: res.toBlockId || res.fromBlockId, +// evmEvents: events.data.evm_event, +// })), +// )), +// ) as Observable), +// shareReplay(1), +// ); +// } +// return apolloExplorerClientInstance$.pipe( +// switchMap((apolloClient: ApolloClient) => from(apolloClient?.query( +// getGqlContractEventsQuery(contractAddress, methodSignature, fromBlockId, toBlockId), +// ))), +// map((events) => ({ +// fromBlockId, +// toBlockId: toBlockId || fromBlockId, +// evmEvents: events.data.evm_event, +// })), +// shareReplay(1), +// ); +// } diff --git a/src/graphql/index.ts b/src/graphql/index.ts index e559057..6b65399 100644 --- a/src/graphql/index.ts +++ b/src/graphql/index.ts @@ -1,3 +1,3 @@ export * from './apollo'; export * from './gql'; -export * from './evmEvents'; +// export * from './evmEvents'; diff --git a/src/graphql/pools.ts b/src/graphql/pools.ts index c8d77ec..6210084 100644 --- a/src/graphql/pools.ts +++ b/src/graphql/pools.ts @@ -1,4 +1,3 @@ -import { gql } from '@apollo/client'; import { BaseFeeData, BaseReservedData, BaseVolumeData, FeeData, PriceData, ReservedData, VolumeData, } from '../state'; @@ -486,7 +485,7 @@ export const POOL_TRANSACTION_COUNT_GQL = ` // Charts queries & subscriptions type Time = 'Day' | 'Hour' | 'Minute'; -const tvlQuery = (time: Time):string => ` +const tvlQuery = (time: Time): string => ` query poolSupply($address: String!, $fromTime: String!) { poolTimeSupplies( address: $address @@ -706,4 +705,4 @@ export const USER_POOL_SUPPLY = ` userSupply } } -`; +`; \ No newline at end of file diff --git a/src/hooks/poolHooks.ts b/src/hooks/poolHooks.ts index 6d4ff4d..1586cd4 100644 --- a/src/hooks/poolHooks.ts +++ b/src/hooks/poolHooks.ts @@ -1,16 +1,18 @@ -import axios, { AxiosInstance, AxiosResponse } from 'axios'; -import { graphql, network } from '@reef-chain/util-lib'; -import { useEffect, useState } from 'react'; import { - PoolBasicTransactionVar, - POOL_CURRENT_RESERVES_GQL, POOL_DAY_FEE_QUERY_GQL, POOL_DAY_TVL_GQL, + PoolBasicTransactionVar, PoolDayFeeQuery, PoolDayVolumeQuery, PoolFeeQuery, + PoolQuery, PoolReservesQuery, PoolSupplyQuery, PoolTransactionCountQuery, + PoolTransactionQuery, PoolDayTvlQuery, PoolVolumeAggregateQuery, + POOL_CURRENT_RESERVES_GQL, POOL_DAY_FEE_QUERY_GQL, POOL_DAY_TVL_GQL, POOL_DAY_VOLUME_GQL, POOL_FEES_GQL, POOL_GQL, POOL_SUPPLY_GQL, POOL_TRANSACTIONS_GQL, POOL_TRANSACTION_COUNT_GQL, - POOL_VOLUME_AGGREGATE_GQL, TransactionTypes, PoolVolumeAggregateQuery + POOL_VOLUME_AGGREGATE_GQL, TransactionTypes, } from '../graphql/pools'; -import { graphqlRequest } from '../graphql/gqlUtils'; -import { useObservableState } from './useObservableState'; +import useInterval from './userInterval'; +import { POLL_INTERVAL } from '../utils'; +import axios, { AxiosInstance } from 'axios'; +import { useEffect, useState } from 'react'; +import { graphqlRequest } from '../appState/accountState'; -export const getPoolVolumeAggregateQuery = (address: string, +const getPoolVolumeAggregateQuery = (address: string, fromTime: string, toTime: string) => ({ query: POOL_VOLUME_AGGREGATE_GQL, @@ -21,11 +23,47 @@ export const getPoolVolumeAggregateQuery = (address: string, }, }); -export const getPoolSupplyQuery = (address: string) => ({ +// Intermediate query hooks +export const useDayVolume = ( + address: string, + fromTime: string, + toTime: string, +): PoolVolumeAggregateQuery => { + const [data, setData] = useState() + const poolCurrReservesQry = getPoolVolumeAggregateQuery(address,fromTime,toTime); + useEffect(()=>{ + const handleResponse = async()=>{ + const response = await graphqlRequest(axios,poolCurrReservesQry); + setData(response.data); + } + handleResponse(); + },[]); + + return data as any; +} + +const getPoolSupplyQuery = (address: string) => ({ query: POOL_SUPPLY_GQL, variables: { address }, }); +export const useCurrentPoolSupply = ( + address: string, +): PoolSupplyQuery =>{ + const [data, setData] = useState() + const poolCurrReservesQry = getPoolSupplyQuery(address); + useEffect(()=>{ + const handleResponse = async()=>{ + const response = await graphqlRequest(axios,poolCurrReservesQry); + setData(response.data); + } + handleResponse(); + },[]); + + return data as any; + +} + export const getPoolFeesQuery = (address: string, fromTime: string) => ({ query: POOL_FEES_GQL, variables: { @@ -34,65 +72,58 @@ export const getPoolFeesQuery = (address: string, fromTime: string) => ({ }, }); -export const getPoolQuery = (address: string) => ({ - query: POOL_GQL, - variables: { address }, -}); - -export const getCurrentReservesQuery = (address: string) => ({ - query: POOL_CURRENT_RESERVES_GQL, - variables: { address }, -}); - -// Intermediate query hooks -export const useDayVolume = ( +export const useDayFee = ( address: string, fromTime: string, - toTime: string, -): PoolVolumeAggregateQuery => { - const [res,setRes] = useState(); - useEffect(() => { +): PoolFeeQuery =>{ + + const [data, setData] = useState() + const poolCurrReservesQry = getPoolFeesQuery(address,fromTime); + useEffect(()=>{ const handleResponse = async()=>{ - const poolVolAggrQry = getPoolVolumeAggregateQuery(address, fromTime, toTime); - const response = await graphqlRequest(axios, poolVolAggrQry); - setRes(response.data); + const response = await graphqlRequest(axios,poolCurrReservesQry); + setData(response.data); } handleResponse(); - }, []) - - return res!; -}; + },[]); -export const useCurrentPoolSupply = async ( - address: string, -): Promise => { - const queryObj = getPoolSupplyQuery(address); - const response = await graphqlRequest(axios, queryObj); - return response.data; -}; + return data as any; +} -export const useDayFee = async ( - address: string, - fromTime: string, -): Promise => { - const queryObj = getPoolFeesQuery(address, fromTime); - const response = await graphqlRequest(axios, queryObj); - return response.data; -}; +const getPoolQuery = (address: string) => ({ + query: POOL_GQL, + variables: { address }, +}); -export const usePoolQuery = async (address: string): Promise => { - const queryObj = getPoolQuery(address); - const response = await graphqlRequest(axios, queryObj); - return response.data; -}; +export const usePoolQuery = (address: string): PoolQuery => +{ + const [data, setData] = useState() + const poolQry = getPoolQuery(address); + useEffect(()=>{ + const handleResponse = async()=>{ + const response = await graphqlRequest(axios,poolQry); + setData(response.data); + } + handleResponse(); + },[]); -export const useCurrentPoolReserve = async ( + return data as any; +} +export const useCurrentPoolReserve = ( address: string, -): Promise => { - const queryObj = getCurrentReservesQuery(address); - const response = await graphqlRequest(axios, queryObj); - return response.data; -}; +): PoolReservesQuery =>{ + const [data, setData] = useState() + const poolCurrReservesQry = getPoolCurrentReservesQry(address); + useEffect(()=>{ + const handleResponse = async()=>{ + const response = await graphqlRequest(axios,poolCurrReservesQry); + setData(response.data); + } + handleResponse(); + },[]); + + return data as any; +} const resolveTransactionVariables = ( search: string | undefined, @@ -102,34 +133,17 @@ const resolveTransactionVariables = ( type: type === 'All' ? ['Swap', 'Mint', 'Burn'] : [type], }); -export const getPoolTransactionCountQuery = (address: string | undefined, type: TransactionTypes) => ({ +const getPoolTransactionCountQry =(address: string | undefined, type: TransactionTypes) => ({ query: POOL_TRANSACTION_COUNT_GQL, variables: resolveTransactionVariables(address, type), }); -export const getPoolDayTvlQuery = (address: string, fromTime: string) => ({ - query: POOL_DAY_TVL_GQL, - variables: { - address, - fromTime, - }, -}); -export const getPoolDayVolumeQuery = (address: string, fromTime: string) => ({ - query: POOL_DAY_VOLUME_GQL, - variables: { - address, - fromTime, - }, -}); -export const getPoolDayFeeQuery = (address: string, fromTime: string) => ({ - query: POOL_DAY_FEE_QUERY_GQL, - variables: { - address, - fromTime, - }, +const getPoolCurrentReservesQry =(address: string) => ({ + query: POOL_CURRENT_RESERVES_GQL, + variables: {address}, }); -export const getPoolTransactionQuery = (address: string | undefined, type: TransactionTypes, limit: number, pageIndex: number): {query: string, variables: any} => ({ +const getPoolTransactionQry = (address: string | undefined, type: TransactionTypes, limit: number, pageIndex: number): {query: string, variables: any} => ({ query: POOL_TRANSACTIONS_GQL, variables: { ...resolveTransactionVariables(address, type), @@ -138,34 +152,26 @@ export const getPoolTransactionQuery = (address: string | undefined, type: Trans }, }); + export const usePoolTransactionCountSubscription = ( address: string | undefined, type: TransactionTypes, httpClient: AxiosInstance, -): any => { +): {data:PoolTransactionCountQuery,loading:boolean} => { + const [data,setData]= useState(); + const [loading,setLoading] = useState(true); if (httpClient === undefined) { return [undefined, true] as any; } - - const [isLoading, setLoading] = useState(true); - const [transactionsCount, setTransactionsCount] = useState([]); - - const contractEvents = useObservableState(network.getLatestBlockContractEvents$(address ? [address] : undefined)); - - useEffect(() => { + const queryObj = getPoolTransactionCountQry(address, type); + useInterval(async() => { setLoading(true); - const queryObj = getPoolTransactionCountQuery(address, type); - graphqlRequest(httpClient, queryObj) - .then((response) => { - setTransactionsCount(response.data); - setLoading(false); - }); - }, [contractEvents]); - - return { - loading: isLoading, - data: transactionsCount, - }; + const response = await graphqlRequest(httpClient, queryObj); + setData(response.data); + setLoading(false); + }, POLL_INTERVAL); + + return {data, loading} as any; }; export const usePoolTransactionSubscription = ( @@ -174,51 +180,94 @@ export const usePoolTransactionSubscription = ( pageIndex = 0, limit = 10, httpClient: AxiosInstance, -): any => { - const [isLoading, setLoading] = useState(true); - const [transactions, setTransactions] = useState([]); - - const contractEvents = useObservableState(network.getLatestBlockContractEvents$(address ? [address] : undefined)); +): {data:PoolTransactionQuery,loading:boolean} => { + const [data,setData]= useState(); + const [loading,setLoading] = useState(true); + if (httpClient === undefined) { + return [undefined, true] as any; + } + const queryObj = getPoolTransactionQry(address, type, limit, pageIndex); - useEffect(() => { + useInterval(async() => { setLoading(true); - const queryObj = getPoolTransactionQuery(address, type, limit, pageIndex); - graphqlRequest(httpClient, queryObj) - .then((response) => { - setTransactions(response.data); - setLoading(false); - }); - }, [contractEvents]); - - return { - loading: isLoading, - data: transactions, - }; -}; + const response = await graphqlRequest(httpClient, queryObj); + setData(response.data); + setLoading(false); + }, POLL_INTERVAL); + + return {data, loading} as any; + } -export const useDayTvl = async ( + const getPoolDayTvlQuery = (address: string, fromTime: string) => ({ + query: POOL_DAY_TVL_GQL, + variables: { + address, + fromTime, + }, + }); + +export const useDayTvl = ( address: string, fromTime: number, -): Promise => { - const queryObj = getPoolDayTvlQuery(address, new Date(fromTime).toISOString()); - const response = await graphqlRequest(axios, queryObj); - return graphql.queryGql$(response.data); -}; +): PoolDayTvlQuery => { + const [data, setData] = useState() + const poolCurrReservesQry = getPoolDayTvlQuery(address, new Date(fromTime).toISOString()); + useEffect(()=>{ + const handleResponse = async()=>{ + const response = await graphqlRequest(axios,poolCurrReservesQry); + setData(response.data); + } + handleResponse(); + },[]); + + return data as any; +} + +const getPoolDayVolumeQuery = (address: string, fromTime: string) => ({ + query: POOL_DAY_VOLUME_GQL, + variables: { + address, + fromTime, + }, +}); -export const useDayPoolVolume = async ( +export const useDayPoolVolume = ( address: string, fromTime: number, -): Promise => { - const queryObj = getPoolDayVolumeQuery(address, new Date(fromTime).toISOString()); - const response = await graphqlRequest(axios, queryObj); - return graphql.queryGql$(response.data); -}; +): PoolDayVolumeQuery => { + const [data, setData] = useState() + const poolCurrReservesQry = getPoolDayVolumeQuery(address, new Date(fromTime).toISOString()); + useEffect(()=>{ + const handleResponse = async()=>{ + const response = await graphqlRequest(axios,poolCurrReservesQry); + setData(response.data); + } + handleResponse(); + },[]); -export const useDayPoolFee = async ( + return data as any; +} + +const getPoolDayFeeQuery = (address: string, fromTime: string) => ({ + query: POOL_DAY_FEE_QUERY_GQL, + variables: { + address, + fromTime, + }, +}); + +export const useDayPoolFee = ( address: string, fromTime: number, -): Promise => { - const queryObj = getPoolDayFeeQuery(address, new Date(fromTime).toISOString()); - const response = await graphqlRequest(axios, queryObj); - return graphql.queryGql$(response.data); -}; +): PoolDayFeeQuery => {const [data, setData] = useState() + const poolCurrReservesQry = getPoolDayFeeQuery(address, new Date(fromTime).toISOString()); + useEffect(()=>{ + const handleResponse = async()=>{ + const response = await graphqlRequest(axios,poolCurrReservesQry); + setData(response.data); + } + handleResponse(); + },[]); + + return data as any; +} \ No newline at end of file diff --git a/src/hooks/useAllPools.ts b/src/hooks/useAllPools.ts index 95c9e74..ce461ac 100644 --- a/src/hooks/useAllPools.ts +++ b/src/hooks/useAllPools.ts @@ -4,7 +4,7 @@ import { POLL_INTERVAL, getIconUrl } from '../utils'; import { useState } from 'react'; import useInterval from './userInterval'; import { PoolWithReserves } from '../state'; -import { graphqlRequest } from '../graphql/gqlUtils'; +import { graphqlRequest } from '../appState/accountState'; export const getAllPoolsQuery = () => ({ query: ALL_POOLS, @@ -25,4 +25,4 @@ export const useAllPools = (httpClient: AxiosInstance): PoolWithReserves[] => { }, POLL_INTERVAL); return allPools; -}; +}; \ No newline at end of file diff --git a/src/hooks/useInitReefState.ts b/src/hooks/useInitReefState.ts index 3ac4aec..15fbe54 100644 --- a/src/hooks/useInitReefState.ts +++ b/src/hooks/useInitReefState.ts @@ -1,57 +1,133 @@ +import { + reefState, +} from '@reef-chain/util-lib'; import { useEffect, useState } from 'react'; +import { useObservableState } from './useObservableState'; +import { availableNetworks, Network, ReefSigner } from '../state'; +import { accountsSubj, setCurrentAddress } from '../appState/accountState'; +import type { Signer as InjectedSigner } from '@polkadot/api/types'; import { - initReefState, - ipfsUrlResolverFn, - Network, - providerConnState$, - selectedNetworkProvider$, -} from '@reef-chain/util-lib/dist/reefState'; -import { map } from 'rxjs'; -import { Provider } from '@reef-defi/evm-provider'; -import { InjectedExtension } from '@reef-defi/extension-inject/types'; + _NFT_IPFS_RESOLVER_FN, initAxiosClients, setNftIpfsResolverFn, State, StateOptions, +} from '../appState/util'; +import { ACTIVE_NETWORK_LS_KEY } from '../appState/providerState'; import { useInjectExtension } from './useInjectExtension'; -import { useObservableState } from './useObservableState'; +import { Provider } from '@reef-defi/evm-provider'; +import { accountToSigner } from '../rpc'; +import { useAsyncEffect } from './useAsyncEffect'; -export interface State { - loading: boolean; - provider?: Provider; - network?: Network; - error?: any; // TODO! - extension?: InjectedExtension; +const getNetworkFallback = (): Network => { + let storedNetwork; + try { + storedNetwork = localStorage.getItem(ACTIVE_NETWORK_LS_KEY); + storedNetwork = JSON.parse(storedNetwork); + storedNetwork = availableNetworks[storedNetwork.name]; + } catch (e) { + // when cookies disabled localStorage can throw + } + return storedNetwork != null ? storedNetwork : availableNetworks.mainnet; +}; + +export const getReefSignersArray = ( + extensionAccounts: any, + provider: Provider, +): [ReefSigner[],boolean] => { + const [accounts, setAccounts] = useState([]); + const [isLoading, setIsLoading] = useState(true); +useAsyncEffect(async()=>{ + setIsLoading(true); + const accountPromisses = extensionAccounts.flatMap( + ({ accounts, name, sig }) => accounts.map((account) => accountToSigner(account, provider, sig, name)), + ); + let _accounts = await Promise.all(accountPromisses); + setAccounts(_accounts); + try { + setCurrentAddress(_accounts[0].address); + } catch (error) { + console.log("no accounts"); + } + setIsLoading(false); +},[provider]); + return [accounts,isLoading]; +}; + +export const reefAccountToReefSigner = (accountsFromUtilLib:any,injectedSigner:InjectedSigner)=>{ + const resultObj = { + name:'reef', + sig:injectedSigner, + }; + let reefSigners = []; + for(let i = 0;i { + const { + explorerClient, dexClient, ipfsHashResolverFn, + } = options; const [accounts, extension, loadingExtension, errExtension] = useInjectExtension(applicationDisplayName); - const { network: selectedNetwork, provider } = useObservableState(selectedNetworkProvider$); - const isProviderLoading = useObservableState(providerConnState$.pipe(map((v) => !v.isConnected)), false); + const jsonAccounts = { accounts, injectedSigner: extension?.signer }; + const selectedNetwork: Network|undefined = useObservableState(reefState.selectedNetwork$); + const provider = useObservableState(reefState.selectedProvider$) as Provider|undefined; + const [loading, setLoading] = useState(true); + + const x = useObservableState(reefState.selectedTransactionHistory$); + console.log("x===",x); - const [loading, setLoading] = useState(false); + console.log("reefstate===",reefState); useEffect(() => { + const network = getNetworkFallback(); + if (!accounts || !accounts.length || !extension) { return; } const jsonAccounts = { accounts, injectedSigner: extension?.signer }; - initReefState({ - network: options.network, - jsonAccounts, - ipfsHashResolverFn: options.ipfsHashResolverFn, - }); - }, [accounts, extension, options]); + reefState.initReefState({ + network, + jsonAccounts, + ipfsHashResolverFn, + }); + }, [accounts, extension]); + + useEffect(() => { + setNftIpfsResolverFn(ipfsHashResolverFn); + }, [ipfsHashResolverFn]); + + useEffect(() => { + initAxiosClients(selectedNetwork, explorerClient, dexClient); + }, [selectedNetwork, explorerClient, dexClient]); + + let accountsFromUtilLib: any= useObservableState(reefState.accounts$); + + const [loadedReefSigners,isLoadingReefSigners] = getReefSignersArray([reefAccountToReefSigner(accountsFromUtilLib,jsonAccounts.injectedSigner!)],provider!); + useEffect(() => { + accountsSubj.next(loadedReefSigners || []); + }, [loadedReefSigners]); useEffect(() => { - setLoading(loadingExtension && isProviderLoading); - }, [isProviderLoading, loadingExtension]); + setLoading(isLoadingReefSigners||loadingExtension||provider==undefined); + + }, [isLoadingReefSigners,loadedReefSigners,loadingExtension,provider]); return { - error: errExtension, + error:errExtension, loading, provider, network: selectedNetwork, - extension, + signers: loadedReefSigners, }; -}; +}; \ No newline at end of file diff --git a/src/hooks/useInjectExtension.ts b/src/hooks/useInjectExtension.ts index 4753f23..b2605b8 100644 --- a/src/hooks/useInjectExtension.ts +++ b/src/hooks/useInjectExtension.ts @@ -39,13 +39,20 @@ export const useInjectExtension = ( ] => { const [accountsVal, setAccountsVal] = useState([]); const [extensionVal, setExtensionVal] = useState(); + const [isReefInjected, setIsReefInjected] = useState(false); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState<{ message: string; code?: number; url?: string }>(); + let extensions: InjectedExtension[]; + + document.addEventListener('reef-injected', async()=>{ + if(!isReefInjected)setIsReefInjected(true); + }); useAsyncEffect(async () => { try { + setError(undefined); setIsLoading(true); - const extensions: InjectedExtension[] = await web3Enable(appDisplayName); + extensions= await web3Enable(appDisplayName); const reefExt = extensions.find((ext) => ext.name === REEF_EXTENSION_IDENT); if (!reefExt) { const installExtensionMessage = getInstallExtensionMessage(); @@ -89,7 +96,7 @@ export const useInjectExtension = ( } finally { setIsLoading(false); } - }, []); + }, [isReefInjected]); /* useEffect(() => { if (!accountsVal.length) { diff --git a/src/hooks/useLoadPool.ts b/src/hooks/useLoadPool.ts index 1b0123c..13c015f 100644 --- a/src/hooks/useLoadPool.ts +++ b/src/hooks/useLoadPool.ts @@ -4,7 +4,7 @@ import { Pool, Token } from '..'; import { USER_POOL_SUPPLY } from '../graphql/pools'; import { EMPTY_ADDRESS, ensure } from '../utils'; import { AxiosInstance } from 'axios'; -import { graphqlRequest } from '../graphql/gqlUtils'; +import { graphqlRequest } from '../appState/accountState'; type LoadingPool = Pool | undefined; @@ -74,4 +74,4 @@ export const useLoadPool = ( }, [token1.address, token2.address, token1.balance, token2.balance]); return [pool, isLoading]; -}; +}; \ No newline at end of file diff --git a/src/hooks/useLoadPools.ts b/src/hooks/useLoadPools.ts index 8ac3a0b..e1448f3 100644 --- a/src/hooks/useLoadPools.ts +++ b/src/hooks/useLoadPools.ts @@ -54,4 +54,4 @@ export const useLoadPools = ( }, [tokens, httpClient, userAddress]); return [pools, isLoading]; -}; +}; \ No newline at end of file diff --git a/src/hooks/useLoadSigners.ts b/src/hooks/useLoadSigners.ts index 7b59a16..0d85abd 100644 --- a/src/hooks/useLoadSigners.ts +++ b/src/hooks/useLoadSigners.ts @@ -80,7 +80,7 @@ export const useLoadSigners = ( setIsLoading(false); return; } - + const sgnrs = await getExtensionSigners(extensions, provider); // TODO signers objects are large cause of provider object inside. Find a way to overcome this problem. setSignersVal(sgnrs); diff --git a/src/hooks/usePoolData.ts b/src/hooks/usePoolData.ts index 3ff653b..22111c4 100644 --- a/src/hooks/usePoolData.ts +++ b/src/hooks/usePoolData.ts @@ -1,10 +1,10 @@ import BigNumber from 'bignumber.js'; import { useEffect, useMemo, useState } from 'react'; -import { poolDataQuery } from '../graphql/pools'; +import { PoolDataQuery, poolDataQuery } from '../graphql/pools'; import { BaseCandlestickData, BaseVolumeData, CandlestickData } from '../state'; import { calcTimeRange, timeDataToMs, truncateDate } from './useFromTime'; -import { AxiosInstance, AxiosResponse } from 'axios'; -import { graphqlRequest } from '../graphql/gqlUtils'; +import { AxiosInstance } from 'axios'; +import { graphqlRequest } from '../appState/accountState'; interface Time { time: Date; @@ -173,21 +173,22 @@ interface UsePoolData { timeData: TimeData; } -export const getPoolQuery = (time:TimeUnit,address:string,fromTime:string) => ({ - query: poolDataQuery(time), - variables: { address,fromTime }, +const getPoolDataQry = (timeData: any,address:string,fromTime:any) => ({ + query: poolDataQuery(timeData.timeUnit), + variables: { + address, + fromTime + }, }); export const usePoolData = ({ address, decimals1, decimals2, price1, price2, timeData = { timeUnit: 'Day', timeSpan: 31 }, -}: UsePoolData, httpClient: AxiosInstance): UsePoolDataOutput => { +}: UsePoolData, httpClient:AxiosInstance): UsePoolDataOutput => { const { fromTime, toTime } = calcTimeRange(timeData.timeUnit, timeData.timeSpan); - const [loading,setLoading] = useState(true); // ********************* Get pool data from GraphQL ************************************** - const poolQry = getPoolQuery(timeData.timeUnit, address,fromTime.toISOString()); - - + const [data, setData] = useState(); + const [loading,setLoading] = useState(true); // const { data, loading, refetch } = useQuery( // poolDataQuery(timeData.timeUnit), // { @@ -198,17 +199,15 @@ export const usePoolData = ({ // }, // }, // ); - let response:AxiosResponse; - let data:any; - + const queryObj = getPoolDataQry(timeData,address, fromTime.toISOString()); useEffect(() => { - setLoading(true); - const refetch = async()=>{ - response = await graphqlRequest(httpClient, poolQry); - data = response.data; + const handleResp = async()=>{ + setLoading(true); + const response = await graphqlRequest(httpClient, queryObj); + setData(response.data); setLoading(false); } - refetch(); + handleResp(); }, [timeData]); const processed = useMemo((): PoolDataTime => { @@ -366,4 +365,4 @@ export const usePoolData = ({ }, [data, price1, price2, decimals1, decimals2]); return [processed, loading]; -}; +}; \ No newline at end of file diff --git a/src/hooks/usePoolLists.ts b/src/hooks/usePoolLists.ts index 30a5436..9e5e688 100644 --- a/src/hooks/usePoolLists.ts +++ b/src/hooks/usePoolLists.ts @@ -1,12 +1,12 @@ import BigNumber from 'bignumber.js'; import { useEffect, useMemo, useState } from 'react'; import { - AllPoolsListCountQuery, AllPoolsListQuery, ALL_POOLS_LIST, ALL_POOLS_LIST_COUNT, PoolListItem,PoolsListVar, UserPoolsListCountQuery, UserPoolsListQuery, USER_POOLS_LIST, USER_POOLS_LIST_COUNT, + AllPoolsListCountQuery, AllPoolsListQuery, ALL_POOLS_LIST, ALL_POOLS_LIST_COUNT, PoolListItem, PoolsListVar, UserPoolsListCountQuery, UserPoolsListQuery, USER_POOLS_LIST, USER_POOLS_LIST_COUNT, } from '../graphql/pools'; import { TokenPrices } from '../state'; import { getIconUrl } from '../utils'; -import axios, { AxiosInstance } from 'axios'; -import { graphqlRequest } from '../graphql/gqlUtils'; +import { AxiosInstance } from 'axios'; +import { graphqlRequest } from '../appState/accountState'; interface PoolItem { address: string; @@ -26,7 +26,7 @@ interface PoolItem { interface UsePoolsList extends PoolsListVar { tokenPrices: TokenPrices; - httpClient:AxiosInstance; + httpClient: AxiosInstance; queryType: 'All' | 'User'; } @@ -97,40 +97,25 @@ const calculateUserLiquidity = ( return res.gt(0) ? res.toFormat(2) : undefined; }; -export const getUserPoolList = ( queryType:string,limit:number, offset:number, search:string, signerAddress:string) => ({ - query: queryType === 'User' ?USER_POOLS_LIST:ALL_POOLS_LIST, - variables: { limit, offset, search, signerAddress }, +const getUserPoolList = (queryType:any,limit:any, offset:any, search:any, signerAddress:any,) => ({ + query: queryType === 'User' ? USER_POOLS_LIST : ALL_POOLS_LIST, + variables: { + limit, offset, search, signerAddress, + }, }); -export const getUserPoolCount = ( queryType:string,search:string, signerAddress:string) => ({ + +const getUserPoolCountQry = (queryType:any,search:any, signerAddress:any,) => ({ query: queryType === 'User' ? USER_POOLS_LIST_COUNT : ALL_POOLS_LIST_COUNT, - variables: { search, signerAddress }, + variables: { search, signerAddress }, }); export const usePoolsList = ({ - limit, offset, search, signerAddress, tokenPrices, queryType + limit, offset, search, signerAddress, tokenPrices, queryType, httpClient, }: UsePoolsList): [PoolItem[], boolean, number] => { - const [loadingPoolsList, setLoadingPoolsList] = useState(true); - const [loadingPoolsCount, setLoadingPoolsCount] = useState(true); - const [dataPoolsList, setDataPoolsList] = useState(); - const [dataPoolsCount, setDataPoolsCount] = useState(); - - - useEffect(() => { - const fetchRes = async()=>{ - const userPoolCountQry = getUserPoolCount(queryType,search, signerAddress); - const userPoolCountQryResp = await graphqlRequest(axios, userPoolCountQry); - setDataPoolsCount(userPoolCountQryResp.data); - setLoadingPoolsCount(false); - const userPoolQry = getUserPoolList(queryType,limit, offset, search, signerAddress,); - const response = await graphqlRequest(axios, userPoolQry); - setDataPoolsList(response.data); - setLoadingPoolsList(false); - } - fetchRes(); - }, []) - - - + const [dataPoolsList, setdataPoolsList] = useState(); + const [dataPoolsCount, setDataPoolsCount] = useState(); + const [loadingPoolsList, setLoadingPoolsList] = useState(true) + const [loadingPoolsCount, setLoadingPoolsCount] = useState(true) // const { data: dataPoolsList, loading: loadingPoolsList } = useQuery( // queryType === 'User' ? USER_POOLS_LIST : ALL_POOLS_LIST, // { @@ -140,9 +125,29 @@ export const usePoolsList = ({ // }, // }, // ); + const userPoolQry = getUserPoolList(queryType,limit, offset, search, signerAddress); + useEffect(() => { + const handleResp = async()=>{ + setLoadingPoolsList(true); + const response = await graphqlRequest(httpClient, userPoolQry); + setdataPoolsList(response.data); + setLoadingPoolsList(false); + } + handleResp(); + }, []); + + const userPoolCountQry = getUserPoolCountQry(queryType, search, signerAddress); + useEffect(() => { + const handleResp = async()=>{ + setLoadingPoolsCount(true); + const response = await graphqlRequest(httpClient, userPoolCountQry); + setDataPoolsCount(response.data); + setLoadingPoolsCount(false); + } + handleResp(); + }, []); - - // const { data: dataPoolsCount, loading: loadingPoolsCount } = useQuery( + // const { data: dataPoolsCount } = useQuery( // queryType === 'User' ? USER_POOLS_LIST_COUNT : ALL_POOLS_LIST_COUNT, // { // client: dexClient, @@ -181,4 +186,4 @@ export const usePoolsList = ({ : (dataPoolsCount as AllPoolsListCountQuery).allPoolsListCount : 0, ]; -}; +}; \ No newline at end of file diff --git a/src/hooks/usePoolStats.ts b/src/hooks/usePoolStats.ts index 71384aa..2c29201 100644 --- a/src/hooks/usePoolStats.ts +++ b/src/hooks/usePoolStats.ts @@ -1,7 +1,10 @@ import { BigNumber } from 'bignumber.js'; import { useEffect, useMemo, useState } from 'react'; -import { AxiosInstance } from 'axios'; import { + Pool24HVolume, + PoolInfoQuery, + PoolsTotalSupply, + PoolTokensDataQuery, POOLS_TOTAL_VALUE_LOCKED, POOL_24H_VOLUME, POOL_INFO_GQL, @@ -10,57 +13,56 @@ import { import { getTokenPrice, TokenPrices } from '../state'; import { getIconUrl, normalize, POLL_INTERVAL } from '../utils'; import useInterval from './userInterval'; -import { graphqlRequest } from '../graphql/gqlUtils'; +import { AxiosInstance } from 'axios'; +import { graphqlRequest } from '../appState/accountState'; -export const getPoolsTotalValueLockedQuery = (toTime: string) => ({ +const getPoolTotalValueLockedQry = (toTime: any) => ({ query: POOLS_TOTAL_VALUE_LOCKED, variables: { toTime }, }); +const getPool24HvolQry = (fromTime: any) => ({ + query: POOL_24H_VOLUME, + variables: { fromTime }, +}); +const getPoolTokensDataQry = (address: string) => ({ + query: POOL_TOKENS_DATA_GQL, + variables: { address }, +}); +const getPoolInfoQry = (address:string, signerAddress:string, fromTime:string, toTime:string) => ({ + query: POOL_INFO_GQL, + variables: { + address, signerAddress, fromTime, toTime, + }, +}); -export const getPool24HourQuery = (fromTime: string) => { - return { - query: POOL_24H_VOLUME, - variables: { fromTime }, - }; -}; - -export const getPoolTokensDataQuery = (address: string) => { - return { - query: POOL_TOKENS_DATA_GQL, - variables: { address }, - }; - }; - -export const getPoolInfoQuery = (address:string, signerAddress:string, fromTime:string, toTime:string) => { - return { - query: POOL_INFO_GQL, - variables: { address,signerAddress,fromTime,toTime }, - }; - }; - - export const useTotalSupply = (tokenPrices: TokenPrices, httpClient: AxiosInstance, previous = false): string=> { - const [data, setData] = useState() - const toTime = useMemo(() => { - const tm = new Date(); - if (previous) { - tm.setDate(tm.getDate() - 1); - } - return tm; - }, []); - - useEffect(()=>{ - const handleResponse = async()=>{ - const poolsTotalValueLockedQry = getPoolsTotalValueLockedQuery(toTime.toISOString()); - const response = await graphqlRequest(httpClient, poolsTotalValueLockedQry); - setData(response.data); - } - handleResponse(); - }) - +export const useTotalSupply = (tokenPrices: TokenPrices, httpClient:AxiosInstance, previous = false): string => { + const [data, setData] = useState() + const toTime = useMemo(() => { + const tm = new Date(); + if (previous) { + tm.setDate(tm.getDate() - 1); + } + return tm; + }, []); - if (!data || data.totalSupply.length === 0) { - return '0'; - } + useEffect(() => { + const handleRes = async ()=>{ + const res = await graphqlRequest(httpClient,getPoolTotalValueLockedQry(toTime.toISOString())); + setData(res.data); + } + handleRes(); + }, []) + + // const { data } = useQuery( + // POOLS_TOTAL_VALUE_LOCKED, + // { + // client: dexClient, + // variables: { toTime: toTime.toISOString() }, + // }, + // ); + if (!data || data.totalSupply.length === 0) { + return '0'; + } const totalSupply = data.totalSupply.reduce((acc, { reserved1, reserved2, pool: { token1, token2 } }) => { const tokenPrice1 = getTokenPrice(token1, tokenPrices); @@ -73,15 +75,30 @@ export const getPoolInfoQuery = (address:string, signerAddress:string, fromTime: return totalSupply.toString(); }; -export const usePoolVolume = async (tokenPrices: TokenPrices, httpClient: AxiosInstance): Promise => { +export const usePoolVolume = (tokenPrices: TokenPrices, httpClient:AxiosInstance): string => { + const [data, setData] = useState() + const fromTime = useMemo( () => new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), [], ); - const pool24HourQry = getPool24HourQuery(fromTime); - const response = await graphqlRequest(httpClient, pool24HourQry); - const data = response.data; + useEffect(() => { + const handleRes = async ()=>{ + const res = await graphqlRequest(httpClient,getPool24HvolQry(fromTime)); + setData(res.data); + } + handleRes(); + }, []) + + + // const { data } = useQuery( + // POOL_24H_VOLUME, + // { + // client: dexClient, + // variables: { fromTime }, + // }, + // ); if (!data || data.volume.length === 0) { return '0'; } @@ -124,11 +141,10 @@ export interface PoolStats { } export const usePoolInfo = (address: string, signerAddress: string, tokenPrices: TokenPrices, httpClient: AxiosInstance): [PoolStats|undefined, boolean] => { - const [poolTokensDataQryResp, setPoolTokensDataQryResp] = useState(); - const [poolInfoQryResp, setPoolInfoQryResp] = useState(); + const [tokensData, setTokensData] = useState() + const [poolInfoData, setPoolInfoData] = useState() const [tokensLoading, setTokensLoading] = useState(true); const [poolInfoLoading, setPoolInfoLoading] = useState(true); - const toTime = useMemo(() => { const date = new Date(); date.setDate(date.getDate() - 1); @@ -141,32 +157,33 @@ export const usePoolInfo = (address: string, signerAddress: string, tokenPrices: return date.toISOString(); }, [address, signerAddress]); - useEffect(()=>{ - const handleResp = async()=>{ - const poolTokensDataQry = getPoolTokensDataQuery(address); - const response = await graphqlRequest(httpClient, poolTokensDataQry); - setPoolTokensDataQryResp(response); + // const { data: tokensData, loading: tokensLoading } = useQuery(POOL_TOKENS_DATA_GQL, { + // client: dexClient, + // variables: { address }, + // }); + useEffect(() => { + const handleRes = async ()=>{ + setTokensLoading(true); + const res = await graphqlRequest(httpClient,getPoolTokensDataQry(address)); + setTokensData(res.data); setTokensLoading(false); - const poolInfoQry = getPoolInfoQuery(address, signerAddress, fromTime, toTime); - const response_ = await graphqlRequest(httpClient, poolInfoQry); - setPoolInfoQryResp(response_); - setPoolInfoLoading(false); } - handleResp(); - }) - - const { data: tokensData} = poolTokensDataQryResp.data; - const { data: poolInfoData } = poolInfoQryResp.data; - - useInterval(() => { + handleRes(); + }, []) + + // const { data: poolInfoData, loading: poolInfoLoading, refetch: refetchPoolInfo } = useQuery(POOL_INFO_GQL, { + // client: dexClient, + // variables: { + // address, signerAddress, fromTime, toTime, + // }, + // }); + + const queryObj = getPoolInfoQry( address, signerAddress, fromTime, toTime); + useInterval(async() => { setPoolInfoLoading(true); - const handleResp = async()=>{ - const poolInfoQry = getPoolInfoQuery(address, signerAddress, fromTime, toTime); - const response_ = await graphqlRequest(httpClient, poolInfoQry); - setPoolInfoQryResp(response_); - setPoolInfoLoading(false); - } - handleResp(); + const response = await graphqlRequest(httpClient, queryObj); + setPoolInfoData(response.data); + setPoolInfoLoading(false); }, POLL_INTERVAL); const info = useMemo(() => { @@ -261,4 +278,4 @@ export const usePoolInfo = (address: string, signerAddress: string, tokenPrices: }, [poolInfoData, tokensData, tokenPrices]); return [info, tokensLoading || poolInfoLoading]; -}; +}; \ No newline at end of file diff --git a/src/hooks/useRemoveLiquidity.tsx b/src/hooks/useRemoveLiquidity.tsx index de10294..53bb8ff 100644 --- a/src/hooks/useRemoveLiquidity.tsx +++ b/src/hooks/useRemoveLiquidity.tsx @@ -34,7 +34,7 @@ interface UseRemoveLiquidity { address2: string; tokens: Token[]; tokenPrices: AddressToNumber; - httpClient?: AxiosInstance; + httpClient:AxiosInstance; signer?: ReefSigner; batchTxs?: boolean; state: RemoveLiquidityState; @@ -304,4 +304,4 @@ export const onRemoveLiquidity = ({ dispatch(setLoadingAction(false)); dispatch(setPercentageAction(0)); } -}; +}; \ No newline at end of file diff --git a/src/hooks/useSwapState.ts b/src/hooks/useSwapState.ts index 42be254..c6ebe9a 100644 --- a/src/hooks/useSwapState.ts +++ b/src/hooks/useSwapState.ts @@ -85,7 +85,7 @@ interface UseSwapState { state: SwapState; tokens: Token[]; account?: ReefSigner; - httpClient?: AxiosInstance; + httpClient?:AxiosInstance; tokenPrices: AddressToNumber; dispatch: Dispatch; waitForPool?: boolean; @@ -387,4 +387,4 @@ export const onSwap = ({ dispatch(setLoadingAction(false)); dispatch(clearTokenAmountsAction()); } -}; +}; \ No newline at end of file diff --git a/src/rpc/accounts.ts b/src/rpc/accounts.ts index d0f19bc..38bf44f 100644 --- a/src/rpc/accounts.ts +++ b/src/rpc/accounts.ts @@ -2,7 +2,7 @@ import type { InjectedAccountWithMeta, InjectedExtension, } from '@polkadot/extension-inject/types'; import { Provider, Signer } from '@reef-defi/evm-provider'; - +import {getAccountSigner as getSignerUtil} from "@reef-chain/util-lib"; import { DeriveBalancesAccountData } from '@polkadot/api-derive/balances/types'; import type { Signer as InjectedSigner } from '@polkadot/api/types'; import type { @@ -77,6 +77,8 @@ const signerToReefSigner = async ( } const balance = await getReefCoinBalance(address, provider); inj?.signer; + + return { signer, balance, @@ -137,7 +139,14 @@ export const accountToSigner = async ( sign: InjectedSigner, source: string, ): Promise => { - const signer = new Signer(provider, account.address, sign); + let signer:Signer; + + let _signer = await getSignerUtil(account.address,provider,sign); + if(_signer.provider == provider){ + signer = _signer; + }else{ + signer = new Signer(provider,account.address,sign); + } return signerToReefSigner( signer, provider, @@ -173,9 +182,11 @@ export const getExtensionSigners = async ( accounts: await extension.accounts.get(), })), ); + console.log("extensionAccounts === ",typeof(extensionAccounts)); const accountPromisses = extensionAccounts.flatMap( ({ accounts, name, sig }) => accounts.map((account) => accountToSigner(account, provider, sig, name)), ); + console.log("accountPromisses===",accountPromisses); const accounts = await Promise.all(accountPromisses); return accounts as ReefSigner[]; }; diff --git a/src/utils/transactionUtil.ts b/src/utils/transactionUtil.ts index 83b1b61..6d94a78 100644 --- a/src/utils/transactionUtil.ts +++ b/src/utils/transactionUtil.ts @@ -117,8 +117,8 @@ export const getExtrinsicUrl = (extrinsic: {id:string}, network: Network = avail const [blockHeight, extrinsicIndex] = extrinsic.id.split('-'); return `${network.reefscanUrl}/extrinsic/${blockHeight}/${extrinsicIndex}`; }; -export const getTransferUrl = (extrinsic: {id:string}, network: Network = availableNetworks.mainnet): string => { +export const getTransferUrl = (extrinsic: {id:string},event:{index:string}, network: Network = availableNetworks.mainnet): string => { const [blockHeight, extrinsicIndex] = extrinsic.id.split('-'); - return `${network.reefscanUrl}/transfer/${blockHeight}/${extrinsicIndex}`; + return `${network.reefscanUrl}/transfer/${blockHeight}/${extrinsicIndex}/${event.index}`; }; export const getContractUrl = (address: string, network: Network = availableNetworks.mainnet): string => `${network.reefscanUrl}/contract/${address}`; diff --git a/yarn.lock b/yarn.lock index c6fe749..f762ad7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,7 +24,7 @@ jsonpointer "^5.0.0" leven "^3.1.0" -"@apollo/client@^3.6.2", "@apollo/client@^3.6.9": +"@apollo/client@^3.6.9": version "3.7.14" resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.7.14.tgz#40ef90390e6690e94917457cd82bdeb29e8b6af9" integrity sha512-BRvdkwq5PAXBkjXjboO12uksDm3nrZEqDi4xF97Fk3Mnaa0zDOEfJa7hoKTY9b9KA1EkeWv9BL3i7hSd4SfGBg== @@ -9276,11 +9276,6 @@ graphql-tag@^2.12.6: dependencies: tslib "^2.1.0" -graphql-ws@^5.11.2: - version "5.13.1" - resolved "https://registry.yarnpkg.com/graphql-ws/-/graphql-ws-5.13.1.tgz#96ac9963edb1e94c8e7f21af48ce5fcaab91779a" - integrity sha512-eiX7ES/ZQr0q7hSM5UBOEIFfaAUmAY9/CSDyAnsETuybByU7l/v46drRg9DQoTvVABEHp3QnrvwgTRMhqy7zxQ== - graphql@^16.2.0, graphql@^16.6.0: version "16.6.0" resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb"