Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
02e2733
added SQL query for Transaction Fee stats
raghukapur9 Sep 5, 2024
2c676c4
feat:added query to get Transaction Fee Stat
raghukapur9 Sep 5, 2024
17bcae7
feat: added blockReward query for statistics
raghukapur9 Sep 5, 2024
54fbc66
feat: added block count and reward stat
raghukapur9 Sep 6, 2024
ce02b4e
fix: block reward query using tai64timestamp
raghukapur9 Sep 6, 2024
61602a4
feat: added transaction count and fee query for statistics
raghukapur9 Sep 6, 2024
315b47d
Merge branch 'FuelLabs:main' into stats
raghukapur9 Sep 6, 2024
b75e986
refactor: created a utils function for getting query time interval
raghukapur9 Sep 6, 2024
2a59351
Merge pull request #14 from DevForce99/stats
raghukapur9 Sep 6, 2024
04abc88
statistics-data-fetch
Sep 9, 2024
586b673
fixed input structure for statistic functions
raghukapur9 Sep 9, 2024
bd8f8a6
statistics-data-fetch
Sep 9, 2024
6c3d8aa
statistics-data-fetch
Sep 10, 2024
0c2a954
fix: fixed ms calculation
raghukapur9 Sep 10, 2024
0fa8155
refactor transaction stats
raghukapur9 Sep 10, 2024
e959db4
added cumulative transaction stat with an offset
raghukapur9 Sep 10, 2024
ca53a07
statistics-data-fetch
Sep 11, 2024
e44ef67
statistics data done
Sep 11, 2024
a8be9dc
Merge branch 'feat/statistics-integrations' into feat/statistics
aashaykapoor Sep 11, 2024
de3c1c8
Merge pull request #16 from DevForce99/feat/statistics
aashaykapoor Sep 11, 2024
6f1c7d5
Revert "Merge branch 'feat/statistics-integrations' into feat/statist…
aashaykapoor Sep 11, 2024
5273bad
fix: stats padding issues
aashaykapoor Sep 11, 2024
9ac1c4b
Account Data Indexing
shivam-25 Sep 12, 2024
210b59c
Merge branch 'feat/statistics' of https://github.com/DevForce99/fuel-…
shivam-25 Sep 12, 2024
1a92687
add date and filter utils
aashaykapoor Sep 12, 2024
12034af
refactor stats screen
aashaykapoor Sep 12, 2024
297cd8a
Account statistics
shivam-25 Sep 12, 2024
0065069
Cumulative Account statistic
shivam-25 Sep 12, 2024
f7796c1
refactor ui
aashaykapoor Sep 13, 2024
d9173cf
Account Data Indexing
raghukapur9 Sep 13, 2024
3bc66ec
stats bug fixes
Sep 13, 2024
760f3a0
Merge branch 'FuelLabs:main' into feat/accountDataIndexer
raghukapur9 Sep 13, 2024
6ea9887
removed AccountModel class
raghukapur9 Sep 13, 2024
759f6b2
statistics refactored
Sep 14, 2024
87311eb
fix: removed unused library
raghukapur9 Sep 14, 2024
22e6195
merge stats-backend
aashaykapoor Sep 14, 2024
492c7e0
merge stats-backend
aashaykapoor Sep 14, 2024
68930dc
refactor code stucture
aashaykapoor Sep 14, 2024
9c9838e
added accounts refactored code
Sep 15, 2024
bfbc470
added the loader wrapper and the loader box
Sep 16, 2024
924c399
Merge branch 'FuelLabs:main' into feat/accountDataIndexer
raghukapur9 Sep 16, 2024
e8bd42e
Account Balance Changes
shivam-25 Sep 16, 2024
8081dca
Block and Transaction stats
shivam-25 Sep 16, 2024
8aebca6
Merge branch 'feat/accountDataIndexer' of https://github.com/DevForce…
shivam-25 Sep 16, 2024
2b7b219
Account stats
shivam-25 Sep 16, 2024
890c920
Daily Account Statistics
shivam-25 Sep 16, 2024
243c78a
tested and fixed account statistics
raghukapur9 Sep 16, 2024
02aaf56
changed query params for CumulativeAccountCreationStatistics
raghukapur9 Sep 16, 2024
dc032a3
Top Accounts
shivam-25 Sep 16, 2024
a87eac6
Top Accounts fix
shivam-25 Sep 16, 2024
82cf321
fix: cumulative counts and ui
aashaykapoor Sep 17, 2024
208f03f
Paginated top accounts
shivam-25 Sep 17, 2024
31aa845
Merge branch 'feat/account-stats' of github.com:DevForce99/fuel-explo…
aashaykapoor Sep 17, 2024
7ed8d73
Merge branch 'feat/account-stats' of github.com:DevForce99/fuel-explo…
aashaykapoor Sep 17, 2024
cdb8bdb
fix: stats header ui
aashaykapoor Sep 17, 2024
52d062d
fix: cumulative accounts
aashaykapoor Sep 17, 2024
d9d4db3
fix: graph ui related issues and default values
aashaykapoor Sep 20, 2024
d74928d
push stats changes
aashaykapoor Sep 20, 2024
2de34d6
revert backend code
aashaykapoor Sep 20, 2024
dfd2cc9
revert backend code
aashaykapoor Sep 20, 2024
d9cf62e
revert backend code
aashaykapoor Sep 20, 2024
a141a50
revert backend code
aashaykapoor Sep 20, 2024
d5cda1d
revert backend code
aashaykapoor Sep 20, 2024
ace1638
revert backend code
aashaykapoor Sep 20, 2024
6dab3b9
revert backend code
aashaykapoor Sep 20, 2024
a44d547
fix: graph ui related issues and default values
aashaykapoor Sep 20, 2024
dd38c93
Merge branch 'main' of github.com:DevForce99/fuel-explorer into feat/…
aashaykapoor Sep 20, 2024
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
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"editor.defaultFormatter": "biomejs.biome",
"editor.formatOnSave": true,
"editor.formatOnSave": false,
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit"
},
Expand Down
1 change: 1 addition & 0 deletions packages/app-explorer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"react-json-view-lite": "1.4.0",
"react-use": "17.5.0",
"react-window": "1.8.10",
"recharts": "2.12.7",
"tai64": "1.0.0",
"tailwind-variants": "0.1.20",
"wagmi": "2.12.7",
Expand Down
7 changes: 6 additions & 1 deletion packages/app-explorer/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
:root {
--hero-bg: #000;
--font-geist-mono: 'GeistMono', 'SF Mono', 'Segoe UI Mono', 'Roboto Mono', Menlo, Courier, monospace;
}

