Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: revert "grouped outputs removal" #439

Merged
merged 2 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@ export const TX_MOCK = mocks.aTransaction({
GROUPED_INPUT_ASSET,
GROUPED_INPUT_MESSAGE,
],
groupedOutputs: [],
outputs: [OUTPUT_ASSET, OUTPUT_ASSET_UNKNOWN, OUTPUT_CONTRACT_CREATED],
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type {
ChangeOutput,
CoinOutput,
ContractCreated,
ContractOutput,
TransactionOutputFragment,
} from '@fuel-explorer/graphql';
import {
Expand Down Expand Up @@ -76,32 +75,6 @@ const TxOutputCoin = createComponent<
},
});

const TxOutputContract = createComponent<
TxOutputProps<ContractOutput>,
typeof Card
>({
id: 'TxOutputContract',
render: (_, { output, ...props }) => {
const classes = styles();

return (
<Card {...props} className={cx('py-3', props.className)}>
<Card.Header className={classes.header()}>
<HStack align="center">
<TxIcon status="Submitted" type="Contract" />
<VStack gap="1">
<Text className="font-medium">Contract Output</Text>
<Text className="text-sm text-secondary">
Input Index: {output.inputIndex}
</Text>
</VStack>
</HStack>
</Card.Header>
</Card>
);
},
});

const TxOutputContractCreated = createComponent<
TxOutputProps<ContractCreated>,
typeof Card
Expand Down Expand Up @@ -141,9 +114,6 @@ export function TxOutput({ output, ...props }: TxOutputProps) {
) {
return <TxOutputCoin output={output} {...props} />;
}
if (isOutput<ContractOutput>(output, 'ContractOutput')) {
return <TxOutputContract output={output} {...props} />;
}
if (isOutput<ContractCreated>(output, 'ContractCreated')) {
return <TxOutputContractCreated output={output} {...props} />;
}
Expand Down
64 changes: 64 additions & 0 deletions packages/graphql/src/domains/Output.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { bn } from '@fuel-ts/math';
import { groupBy } from 'lodash';

import type {
ChangeOutput,
CoinOutput,
ContractCreated,
TransactionItemFragment,
} from '../generated/types';

type Outputs = TransactionItemFragment['outputs'];

export class OutputDomain {
constructor(private outputs: Outputs) {}

get groupedOutputs() {
return [
...this.coinOutputs,
...this.changeOutputs,
...this.contractCreatedOutputs,
];
}

get coinOutputs() {
const outputs = this._filterByTypename<CoinOutput>('CoinOutput');
const entries = Object.entries(groupBy(outputs, (i) => i.assetId));
return entries.map(([assetId, outputs]) => {
const type = outputs[0].__typename;
const to = outputs[0].to;
const totalAmount = this._getTotalAmount(outputs);
return { to, assetId, type, totalAmount, outputs };
});
}

get changeOutputs() {
const outputs = this._filterByTypename<ChangeOutput>('ChangeOutput');
const entries = Object.entries(groupBy(outputs, (i) => i.assetId));
return entries.map(([assetId, outputs]) => {
const type = outputs[0].__typename;
const to = outputs[0].to;
const totalAmount = this._getTotalAmount(outputs);
return { to, assetId, type, outputs, totalAmount };
});
}

get contractCreatedOutputs() {
const outputs = this._filterByTypename<ContractCreated>('ContractCreated');
const entries = Object.entries(groupBy(outputs, (i) => i.contract));
return entries.map(([_, outputs]) => {
const type = outputs[0].__typename;
const contractId = outputs[0].contract;
return { contractId, type, outputs };
});
}

private _filterByTypename<T>(typename: string | string[]) {
const type = Array.isArray(typename) ? typename : [typename];
return this.outputs?.filter((i) => type.includes(i.__typename)) as T[];
}

private _getTotalAmount<T extends { amount: string }>(inputs: T[]) {
return inputs.reduce((acc, input) => acc.add(bn(input.amount)), bn(0));
}
}
8 changes: 8 additions & 0 deletions packages/graphql/src/domains/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { type Context, Domain } from '../utils/domain';
import type { GqlTransaction } from 'fuels';
import { InputDomain } from './Input';
import { OperationDomain } from './Operation';
import { OutputDomain } from './Output';

export class TransactionDomain extends Domain<TransactionItemFragment> {
static createResolvers() {
Expand All @@ -17,6 +18,7 @@ export class TransactionDomain extends Domain<TransactionItemFragment> {
...domain.createResolver('fee', 'getFee'),
...domain.createResolver('gasUsed', 'getGasUsed'),
...domain.createResolver('groupedInputs'),
...domain.createResolver('groupedOutputs'),
...domain.createResolver('isPredicate'),
...domain.createResolver('operations', 'getOperations'),
...domain.createResolver('statusType'),
Expand Down Expand Up @@ -118,6 +120,12 @@ export class TransactionDomain extends Domain<TransactionItemFragment> {
return domain.groupedInputs;
}

get groupedOutputs() {
const { source: transaction } = this;
const domain = new OutputDomain(transaction.outputs ?? []);
return domain.groupedOutputs;
}

get isPredicate() {
const inputs = this.source.inputs ?? [];
return inputs.some((input) => {
Expand Down
12 changes: 12 additions & 0 deletions packages/graphql/src/queries/tx-fragments.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,18 @@ fragment TransactionItem on Transaction {
data
owner
}
groupedOutputs {
to
type
totalAmount
outputs {
...TransactionOutput
}
contractId
assetId
inputIndex
recipient
}
accountsInvolved {
id
type
Expand Down
21 changes: 21 additions & 0 deletions packages/graphql/src/services/extends.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,26 @@ type GroupedInput {
owner: Address
}

enum GroupedOutputType {
CoinOutput
ContractOutput
MessageOutput
ChangeOutput
VariableOutput
ContractCreated
}

type GroupedOutput {
type: GroupedOutputType
totalAmount: U64
outputs: [Output]
to: Address
assetId: AssetId
inputIndex: Int
recipient: Address
contractId: ContractId
}

enum TransactionAccountType {
Contract
Predicate
Expand Down Expand Up @@ -86,6 +106,7 @@ extend type Transaction {
operations: [Operation]
accountsInvolved: [TransactionAccount]
groupedInputs: [GroupedInput]
groupedOutputs: [GroupedOutput]
isPredicate: Boolean
fee: U64
}
Expand Down
Loading