From af904c51767c162a6be530565117e5886a48b6df Mon Sep 17 00:00:00 2001 From: Rhys Bartels-Waller Date: Fri, 25 Sep 2020 12:35:52 +1000 Subject: [PATCH] Release/1.2.0 (#365) * chore: update to cardano-graphql 2.2.0-beta use new combined schema in package, removing local build step * feat: show deposits and reclaims when present in transaction Shows Deposit or Deposit Reclaim in the TransactionInfo when present in transaction Closes #353 * feat: add withdrawals to TransactionInfo Withdrawals from reward accounts are displayed alongside transaction inputs in the 'from' section. Closes #352 * feat: resolve stake address searches based on withdrawals searchForAddress is now separated into searchForPaymentAddress and searchForStakeAddress, determined by using the bech32 prefix. Closes #352 * feat: use stake pool hash over slot leader reference when a block is created by a stake pool, the pool hash is now used. BFT nodes still use the slot leader reference Closes #355 * chore: bump versions, update changelog --- .gitignore | 1 - CHANGELOG.md | 16 ++++- codegen.yml | 2 +- package.json | 7 +- .../@cardano-graphql-client-ts-2.1.0.tgz | Bin 15137 -> 0 bytes .../@cardano-graphql-client-ts-2.2.0.tgz | Bin 0 -> 17096 bytes source/features/address/api/transformers.ts | 45 ++++++++---- source/features/address/types.ts | 10 ++- source/features/address/ui/AddressSummary.tsx | 50 ++++++++++++-- .../features/blocks/api/BlockOverview.graphql | 3 + source/features/blocks/api/transformers.ts | 13 +++- source/features/i18n/translations/de.json | 8 ++- source/features/i18n/translations/en.json | 8 ++- source/features/i18n/translations/ja.json | 8 ++- source/features/search/api/index.ts | 28 +++++--- ...raphql => searchForPaymentAddress.graphql} | 2 +- .../search/api/searchForStakeAddress.graphql | 38 +++++++++++ source/features/search/index.ts | 6 +- .../specs/helpers/exampleAddressData.ts | 8 ++- .../search/specs/searchForAddress.spec.ts | 34 ---------- .../specs/searchForPaymentAddress.spec.ts | 34 ++++++++++ .../specs/searchForStakeAddress.spec.ts | 34 ++++++++++ source/features/search/store.ts | 64 ++++++++++++++---- .../search/ui/AddressSearchResult.tsx | 49 +++++++++----- .../api/TransactionDetails.graphql | 5 ++ .../api/getAddressTransactions.graphql | 6 ++ .../features/transactions/api/transformers.ts | 5 ++ .../components/TransactionInfo.tsx | 17 ++++- source/features/transactions/types.ts | 6 ++ source/utils/generateGraphQLSchema.js | 17 ----- yarn.lock | 8 +-- 31 files changed, 394 insertions(+), 138 deletions(-) delete mode 100644 packages-cache/@cardano-graphql-client-ts-2.1.0.tgz create mode 100644 packages-cache/@cardano-graphql-client-ts-2.2.0.tgz rename source/features/search/api/{searchForAddress.graphql => searchForPaymentAddress.graphql} (95%) create mode 100644 source/features/search/api/searchForStakeAddress.graphql delete mode 100644 source/features/search/specs/searchForAddress.spec.ts create mode 100644 source/features/search/specs/searchForPaymentAddress.spec.ts create mode 100644 source/features/search/specs/searchForStakeAddress.spec.ts delete mode 100644 source/utils/generateGraphQLSchema.js diff --git a/.gitignore b/.gitignore index b8e5e2b8..1725614d 100755 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,3 @@ yarn-error.log .env generated/ result* -schema.graphql diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b4c64b4..ebc3c008 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,23 @@ Changelog ========= +## 1.2.0 + +### Compatible with: + +- [`cardano-graphql`: `2.2.0`](https://github.com/input-output-hk/cardano-graphql/releases/tag/2.2.0) + +### Features +- [show deposits and reclaims when present in transaction](https://github.com/input-output-hk/cardano-explorer-app/pull/361) +- [add withdrawals to TransactionInfo](https://github.com/input-output-hk/cardano-explorer-app/pull/363) +- [resolve stake address searches based on withdrawals](https://github.com/input-output-hk/cardano-explorer-app/pull/363) +- [use stake pool hash over slot leader reference](https://github.com/input-output-hk/cardano-explorer-app/pull/364) +### Chores +- [use new combined cardano-graphql schema from client package, removing local build step](https://github.com/input-output-hk/cardano-explorer-app/pull/362) + ## 1.1.0 ### Features -- [Split slots & blocks into separate columns](https://github.com/input-output-hk/cardano-explorer-app/pull/338) +- [Split slots & blocks into separate columns](https://github.com/input-output-hk/cardano-explorer-app/pull/347) - [Add package.json version to footer](https://github.com/input-output-hk/cardano-explorer-app/pull/348) ### Chores - [Dynamically calc Byron epochs length](https://github.com/input-output-hk/cardano-explorer-app/pull/334) diff --git a/codegen.yml b/codegen.yml index ee1c1d5a..cbb645d7 100644 --- a/codegen.yml +++ b/codegen.yml @@ -1,5 +1,5 @@ overwrite: true -schema: schema.graphql +schema: node_modules/@cardano-graphql/client-ts/api/schema.graphql documents: "source/**/*.graphql" generates: generated/typings/graphql-schema.d.ts: diff --git a/package.json b/package.json index 118edd15..d77f5c69 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cardano-explorer-app", - "version": "1.1.0", + "version": "1.2.0", "description": "Cardano Explorer App", "author": "Daedalus Team @ Input Output HK", "license": "Apache-2.0", @@ -13,8 +13,7 @@ "test": "jest", "test:e2e": "cypress run", "test:e2e:dev": "cypress open", - "generate:graphql-schema": "node source/utils/generateGraphQLSchema.js", - "generate:graphql-typings": "yarn generate:graphql-schema && graphql-codegen", + "generate:graphql-typings": "graphql-codegen", "export": "next export source --outdir build/static", "static:build": "NODE_ENV=production yarn build && yarn export", "static:serve": "serve ./build/static", @@ -72,7 +71,7 @@ "@babel/plugin-transform-react-display-name": "7.8.3", "@babel/plugin-transform-react-jsx-self": "7.9.0", "@babel/plugin-transform-react-jsx-source": "7.9.0", - "@cardano-graphql/client-ts": "2.1.0", + "@cardano-graphql/client-ts": "2.2.0", "@cypress/webpack-preprocessor": "4.1.1", "@graphql-codegen/cli": "1.2.0", "@graphql-codegen/typescript": "1.2.0", diff --git a/packages-cache/@cardano-graphql-client-ts-2.1.0.tgz b/packages-cache/@cardano-graphql-client-ts-2.1.0.tgz deleted file mode 100644 index 6a83cb666ddb86423f396b3a4276a99ee501b66d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15137 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 PAMpAA$c9ec0KNeL{UfKD diff --git a/packages-cache/@cardano-graphql-client-ts-2.2.0.tgz b/packages-cache/@cardano-graphql-client-ts-2.2.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..6ce23253312e74bef42bcf015bd1597d8fe9652c GIT binary patch literal 17096 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 ({ - address, - finalBalance: Currency.Util.lovelacesToAda( - s.utxos_aggregate?.aggregate?.sum?.value || '0' - ), - transactionsCount: - s.transactions_aggregate?.aggregate?.count.toString() || '0', -}); + s: SearchForPaymentAddressQuery +): IPaymentAddressSummary => { + return { + address, + finalBalance: Currency.Util.lovelacesToAda( + s.utxos_aggregate?.aggregate?.sum?.value || '0' + ), + transactionsCount: + s.transactions_aggregate?.aggregate?.count.toString() || '0' + } +}; + +export const stakeAddressDetailTransformer = ( + address: string, + s: SearchForStakeAddressQuery +): IStakeAddressSummary => { + return { + address, + totalWithdrawals: + s.withdrawals_aggregate?.aggregate?.count.toString() || '0', + totalWithdrawn: Currency.Util.lovelacesToAda( + s.withdrawals_aggregate?.aggregate?.sum?.amount || '0' + ), + transactionsCount: + s.transactions_aggregate?.aggregate?.count.toString() || '0' + } +}; diff --git a/source/features/address/types.ts b/source/features/address/types.ts index 2cf26c3a..5789f357 100644 --- a/source/features/address/types.ts +++ b/source/features/address/types.ts @@ -1,5 +1,13 @@ export interface IAddressSummary { address: string; - finalBalance: string; transactionsCount: string; } + +export interface IPaymentAddressSummary extends IAddressSummary { + finalBalance: string; +} + +export interface IStakeAddressSummary extends IAddressSummary { + totalWithdrawals: string; + totalWithdrawn: string; +} diff --git a/source/features/address/ui/AddressSummary.tsx b/source/features/address/ui/AddressSummary.tsx index b8936e0b..6b7953a6 100644 --- a/source/features/address/ui/AddressSummary.tsx +++ b/source/features/address/ui/AddressSummary.tsx @@ -6,12 +6,30 @@ import styles from './AddressSummary.module.scss'; export interface IAddressSummaryProps { address: string; - finalBalance: string; title: string; transactionsCount: string; } -const AddressSummary = (props: IAddressSummaryProps) => { +export interface IPaymentAddressSummaryProps extends IAddressSummaryProps { + finalBalance: string; +} + +export interface IStakeAddressSummaryProps extends IAddressSummaryProps { + totalWithdrawn: string; + totalWithdrawals: string; +} + +type AddressSummaryProps = IPaymentAddressSummaryProps | IStakeAddressSummaryProps + +function isPaymentAddress (props: AddressSummaryProps): props is IPaymentAddressSummaryProps { + return (props as IPaymentAddressSummaryProps).finalBalance !== undefined; +} + +function isStakeAddress (props: AddressSummaryProps): props is IStakeAddressSummaryProps { + return (props as IStakeAddressSummaryProps).totalWithdrawn !== undefined; +} + +const AddressSummary = (props: AddressSummaryProps) => { const { translate } = useI18nFeature().store; return (
@@ -32,12 +50,30 @@ const AddressSummary = (props: IAddressSummaryProps) => {
{props.transactionsCount}
-
-
- {translate('address.summaryBalanceLabel')} + {isPaymentAddress(props) && ( +
+
+ {translate('address.summaryBalanceLabel')} +
+
{props.finalBalance} ADA
-
{props.finalBalance} ADA
-
+ )} + {isStakeAddress(props) && ( + <> +
+
+ {translate('withdrawals')} +
+
{props.totalWithdrawals}
+
+
+
+ {translate('address.totalWithdrawn')} +
+
{props.totalWithdrawn} ADA
+
+ + )}
; + + public searchForStakeAddressQuery: GraphQLRequest< + SearchForStakeAddressQuery, + SearchForStakeAddressQueryVariables >; public searchByIdQuery: GraphQLRequest< @@ -37,9 +45,13 @@ export class SearchApi { >; constructor(client: GraphQLClient) { - this.searchForAddressQuery = new GraphQLRequest( + this.searchForPaymentAddressQuery = new GraphQLRequest( + client, + searchForPaymentAddressQuery + ); + this.searchForStakeAddressQuery = new GraphQLRequest( client, - searchForAddressQuery + searchForStakeAddressQuery ); this.searchByIdQuery = new GraphQLRequest(client, searchByIdQuery); this.searchForBlockByNumberQuery = new GraphQLRequest( diff --git a/source/features/search/api/searchForAddress.graphql b/source/features/search/api/searchForPaymentAddress.graphql similarity index 95% rename from source/features/search/api/searchForAddress.graphql rename to source/features/search/api/searchForPaymentAddress.graphql index bcb06fc8..0b03e242 100644 --- a/source/features/search/api/searchForAddress.graphql +++ b/source/features/search/api/searchForPaymentAddress.graphql @@ -1,4 +1,4 @@ -query searchForAddress( +query searchForPaymentAddress( $address: String! ) { utxos_aggregate ( diff --git a/source/features/search/api/searchForStakeAddress.graphql b/source/features/search/api/searchForStakeAddress.graphql new file mode 100644 index 00000000..e479bb4a --- /dev/null +++ b/source/features/search/api/searchForStakeAddress.graphql @@ -0,0 +1,38 @@ +#import "../../transactions/api/TransactionDetails.graphql" + +query searchForStakeAddress( + $address: String! +) { + transactions_aggregate ( + where: { + withdrawals: { + address: { + _eq: $address + } + } + } + ) { + aggregate { + count + } + } + withdrawals { + transaction { + ...TransactionDetails + } + } + withdrawals_aggregate ( + where: { + address: { + _eq: $address + } + } + ) { + aggregate { + count + sum { + amount + } + } + } +} diff --git a/source/features/search/index.ts b/source/features/search/index.ts index 410338f0..623e8027 100644 --- a/source/features/search/index.ts +++ b/source/features/search/index.ts @@ -10,16 +10,18 @@ import { SearchStore } from './store'; * Defines the actions that are supported by this feature */ export class SearchActions { + public addressNotFound: Action<{ address: string }> = new Action(); public addressSearchRequested: Action<{ address: string }> = new Action(); public blockNumberSearchRequested: Action<{ number: number }> = new Action(); public epochNumberSearchRequested: Action<{ number: number }> = new Action(); public idSearchRequested: Action<{ id: string }> = new Action(); - public unknownSearchRequested: Action<{ query: string }> = new Action(); public searchById: Action<{ id: string }> = new Action(); - public searchForAddress: Action<{ address: string }> = new Action(); + public searchForPaymentAddress: Action<{ address: string }> = new Action(); + public searchForStakeAddress: Action<{ address: string }> = new Action(); public searchForBlockByNumber: Action<{ number: number }> = new Action(); public searchForEpochByNumber: Action<{ number: number }> = new Action(); public subscribeToEpoch: Action<{ number: number }> = new Action(); + public unknownSearchRequested: Action<{ query: string }> = new Action(); public unsubscribeFromEpoch: Action = new Action(); } diff --git a/source/features/search/specs/helpers/exampleAddressData.ts b/source/features/search/specs/helpers/exampleAddressData.ts index 77521578..330afe6c 100644 --- a/source/features/search/specs/helpers/exampleAddressData.ts +++ b/source/features/search/specs/helpers/exampleAddressData.ts @@ -1,4 +1,4 @@ -export const exampleAddressData = { +export const examplePaymentAddressData = { address: 'Ae2tdPwUPEZBZTsRj7nGvvWQDTkqD9KLpCPpuZvjA1roL7KLDDVgkPU5S8j', finalBalance: '0', transactions: [ @@ -25,3 +25,9 @@ export const exampleAddressData = { ], transactionsCount: '2', }; + +export const exampleStakeAddressData = { + address: 'stake1u8gu2vzsk2nc6hsphudhl3p6aum7nd59ajqjg9zp00uvxcqwsdray', + totalWithdrawn: '1563.774139', + transactionsCount: '1', +}; diff --git a/source/features/search/specs/searchForAddress.spec.ts b/source/features/search/specs/searchForAddress.spec.ts deleted file mode 100644 index 940f2ac2..00000000 --- a/source/features/search/specs/searchForAddress.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import waitForExpect from 'wait-for-expect'; -import { ISearchFeature } from '../index'; -import { exampleAddressData } from './helpers/exampleAddressData'; -import { setupSearchFeature } from './helpers/setup'; - -describe('Searching for an address summary', () => { - let search: ISearchFeature; - beforeEach(() => { - search = setupSearchFeature(); - search.start(); - }); - afterEach(() => { - search.stop(); - }); - it('searches for a summary related to the provided address', async () => { - // 1. Trigger action - search.actions.searchForAddress.trigger({ - address: exampleAddressData.address, - }); - - // 2. Check the API query status - expect(search.api.searchForAddressQuery.isExecuting).toBe(true); - - // 3. Access the observable search result provided by the store - await waitForExpect(() => { - expect(search.store?.addressSearchResult?.finalBalance).toBe( - exampleAddressData.finalBalance - ); - expect(search.store?.addressSearchResult?.transactionsCount).toBe( - exampleAddressData.transactionsCount - ); - }); - }); -}); diff --git a/source/features/search/specs/searchForPaymentAddress.spec.ts b/source/features/search/specs/searchForPaymentAddress.spec.ts new file mode 100644 index 00000000..3529f2b1 --- /dev/null +++ b/source/features/search/specs/searchForPaymentAddress.spec.ts @@ -0,0 +1,34 @@ +import waitForExpect from 'wait-for-expect'; +import { ISearchFeature } from '../index'; +import { examplePaymentAddressData } from './helpers/exampleAddressData'; +import { setupSearchFeature } from './helpers/setup'; + +describe('Searching for a payment address summary', () => { + let search: ISearchFeature; + beforeEach(() => { + search = setupSearchFeature(); + search.start(); + }); + afterEach(() => { + search.stop(); + }); + it('searches for a summary related to the provided payment address', async () => { + // 1. Trigger action + search.actions.searchForPaymentAddress.trigger({ + address: examplePaymentAddressData.address, + }); + + // 2. Check the API query status + expect(search.api.searchForPaymentAddressQuery.isExecuting).toBe(true); + + // 3. Access the observable search result provided by the store + await waitForExpect(() => { + expect(search.store?.paymentAddressSearchResult?.finalBalance).toBe( + examplePaymentAddressData.finalBalance + ); + expect(search.store?.paymentAddressSearchResult?.transactionsCount).toBe( + examplePaymentAddressData.transactionsCount + ); + }); + }); +}); diff --git a/source/features/search/specs/searchForStakeAddress.spec.ts b/source/features/search/specs/searchForStakeAddress.spec.ts new file mode 100644 index 00000000..123de9f7 --- /dev/null +++ b/source/features/search/specs/searchForStakeAddress.spec.ts @@ -0,0 +1,34 @@ +import waitForExpect from 'wait-for-expect'; +import { ISearchFeature } from '../index'; +import { exampleStakeAddressData } from './helpers/exampleAddressData'; +import { setupSearchFeature } from './helpers/setup'; + +describe('Searching for a stake address summary', () => { + let search: ISearchFeature; + beforeEach(() => { + search = setupSearchFeature(); + search.start(); + }); + afterEach(() => { + search.stop(); + }); + it('searches for a summary related to the provided stake address', async () => { + // 1. Trigger action + search.actions.searchForStakeAddress.trigger({ + address: exampleStakeAddressData.address, + }); + + // 2. Check the API query status + expect(search.api.searchForStakeAddressQuery.isExecuting).toBe(true); + + // 3. Access the observable search result provided by the store + await waitForExpect(() => { + expect(search.store?.stakeAddressSearchResult?.totalWithdrawn).toBe( + exampleStakeAddressData.totalWithdrawn + ); + expect(search.store?.stakeAddressSearchResult?.transactionsCount).toBe( + exampleStakeAddressData.transactionsCount + ); + }); + }); +}); diff --git a/source/features/search/store.ts b/source/features/search/store.ts index 20774556..19e0c0a2 100644 --- a/source/features/search/store.ts +++ b/source/features/search/store.ts @@ -3,9 +3,12 @@ import { ActionProps, createActionBindings } from '../../lib/ActionBinding'; import Reaction, { createReactions } from '../../lib/mobx/Reaction'; import { Store } from '../../lib/Store'; import { isDefined } from '../../lib/types'; -import { addressDetailTransformer } from '../address/api/transformers'; +import { + paymentAddressDetailTransformer, + stakeAddressDetailTransformer +} from '../address/api/transformers'; import { ADDRESS_SEARCH_RESULT_PATH } from '../address/config'; -import { IAddressSummary } from '../address/types'; +import { IAddressSummary, IPaymentAddressSummary, IStakeAddressSummary } from '../address/types'; import { blockDetailsTransformer } from '../blocks/api/transformers'; import { BLOCK_SEARCH_RESULT_PATH } from '../blocks/config'; import { IBlockDetailed } from '../blocks/types'; @@ -31,9 +34,10 @@ export enum SearchType { } export class SearchStore extends Store { - @observable public addressSearchResult: IAddressSummary | null = null; @observable public blockSearchResult: IBlockDetailed | null = null; @observable public epochSearchResult: IEpochOverview | null = null; + @observable public paymentAddressSearchResult: IPaymentAddressSummary | null = null; + @observable public stakeAddressSearchResult: IStakeAddressSummary | null = null; @observable public transactionSearchResult: ITransactionDetails | null = null; private readonly searchApi: SearchApi; @@ -71,7 +75,8 @@ export class SearchStore extends Store { this.onSearchByEpochNumberRequested, ], [this.searchActions.searchById, this.searchById], - [this.searchActions.searchForAddress, this.searchForAddress], + [this.searchActions.searchForPaymentAddress, this.searchForPaymentAddress], + [this.searchActions.searchForStakeAddress, this.searchForStakeAddress], [ this.searchActions.searchForBlockByNumber, this.searchForBlockByNumber, @@ -98,11 +103,12 @@ export class SearchStore extends Store { @computed get isSearching() { return ( - this.searchApi.searchForAddressQuery.isExecuting || - this.searchApi.searchForBlockByNumberQuery.isExecuting || this.searchApi.searchByIdQuery.isExecuting || this.searchApi.searchForBlockByNumberQuery.isExecuting || - this.searchApi.searchForEpochByNumberQuery.isExecuting + this.searchApi.searchForBlockByNumberQuery.isExecuting || + this.searchApi.searchForEpochByNumberQuery.isExecuting || + this.searchApi.searchForPaymentAddressQuery.isExecuting || + this.searchApi.searchForStakeAddressQuery.isExecuting ); } @@ -189,20 +195,21 @@ export class SearchStore extends Store { }); }; - @action private searchForAddress = async ({ - address, + @action private searchForPaymentAddress = async ({ + address }: { address: string; }) => { // Do not execute queries more than necessary! if ( - this.searchApi.searchForAddressQuery.isExecuting || - this.addressSearchResult?.address === address + this.searchApi.searchForPaymentAddressQuery.isExecuting || + this.paymentAddressSearchResult?.address === address ) { return; } - this.addressSearchResult = null; - const result = await this.searchApi.searchForAddressQuery.execute({ + this.paymentAddressSearchResult = null; + this.stakeAddressSearchResult = null; + const result = await this.searchApi.searchForPaymentAddressQuery.execute({ address, }); if (isDefined(result)) { @@ -215,7 +222,36 @@ export class SearchStore extends Store { }); } runInAction(() => { - this.addressSearchResult = addressDetailTransformer(address, result); + this.paymentAddressSearchResult = paymentAddressDetailTransformer(address, result); + }); + } + }; + + @action private searchForStakeAddress = async ({ + address, + }: { + address: string; + }) => { + // Do not execute queries more than necessary! + if ( + this.searchApi.searchForStakeAddressQuery.isExecuting || + this.stakeAddressSearchResult?.address === address + ) { + return; + } + this.stakeAddressSearchResult = null; + this.paymentAddressSearchResult = null; + const result = await this.searchApi.searchForStakeAddressQuery.execute({ + address, + }); + if (isDefined(result)) { + if (result.withdrawals_aggregate?.aggregate?.count === '0') { + return this.searchActions.unknownSearchRequested.trigger({ + query: address, + }); + } + runInAction(() => { + this.stakeAddressSearchResult = stakeAddressDetailTransformer(address, result); }); } }; diff --git a/source/features/search/ui/AddressSearchResult.tsx b/source/features/search/ui/AddressSearchResult.tsx index 963ff88f..64fab89c 100644 --- a/source/features/search/ui/AddressSearchResult.tsx +++ b/source/features/search/ui/AddressSearchResult.tsx @@ -25,36 +25,49 @@ export const AddressSearchResult = () => { const { query } = navigation.store; const { address } = query; if (isString(address)) { - actions.searchForAddress.trigger({ address }); + if (address.substring(0, 5) === 'stake') { + actions.searchForStakeAddress.trigger({ address }); + } else { + actions.searchForPaymentAddress.trigger({ address }); + } } }); return ( {() => { - const { addressSearchResult } = store; + const { paymentAddressSearchResult, stakeAddressSearchResult } = store; + const address = paymentAddressSearchResult?.address || stakeAddressSearchResult?.address || null; + const transactionsCount = paymentAddressSearchResult?.transactionsCount || stakeAddressSearchResult?.transactionsCount; if ( - !api.searchForAddressQuery.hasBeenExecutedAtLeastOnce || + ( paymentAddressSearchResult && !api.searchForPaymentAddressQuery.hasBeenExecutedAtLeastOnce ) || + ( stakeAddressSearchResult && !api.searchForStakeAddressQuery.hasBeenExecutedAtLeastOnce ) || store.isSearching ) { return ; - } else if (addressSearchResult) { - const { - address, - finalBalance, - transactionsCount, - } = addressSearchResult; + } else if (address !== null && transactionsCount !== null) { return ( <>
- + { paymentAddressSearchResult && ( + + )} + { stakeAddressSearchResult && ( + + )}
- { }} perPage={navigation.store.query.perPage as string} currentPage={(navigation.store.query.page as string) ?? 1} - total={parseInt(transactionsCount, 10)} + total={parseInt(paymentAddressSearchResult?.transactionsCount || stakeAddressSearchResult?.transactionsCount || '0', 10)} transactions={transactions.store.browsedAddressTransactions} - /> + />}
); diff --git a/source/features/transactions/api/TransactionDetails.graphql b/source/features/transactions/api/TransactionDetails.graphql index 2be03a9d..218fae75 100644 --- a/source/features/transactions/api/TransactionDetails.graphql +++ b/source/features/transactions/api/TransactionDetails.graphql @@ -5,6 +5,7 @@ fragment TransactionDetails on Transaction { number, slotNo, } + deposit, fee, hash, includedAt, @@ -20,4 +21,8 @@ fragment TransactionDetails on Transaction { value }, totalOutput + withdrawals { + address + amount + } } diff --git a/source/features/transactions/api/getAddressTransactions.graphql b/source/features/transactions/api/getAddressTransactions.graphql index 387bff5e..5aaf7cb5 100644 --- a/source/features/transactions/api/getAddressTransactions.graphql +++ b/source/features/transactions/api/getAddressTransactions.graphql @@ -8,6 +8,12 @@ query getAddressTransactions( transactions( where: { _or: [{ + withdrawals: { + address: { + _eq: $address + } + } + }, { inputs: { address: { _eq: $address diff --git a/source/features/transactions/api/transformers.ts b/source/features/transactions/api/transformers.ts index 68c7c07d..5628976c 100644 --- a/source/features/transactions/api/transformers.ts +++ b/source/features/transactions/api/transformers.ts @@ -11,6 +11,7 @@ export const transactionDetailsTransformer = ( id: tx.block?.hash, number: tx.block?.number, }, + deposit: Currency.Util.lovelacesToAda(tx.deposit), fee: Currency.Util.lovelacesToAda(tx.fee), id: tx.hash, includedAt: new Date(tx.includedAt), @@ -24,4 +25,8 @@ export const transactionDetailsTransformer = ( value: Currency.Util.lovelacesToAda(i.value), })), totalOutput: Currency.Util.lovelacesToAda(tx.totalOutput), + withdrawals: tx.withdrawals?.filter(isDefined).map((i) => ({ + address: i.address, + value: Currency.Util.lovelacesToAda(i.amount) + })) || [] }); diff --git a/source/features/transactions/components/TransactionInfo.tsx b/source/features/transactions/components/TransactionInfo.tsx index 7f5fe465..55f2d898 100644 --- a/source/features/transactions/components/TransactionInfo.tsx +++ b/source/features/transactions/components/TransactionInfo.tsx @@ -18,6 +18,7 @@ import { ITransactionDetails, ITransactionInput, ITransactionOutput, + IWithdrawal, } from '../types'; import styles from './TransactionInfo.module.scss'; @@ -48,7 +49,7 @@ const TransactionAddressMobile = (props: { address: string }) => ); -type AddressInputOutput = ITransactionInput | ITransactionOutput; +type AddressInputOutput = ITransactionInput | IWithdrawal | ITransactionOutput; interface IAddressesRowProps { addresses?: Array; @@ -119,7 +120,7 @@ const TransactionInfo = (props: ITransactionInfoProps) => { }); }; const epoch = props.block.epoch === '-' ? 0 : props.block.epoch; - + const depositLabel = parseInt(props.deposit) >= 0 ? 'transaction.deposit' : 'transaction.depositReclaim' return (
{props.title && ( @@ -203,7 +204,7 @@ const TransactionInfo = (props: ITransactionInfoProps) => {
@@ -227,6 +228,16 @@ const TransactionInfo = (props: ITransactionInfoProps) => {
+ {/* ===== DEPOSIT ===== */} + {props.deposit !== '0' && ( +
+
+ {translate(depositLabel)} +
+
{Math.abs(parseInt(props.deposit))} ADA
+
+ )} + {/* ===== TOTAL OUTPUT ===== */}
diff --git a/source/features/transactions/types.ts b/source/features/transactions/types.ts index 63148484..2a29265c 100644 --- a/source/features/transactions/types.ts +++ b/source/features/transactions/types.ts @@ -13,6 +13,10 @@ export interface ITransactionOutput extends ICoin { index: number; } +export interface IWithdrawal extends ICoin { + address: string; +} + export interface ITransactionDetails { block: { epoch?: number | '-'; @@ -20,10 +24,12 @@ export interface ITransactionDetails { number?: number | null; slot?: number | null; }; + deposit: string; fee: string; id: string; includedAt: Date; inputs: ITransactionInput[]; outputs?: ITransactionOutput[]; totalOutput: string; + withdrawals: IWithdrawal[]; } diff --git a/source/utils/generateGraphQLSchema.js b/source/utils/generateGraphQLSchema.js deleted file mode 100644 index 94f1a144..00000000 --- a/source/utils/generateGraphQLSchema.js +++ /dev/null @@ -1,17 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const { loadFilesSync } = require('@graphql-tools/load-files'); -const { mergeTypeDefs } = require('@graphql-tools/merge'); -const { printSchemaWithDirectives } = require('@graphql-tools/utils'); -const { makeExecutableSchema } = require('@graphql-tools/schema'); - -const cardanoDbHasuraSchema = loadFilesSync('./node_modules/@cardano-graphql/client-ts/api/cardano-db-hasura/schema.graphql'); -const genesisSchema = loadFilesSync('./node_modules/@cardano-graphql/client-ts/api/genesis/schema.graphql'); -const mergedTypes = mergeTypeDefs([cardanoDbHasuraSchema, genesisSchema], { - throwOnConflict: true -}); - -const executableSchema = makeExecutableSchema({ typeDefs: [mergedTypes] }); -const schema = printSchemaWithDirectives(executableSchema); - -fs.writeFileSync(path.join(__dirname, '../../schema.graphql'), schema); diff --git a/yarn.lock b/yarn.lock index b19022f1..9d6fa36c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1443,10 +1443,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@cardano-graphql/client-ts@2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@cardano-graphql/client-ts/-/client-ts-2.1.0.tgz#f93ddbe4cb88c7b4f5048bc0692e575bd81d9993" - integrity sha512-OnvlWkMxSoH2NFfSLPTNRGnzqg4efZmXc34wBUefTfPvmGaNO1NxYVP1wW2nS5/lfkNxwSyFPKX3yNu+MNKh2Q== +"@cardano-graphql/client-ts@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@cardano-graphql/client-ts/-/client-ts-2.2.0.tgz#a8f725ab642a9605f9c4aee3b78d2a637f568675" + integrity sha512-1ob9UboUijZxXllSlaYtsoOWM4EXcmPlKyhm1o5+kY2qkD7lRzOs6TBpJegrU4xQX+TGhLALawP+l6lNiHIsTg== "@cnakazawa/watch@^1.0.3": version "1.0.4"