h1,
h2,
h3,
h4,
Expand All @@ -11,6 +11,11 @@ h6 {
font-weight: 600;
letter-spacing: -0.025em;
}

h1,
h2{
font-family: var(--font-geist-mono);
}
kbd {
font-size: 0.875rem;
font-family: var(--default-font-family);
Expand Down
17 changes: 17 additions & 0 deletions packages/app-explorer/src/app/statistics/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { OverlayDialog, Providers } from 'app-portal';
import type { Metadata } from 'next';

export const metadata: Metadata = {
title: 'Statistics',
};

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<Providers>
<OverlayDialog />
{children}
</Providers>
);
}

export const dynamic = 'force-static';
23 changes: 23 additions & 0 deletions packages/app-explorer/src/app/statistics/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use client';
import { Box, Flex } from '@fuels/ui';
import { tv } from 'tailwind-variants';
import { StatisticsScreen } from '~/systems/Statistics/screens/StatisticsScreen';

const Statistics = () => {
const classes = styles();
return (
<Flex justify="center">
<Box className={classes.content()}>
<StatisticsScreen />
</Box>
</Flex>
);
};
const styles = tv({
slots: {
content: 'w-full max-w-[100%]',
},
});
export default Statistics;

export const dynamic = 'force-static';
124 changes: 124 additions & 0 deletions packages/app-explorer/src/systems/Statistics/actions/getAccounts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
'use server';

import { z } from 'zod';
import { act } from '~/systems/Core/utils/act-server';
import { sdk } from '~/systems/Core/utils/sdk';
import {
createIntervals,
getUnitAndInterval,
processAccounts, // You would need to implement this to handle account-specific data
} from '../utils/utils';

const schema = z.object({
timeFilter: z.string().optional().nullable(),
});

interface AccountParams {
timeFilter?: string;
}

interface AccountNode {
__typename: 'Account';
timestamp: string;
}

// Common function to process account statistics
async function fetchAccountStatistics(
params: AccountParams,
fieldName:
| 'accountCreationStatistics'
| 'cumulativeAccountCreationStatistics',
unit: 'minute' | 'hour' | 'day' | 'month',
intervalSize: number,
isCumulative = false,
) {
const data = await (isCumulative
? sdk.cumulativeAccountCreationStatistics(params)
: sdk.accountCreationStatistics(params));

const { nodes, offset } = extractAccountData(data, fieldName);

if (!nodes.length) {
return isCumulative ? { accounts: [], offset: 0 } : { accounts: [] };
}

const firstTimestamp = Number(nodes[0].timestamp);
const lastTimestamp = Number(nodes[nodes.length - 1].timestamp);

const intervalMap = createIntervals(
firstTimestamp,
lastTimestamp,
unit,
intervalSize,
);
const accounts = processAccounts(nodes, intervalMap); // Use this function for account-specific logic
console.log('Account Stats --->', offset, accounts);
if (isCumulative) {
return { accounts, offset };
}

return accounts;
}

// Helper to extract nodes and timestamps from the response
function extractAccountData(
data: any,
fieldName: string,
): { nodes: AccountNode[]; offset?: number } {
const nodes = data.data[fieldName]?.nodes || [];
const offset = data.data[fieldName]?.accountOffset;
return { nodes, offset };
}

async function getCumulativeAccountCreationStats(
params: AccountParams,
unit: 'minute' | 'hour' | 'day' | 'month',
intervalSize: number,
) {
return fetchAccountStatistics(
params,
'cumulativeAccountCreationStatistics',
unit,
intervalSize,
true,
);
}

export async function getAccountCreationStats(
params: AccountParams,
unit: 'minute' | 'hour' | 'day' | 'month',
intervalSize: number,
) {
return fetchAccountStatistics(
params,
'accountCreationStatistics',
unit,
intervalSize,
);
}

export const getAccountStats = act(schema, async ({ timeFilter }) => {
const params = { timeFilter: timeFilter } as { timeFilter?: string };
const { unit, intervalSize } = getUnitAndInterval(params.timeFilter || '');
console.log('Hello its is called');

return getAccountCreationStats(params, unit, intervalSize);
});

export const getDailyAccountCreationStats = act(
schema,
async ({ timeFilter }) => {
const params = { timeFilter: timeFilter } as { timeFilter?: string };
console.log('The timefilter for the new accounts', timeFilter);

// Use 'day' as the unit and 1 as the interval size
return getAccountCreationStats(params, 'day', 1);
},
);

export const getCumulativeAccountStats = act(schema, async ({ timeFilter }) => {
const params = { timeFilter: timeFilter } as { timeFilter?: string };
const { unit, intervalSize } = getUnitAndInterval(params.timeFilter || '');

return getCumulativeAccountCreationStats(params, unit, intervalSize);
});
62 changes: 62 additions & 0 deletions packages/app-explorer/src/systems/Statistics/actions/getBlocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
'use server';

import { z } from 'zod';
import { act } from '~/systems/Core/utils/act-server';
import { sdk } from '~/systems/Core/utils/sdk';
import { DateHelper } from '../utils/date';
import { createIntervals, getUnitAndInterval } from '../utils/utils';

const schema = z.object({
timeFilter: z.string().optional().nullable(),
});

export const getBlockStats = act(schema, async ({ timeFilter }) => {
const params = { timeFilter: timeFilter } as {
timeFilter?: string;
};
const data = await sdk.blockRewardStatistics(params);

if (!data.data.blockRewardStatistics.nodes) {
return {};
}
const { unit, intervalSize } = getUnitAndInterval(params.timeFilter || '');
const nodes = data.data.blockRewardStatistics.nodes;
const firstTimestamp = Number(DateHelper.tai64toDate(nodes[0].timestamp));
const lastTimestamp = Number(
DateHelper.tai64toDate(nodes[nodes.length - 1].timestamp),
);

const intervals = createIntervals(
firstTimestamp,
lastTimestamp,
unit,
intervalSize,
);

const intervalMap = intervals.map((interval) => ({
start: interval.start.toISOString(),
end: interval.end.toISOString(),
count: 0,
totalRewards: 0,
}));

// Process blocks and put them into the correct interval
nodes.forEach((block) => {
const blockTimestamp = Number(DateHelper.tai64toDate(block.timestamp));
const blockReward = Number(block.reward);

// Find the correct interval for the current block
for (const interval of intervalMap) {
const intervalStart = new Date(interval.start).getTime();
const intervalEnd = new Date(interval.end).getTime();

if (blockTimestamp >= intervalStart && blockTimestamp < intervalEnd) {
// Increment count and add the reward to totalRewards
interval.count += 1;
interval.totalRewards += blockReward;
break; // Block has been assigned to the correct interval, no need to check further
}
}
});
return intervalMap;
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
'use server';

import { z } from 'zod';
import { act } from '~/systems/Core/utils/act-server';
import { sdk } from '~/systems/Core/utils/sdk';
import { DateHelper } from '../utils/date';
import {
createIntervals,
getUnitAndInterval,
processTransactions,
} from '../utils/utils';

const schema = z.object({
timeFilter: z.string().optional().nullable(),
});

interface TransactionParams {
timeFilter?: string;
}

interface TransactionNode {
__typename: 'TransactionFee';
fee: string;
timestamp: string;
}

// Common function to process transaction statistics
async function fetchTransactionStatistics(
params: TransactionParams,
fieldName:
| 'transactionsFeeStatistics'
| 'cumulativeTransactionsFeeStatistics',
unit: 'minute' | 'hour' | 'day' | 'month',
intervalSize: number,
isCumulative = false,
) {
const data = await (isCumulative
? sdk.cumulativeTransactionsFeeStatistics(params)
: sdk.transactionsFeeStatistics(params));

const { nodes, offset } = extractTransactionData(data, fieldName);

if (!nodes.length) {
return isCumulative
? { transactions: [], offset: 0 }
: { transactions: [] };
}

const firstTimestamp = Number(DateHelper.tai64toDate(nodes[0].timestamp));
const lastTimestamp = Number(
DateHelper.tai64toDate(nodes[nodes.length - 1].timestamp),
);

const intervalMap = createIntervals(
firstTimestamp,
lastTimestamp,
unit,
intervalSize,
);
const transactions = processTransactions(nodes, intervalMap);

if (isCumulative) {
return { transactions, offset };
}

return transactions;
}

// Helper to extract nodes and timestamps from the response
function extractTransactionData(
data: any,
fieldName: string,
): { nodes: TransactionNode[]; offset?: number } {
const nodes = data.data[fieldName]?.nodes || [];
const offset = data.data[fieldName]?.transactionOffset;
return { nodes, offset };
}

async function getCumulativeTransactionFeeStats(
params: TransactionParams,
unit: 'minute' | 'hour' | 'day' | 'month',
intervalSize: number,
) {
return fetchTransactionStatistics(
params,
'cumulativeTransactionsFeeStatistics',
unit,
intervalSize,
true,
);
}

export async function getTransactionFeeStats(
params: TransactionParams,
unit: 'minute' | 'hour' | 'day' | 'month',
intervalSize: number,
) {
return fetchTransactionStatistics(
params,
'transactionsFeeStatistics',
unit,
intervalSize,
);
}

export const getTransactionStats = act(schema, async ({ timeFilter }) => {
const params = { timeFilter: timeFilter } as { timeFilter?: string };
const { unit, intervalSize } = getUnitAndInterval(params.timeFilter || '');

return getTransactionFeeStats(params, unit, intervalSize);
});

export const getDailyTransactionFeeStats = act(
schema,
async ({ timeFilter }) => {
const params = { timeFilter: timeFilter } as { timeFilter?: string };

// Use 'day' as the unit and 1 as the interval size
return getTransactionFeeStats(params, 'day', 1);
},
);

export const getCumulativeTransactionStats = act(
schema,
async ({ timeFilter }) => {
const params = { timeFilter: timeFilter } as { timeFilter?: string };
const { unit, intervalSize } = getUnitAndInterval(params.timeFilter || '');

return getCumulativeTransactionFeeStats(params, unit, intervalSize);
},
);
Loading