@d13co/algo-metrics-react 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # @d13co/algo-metrics-react
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@d13co/algo-metrics-react)](https://www.npmjs.com/package/@d13co/algo-metrics-react)
4
+
5
+ React hooks for [@d13co/algo-metrics-sdk](https://www.npmjs.com/package/@d13co/algo-metrics-sdk). Wraps the SDK with a single shared watcher callback so multiple components can consume live Algorand block metrics without duplicate network calls.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pnpm add @d13co/algo-metrics-react @d13co/algo-metrics-sdk
11
+ ```
12
+
13
+ React 18 or 19 is required as a peer dependency.
14
+
15
+ ## Quick Start
16
+
17
+ Wrap your app with `AlgoMetricsProvider`, then use hooks anywhere inside:
18
+
19
+ ```tsx
20
+ import { AlgoMetricsProvider, useLatestRound, useTransactionsPerSecond } from '@d13co/algo-metrics-react';
21
+
22
+ function App() {
23
+ return (
24
+ <AlgoMetricsProvider>
25
+ <Dashboard />
26
+ </AlgoMetricsProvider>
27
+ );
28
+ }
29
+
30
+ function Dashboard() {
31
+ const round = useLatestRound();
32
+ const tps = useTransactionsPerSecond();
33
+
34
+ return (
35
+ <div>
36
+ <p>Latest round: {round?.toString() ?? '–'}</p>
37
+ <p>TPS: {tps?.toFixed(1) ?? '–'}</p>
38
+ </div>
39
+ );
40
+ }
41
+ ```
42
+
43
+ ## Provider
44
+
45
+ ### `<AlgoMetricsProvider>`
46
+
47
+ | Prop | Type | Default | Description |
48
+ | --- | --- | --- | --- |
49
+ | `options` | `AlgoMetricsSDKOptions` | `{}` | Options forwarded to `new AlgoMetricsSDK(options)` |
50
+ | `sdk` | `AlgoMetricsSDK` | — | Use an existing SDK instance instead of creating one |
51
+ | `children` | `ReactNode` | — | — |
52
+
53
+ The provider registers a single watcher callback on mount and unregisters on unmount. It auto-detects whether the connected network is mainnet by comparing the genesis hash from `algod.getTransactionParams()`. All hooks derive their values from the shared block data via context.
54
+
55
+ ## Hooks
56
+
57
+ ### `useLatestRound(): bigint | null`
58
+
59
+ Returns the most recent block round number, or `null` while loading.
60
+
61
+ ### `useAverageRoundTime(): number | null`
62
+
63
+ Returns the average time between blocks in seconds, computed as `(last.ts - first.ts) / (blockCount - 1)`.
64
+
65
+ ### `useTransactionsPerSecond(): number | null`
66
+
67
+ Returns the current transactions per second, computed as `(last.tc - first.tc) / (last.ts - first.ts)`.
68
+
69
+ ### `useTransactionCount(): bigint | null`
70
+
71
+ Returns the cumulative transaction count. Adds `563,279` on mainnet to account for the genesis offset.
72
+
73
+ ### `useBlockData(): BlockRoundTimeAndTc[] | null`
74
+
75
+ Returns the raw block data array from the provider.
76
+
77
+ ### `useAlgoMetricsContext(): AlgoMetricsContextValue`
78
+
79
+ Returns the full context value: `{ data, isLoading, sdk, isMainnet }`.
80
+
81
+ ## Pure Functions
82
+
83
+ The compute functions are also exported for use outside of React:
84
+
85
+ ```ts
86
+ import { getLatestRound, getAverageRoundTime, getTransactionsPerSecond, getTransactionCount, MAINNET_TC_OFFSET } from '@d13co/algo-metrics-react';
87
+ ```
88
+
89
+ ## Custom Algorand Client
90
+
91
+ ```tsx
92
+ import { AlgorandClient } from '@algorandfoundation/algokit-utils';
93
+
94
+ <AlgoMetricsProvider options={{ algorand: AlgorandClient.testNet() }}>
95
+ {children}
96
+ </AlgoMetricsProvider>
97
+ ```
98
+
99
+ ## License
100
+
101
+ MIT
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compute.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/compute.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,76 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { getLatestRound, getAverageRoundTime, getTransactionsPerSecond, getTransactionCount, isMainnetGenesisHash, MAINNET_TC_OFFSET, MAINNET_GENESIS_HASH, } from '../compute.js';
3
+ function block(rnd, ts = rnd, tc = rnd * 10) {
4
+ return { rnd: BigInt(rnd), ts, tc: BigInt(tc) };
5
+ }
6
+ describe('getLatestRound', () => {
7
+ it('returns null for empty data', () => {
8
+ expect(getLatestRound([])).toBeNull();
9
+ });
10
+ it('returns the last round number', () => {
11
+ expect(getLatestRound([block(1), block(2), block(3)])).toBe(3n);
12
+ });
13
+ });
14
+ describe('getAverageRoundTime', () => {
15
+ it('returns null for fewer than 2 blocks', () => {
16
+ expect(getAverageRoundTime([])).toBeNull();
17
+ expect(getAverageRoundTime([block(1)])).toBeNull();
18
+ });
19
+ it('computes (last.ts - first.ts) / (length - 1)', () => {
20
+ const data = [block(1, 100), block(2, 103), block(3, 106)];
21
+ expect(getAverageRoundTime(data)).toBe(3);
22
+ });
23
+ it('handles non-uniform timestamps', () => {
24
+ const data = [block(1, 0), block(2, 2), block(3, 10)];
25
+ expect(getAverageRoundTime(data)).toBe(5);
26
+ });
27
+ });
28
+ describe('getTransactionsPerSecond', () => {
29
+ it('returns null for fewer than 2 blocks', () => {
30
+ expect(getTransactionsPerSecond([])).toBeNull();
31
+ expect(getTransactionsPerSecond([block(1)])).toBeNull();
32
+ });
33
+ it('returns null when time diff is zero', () => {
34
+ const data = [block(1, 100, 10), block(2, 100, 20)];
35
+ expect(getTransactionsPerSecond(data)).toBeNull();
36
+ });
37
+ it('computes (last.tc - first.tc) / (last.ts - first.ts)', () => {
38
+ const data = [block(1, 0, 0), block(2, 10, 100)];
39
+ expect(getTransactionsPerSecond(data)).toBe(10);
40
+ });
41
+ });
42
+ describe('getTransactionCount', () => {
43
+ it('returns null for empty data', () => {
44
+ expect(getTransactionCount([], true)).toBeNull();
45
+ });
46
+ it('returns last tc for non-mainnet', () => {
47
+ expect(getTransactionCount([block(1, 1, 500)], false)).toBe(500n);
48
+ });
49
+ it('adds MAINNET_TC_OFFSET for mainnet', () => {
50
+ expect(getTransactionCount([block(1, 1, 500)], true)).toBe(500n + MAINNET_TC_OFFSET);
51
+ });
52
+ });
53
+ describe('MAINNET_TC_OFFSET', () => {
54
+ it('equals 563_279n', () => {
55
+ expect(MAINNET_TC_OFFSET).toBe(563279n);
56
+ });
57
+ });
58
+ describe('isMainnetGenesisHash', () => {
59
+ function b64ToUint8Array(b64) {
60
+ const binary = atob(b64);
61
+ const bytes = new Uint8Array(binary.length);
62
+ for (let i = 0; i < binary.length; i++) {
63
+ bytes[i] = binary.charCodeAt(i);
64
+ }
65
+ return bytes;
66
+ }
67
+ it('returns true for mainnet genesis hash', () => {
68
+ const hash = b64ToUint8Array(MAINNET_GENESIS_HASH);
69
+ expect(isMainnetGenesisHash(hash)).toBe(true);
70
+ });
71
+ it('returns false for a different genesis hash', () => {
72
+ const hash = b64ToUint8Array('SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=');
73
+ expect(isMainnetGenesisHash(hash)).toBe(false);
74
+ });
75
+ });
76
+ //# sourceMappingURL=compute.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute.test.js","sourceRoot":"","sources":["../../src/__tests__/compute.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=hooks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/hooks.test.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,210 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
3
+ import { renderHook, act } from '@testing-library/react';
4
+ import { AlgoMetricsProvider } from '../context.js';
5
+ import { useLatestRound, useAverageRoundTime, useTransactionsPerSecond, useTransactionCount, useBlockData, useAlgoMetricsContext, } from '../index.js';
6
+ import { MAINNET_TC_OFFSET, MAINNET_GENESIS_HASH } from '../compute.js';
7
+ const TESTNET_GENESIS_HASH = 'SGO1GKSzyE7IEPItTxCByw9x8FmnrCDexi9/cOUJOiI=';
8
+ function b64ToUint8Array(b64) {
9
+ const binary = atob(b64);
10
+ const bytes = new Uint8Array(binary.length);
11
+ for (let i = 0; i < binary.length; i++) {
12
+ bytes[i] = binary.charCodeAt(i);
13
+ }
14
+ return bytes;
15
+ }
16
+ function block(rnd, ts = rnd, tc = rnd * 10) {
17
+ return { rnd: BigInt(rnd), ts, tc: BigInt(tc) };
18
+ }
19
+ const testBlocks = [block(1, 100, 1000), block(2, 103, 1050), block(3, 106, 1100)];
20
+ function createMockSDK(genesisHashB64 = MAINNET_GENESIS_HASH) {
21
+ let capturedCallback = null;
22
+ const mock = {
23
+ registerTsTcWatcher: vi.fn(async (cb) => {
24
+ capturedCallback = cb;
25
+ }),
26
+ unregisterTsTcWatcher: vi.fn(),
27
+ algorand: {
28
+ client: {
29
+ algod: {
30
+ getTransactionParams: vi.fn(() => ({
31
+ do: vi.fn(async () => ({
32
+ genesisHash: b64ToUint8Array(genesisHashB64),
33
+ })),
34
+ })),
35
+ },
36
+ },
37
+ },
38
+ };
39
+ return {
40
+ sdk: mock,
41
+ mock,
42
+ emitBlocks: (blocks) => {
43
+ act(() => {
44
+ capturedCallback?.(blocks);
45
+ });
46
+ },
47
+ };
48
+ }
49
+ function createWrapper(sdk) {
50
+ return function Wrapper({ children }) {
51
+ return _jsx(AlgoMetricsProvider, { sdk: sdk, children: children });
52
+ };
53
+ }
54
+ describe('AlgoMetricsProvider', () => {
55
+ beforeEach(() => {
56
+ vi.restoreAllMocks();
57
+ });
58
+ it('registers watcher on mount and unregisters on unmount', () => {
59
+ const { sdk, mock } = createMockSDK();
60
+ const { unmount } = renderHook(() => useAlgoMetricsContext(), {
61
+ wrapper: createWrapper(sdk),
62
+ });
63
+ expect(mock.registerTsTcWatcher).toHaveBeenCalledOnce();
64
+ unmount();
65
+ expect(mock.unregisterTsTcWatcher).toHaveBeenCalledOnce();
66
+ });
67
+ it('starts in loading state with null data', () => {
68
+ const { sdk } = createMockSDK();
69
+ const { result } = renderHook(() => useAlgoMetricsContext(), {
70
+ wrapper: createWrapper(sdk),
71
+ });
72
+ expect(result.current.isLoading).toBe(true);
73
+ expect(result.current.data).toBeNull();
74
+ });
75
+ it('updates data when callback fires', () => {
76
+ const { sdk, emitBlocks } = createMockSDK();
77
+ const { result } = renderHook(() => useAlgoMetricsContext(), {
78
+ wrapper: createWrapper(sdk),
79
+ });
80
+ emitBlocks(testBlocks);
81
+ expect(result.current.isLoading).toBe(false);
82
+ expect(result.current.data).toEqual(testBlocks);
83
+ });
84
+ it('auto-detects mainnet from genesis hash', async () => {
85
+ const { sdk, emitBlocks } = createMockSDK(MAINNET_GENESIS_HASH);
86
+ const { result } = renderHook(() => useAlgoMetricsContext(), {
87
+ wrapper: createWrapper(sdk),
88
+ });
89
+ emitBlocks(testBlocks);
90
+ await vi.waitFor(() => {
91
+ expect(result.current.isMainnet).toBe(true);
92
+ });
93
+ });
94
+ it('auto-detects non-mainnet from genesis hash', async () => {
95
+ const { sdk, emitBlocks } = createMockSDK(TESTNET_GENESIS_HASH);
96
+ const { result } = renderHook(() => useAlgoMetricsContext(), {
97
+ wrapper: createWrapper(sdk),
98
+ });
99
+ emitBlocks(testBlocks);
100
+ await vi.waitFor(() => {
101
+ expect(result.current.isMainnet).toBe(false);
102
+ });
103
+ });
104
+ });
105
+ describe('useLatestRound', () => {
106
+ it('returns null before data arrives', () => {
107
+ const { sdk } = createMockSDK();
108
+ const { result } = renderHook(() => useLatestRound(), {
109
+ wrapper: createWrapper(sdk),
110
+ });
111
+ expect(result.current).toBeNull();
112
+ });
113
+ it('returns the latest round', () => {
114
+ const { sdk, emitBlocks } = createMockSDK();
115
+ const { result } = renderHook(() => useLatestRound(), {
116
+ wrapper: createWrapper(sdk),
117
+ });
118
+ emitBlocks(testBlocks);
119
+ expect(result.current).toBe(3n);
120
+ });
121
+ });
122
+ describe('useAverageRoundTime', () => {
123
+ it('returns null before data arrives', () => {
124
+ const { sdk } = createMockSDK();
125
+ const { result } = renderHook(() => useAverageRoundTime(), {
126
+ wrapper: createWrapper(sdk),
127
+ });
128
+ expect(result.current).toBeNull();
129
+ });
130
+ it('computes average round time', () => {
131
+ const { sdk, emitBlocks } = createMockSDK();
132
+ const { result } = renderHook(() => useAverageRoundTime(), {
133
+ wrapper: createWrapper(sdk),
134
+ });
135
+ emitBlocks(testBlocks);
136
+ expect(result.current).toBe(3);
137
+ });
138
+ });
139
+ describe('useTransactionsPerSecond', () => {
140
+ it('returns null before data arrives', () => {
141
+ const { sdk } = createMockSDK();
142
+ const { result } = renderHook(() => useTransactionsPerSecond(), {
143
+ wrapper: createWrapper(sdk),
144
+ });
145
+ expect(result.current).toBeNull();
146
+ });
147
+ it('computes TPS', () => {
148
+ const { sdk, emitBlocks } = createMockSDK();
149
+ const { result } = renderHook(() => useTransactionsPerSecond(), {
150
+ wrapper: createWrapper(sdk),
151
+ });
152
+ // tc diff = 1100 - 1000 = 100, ts diff = 106 - 100 = 6
153
+ emitBlocks(testBlocks);
154
+ expect(result.current).toBeCloseTo(100 / 6);
155
+ });
156
+ });
157
+ describe('useTransactionCount', () => {
158
+ it('returns null before data arrives', () => {
159
+ const { sdk } = createMockSDK();
160
+ const { result } = renderHook(() => useTransactionCount(), {
161
+ wrapper: createWrapper(sdk),
162
+ });
163
+ expect(result.current).toBeNull();
164
+ });
165
+ it('applies mainnet offset when connected to mainnet', async () => {
166
+ const { sdk, emitBlocks } = createMockSDK(MAINNET_GENESIS_HASH);
167
+ const { result } = renderHook(() => useTransactionCount(), {
168
+ wrapper: createWrapper(sdk),
169
+ });
170
+ emitBlocks(testBlocks);
171
+ await vi.waitFor(() => {
172
+ expect(result.current).toBe(1100n + MAINNET_TC_OFFSET);
173
+ });
174
+ });
175
+ it('does not apply offset when connected to testnet', async () => {
176
+ const { sdk, emitBlocks } = createMockSDK(TESTNET_GENESIS_HASH);
177
+ const { result } = renderHook(() => useTransactionCount(), {
178
+ wrapper: createWrapper(sdk),
179
+ });
180
+ emitBlocks(testBlocks);
181
+ await vi.waitFor(() => {
182
+ expect(result.current).toBe(1100n);
183
+ });
184
+ });
185
+ });
186
+ describe('useBlockData', () => {
187
+ it('returns null before data arrives', () => {
188
+ const { sdk } = createMockSDK();
189
+ const { result } = renderHook(() => useBlockData(), {
190
+ wrapper: createWrapper(sdk),
191
+ });
192
+ expect(result.current).toBeNull();
193
+ });
194
+ it('returns raw block data', () => {
195
+ const { sdk, emitBlocks } = createMockSDK();
196
+ const { result } = renderHook(() => useBlockData(), {
197
+ wrapper: createWrapper(sdk),
198
+ });
199
+ emitBlocks(testBlocks);
200
+ expect(result.current).toEqual(testBlocks);
201
+ });
202
+ });
203
+ describe('useAlgoMetricsContext', () => {
204
+ it('throws when used outside provider', () => {
205
+ expect(() => {
206
+ renderHook(() => useAlgoMetricsContext());
207
+ }).toThrow('useAlgoMetricsContext must be used within an AlgoMetricsProvider');
208
+ });
209
+ });
210
+ //# sourceMappingURL=hooks.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.test.js","sourceRoot":"","sources":["../../src/__tests__/hooks.test.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { BlockRoundTimeAndTc } from '@d13co/algo-metrics-sdk';
2
+ export declare const MAINNET_TC_OFFSET = 563279n;
3
+ export declare const MAINNET_GENESIS_HASH = "wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=";
4
+ export declare function isMainnetGenesisHash(genesisHash: Uint8Array): boolean;
5
+ export declare function getLatestRound(data: BlockRoundTimeAndTc[]): bigint | null;
6
+ export declare function getAverageRoundTime(data: BlockRoundTimeAndTc[]): number | null;
7
+ export declare function getTransactionsPerSecond(data: BlockRoundTimeAndTc[]): number | null;
8
+ export declare function getTransactionCount(data: BlockRoundTimeAndTc[], isMainnet: boolean): bigint | null;
9
+ //# sourceMappingURL=compute.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute.d.ts","sourceRoot":"","sources":["../src/compute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,eAAO,MAAM,iBAAiB,UAAW,CAAC;AAE1C,eAAO,MAAM,oBAAoB,iDAAiD,CAAC;AAEnF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,UAAU,GAAG,OAAO,CAGrE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,MAAM,GAAG,IAAI,CAGzE;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,MAAM,GAAG,IAAI,CAK9E;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,mBAAmB,EAAE,GAAG,MAAM,GAAG,IAAI,CAOnF;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,mBAAmB,EAAE,EAC3B,SAAS,EAAE,OAAO,GACjB,MAAM,GAAG,IAAI,CAIf"}
@@ -0,0 +1,35 @@
1
+ export const MAINNET_TC_OFFSET = 563279n;
2
+ export const MAINNET_GENESIS_HASH = 'wGHE2Pwdvd7S12BL5FaOP20EGYesN73ktiC1qzkkit8=';
3
+ export function isMainnetGenesisHash(genesisHash) {
4
+ const b64 = btoa(String.fromCharCode(...genesisHash));
5
+ return b64 === MAINNET_GENESIS_HASH;
6
+ }
7
+ export function getLatestRound(data) {
8
+ if (data.length === 0)
9
+ return null;
10
+ return data[data.length - 1].rnd;
11
+ }
12
+ export function getAverageRoundTime(data) {
13
+ if (data.length < 2)
14
+ return null;
15
+ const first = data[0];
16
+ const last = data[data.length - 1];
17
+ return (last.ts - first.ts) / (data.length - 1);
18
+ }
19
+ export function getTransactionsPerSecond(data) {
20
+ if (data.length < 2)
21
+ return null;
22
+ const first = data[0];
23
+ const last = data[data.length - 1];
24
+ const timeDiff = last.ts - first.ts;
25
+ if (timeDiff === 0)
26
+ return null;
27
+ return Number(last.tc - first.tc) / timeDiff;
28
+ }
29
+ export function getTransactionCount(data, isMainnet) {
30
+ if (data.length === 0)
31
+ return null;
32
+ const lastTc = data[data.length - 1].tc;
33
+ return isMainnet ? lastTc + MAINNET_TC_OFFSET : lastTc;
34
+ }
35
+ //# sourceMappingURL=compute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compute.js","sourceRoot":"","sources":["../src/compute.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAQ,CAAC;AAE1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,8CAA8C,CAAC;AAEnF,MAAM,UAAU,oBAAoB,CAAC,WAAuB;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC;IACtD,OAAO,GAAG,KAAK,oBAAoB,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAA2B;IACxD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,GAAG,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAA2B;IAC7D,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;IACvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;IACpC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,IAA2B;IAClE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;IACvB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;IACpC,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,IAA2B,EAC3B,SAAkB;IAElB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAE,CAAC,EAAE,CAAC;IACzC,OAAO,SAAS,CAAC,CAAC,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,MAAM,CAAC;AACzD,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { AlgoMetricsContextValue, AlgoMetricsProviderProps } from './types.js';
2
+ export declare function AlgoMetricsProvider({ options, sdk: externalSdk, children, }: AlgoMetricsProviderProps): React.JSX.Element;
3
+ export declare function useAlgoMetricsContext(): AlgoMetricsContextValue;
4
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAKpF,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACP,GAAG,EAAE,WAAW,EAChB,QAAQ,GACT,EAAE,wBAAwB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA4C9C;AAED,wBAAgB,qBAAqB,IAAI,uBAAuB,CAM/D"}
@@ -0,0 +1,48 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useEffect, useMemo, useState } from 'react';
3
+ import { AlgoMetricsSDK } from '@d13co/algo-metrics-sdk';
4
+ import { isMainnetGenesisHash } from './compute.js';
5
+ const AlgoMetricsContext = createContext(null);
6
+ export function AlgoMetricsProvider({ options, sdk: externalSdk, children, }) {
7
+ const sdk = useMemo(() => externalSdk ?? new AlgoMetricsSDK(options), [externalSdk, options]);
8
+ const [data, setData] = useState(null);
9
+ const [isLoading, setIsLoading] = useState(true);
10
+ const [isMainnet, setIsMainnet] = useState(true);
11
+ useEffect(() => {
12
+ const controller = new AbortController();
13
+ void (async () => {
14
+ try {
15
+ const params = await sdk.algorand.client.algod.getTransactionParams().do();
16
+ if (!controller.signal.aborted) {
17
+ setIsMainnet(isMainnetGenesisHash(params.genesisHash));
18
+ }
19
+ }
20
+ catch {
21
+ // detection failed — keep default (true)
22
+ }
23
+ })();
24
+ return () => {
25
+ controller.abort();
26
+ };
27
+ }, [sdk]);
28
+ useEffect(() => {
29
+ const callback = (blocks) => {
30
+ setData(blocks);
31
+ setIsLoading(false);
32
+ };
33
+ void sdk.registerTsTcWatcher(callback, { numBlocks: 1000 });
34
+ return () => {
35
+ sdk.unregisterTsTcWatcher(callback);
36
+ };
37
+ }, [sdk]);
38
+ const value = useMemo(() => ({ data, isLoading, sdk, isMainnet }), [data, isLoading, sdk, isMainnet]);
39
+ return _jsx(AlgoMetricsContext, { value: value, children: children });
40
+ }
41
+ export function useAlgoMetricsContext() {
42
+ const context = useContext(AlgoMetricsContext);
43
+ if (context === null) {
44
+ throw new Error('useAlgoMetricsContext must be used within an AlgoMetricsProvider');
45
+ }
46
+ return context;
47
+ }
48
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAChF,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,kBAAkB,GAAG,aAAa,CAAiC,IAAI,CAAC,CAAC;AAE/E,MAAM,UAAU,mBAAmB,CAAC,EAClC,OAAO,EACP,GAAG,EAAE,WAAW,EAChB,QAAQ,GACiB;IACzB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,WAAW,IAAI,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAE9F,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAA+B,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IACjD,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEjD,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,KAAK,CAAC,KAAK,IAAmB,EAAE;YAC9B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3E,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBAC/B,YAAY,CAAC,oBAAoB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,yCAAyC;YAC3C,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;QAEL,OAAO,GAAS,EAAE;YAChB,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,QAAQ,GAAG,CAAC,MAA6B,EAAQ,EAAE;YACvD,OAAO,CAAC,MAAM,CAAC,CAAC;YAChB,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC,CAAC;QAEF,KAAK,GAAG,CAAC,mBAAmB,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE5D,OAAO,GAAS,EAAE;YAChB,GAAG,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,MAAM,KAAK,GAAG,OAAO,CACnB,GAA4B,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EACpE,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,SAAS,CAAC,CAClC,CAAC;IAEF,OAAO,KAAC,kBAAkB,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAAsB,CAAC;AAC3E,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,OAAO,GAAG,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC/C,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { BlockRoundTimeAndTc } from '@d13co/algo-metrics-sdk';
2
+ export declare function useLatestRound(): bigint | null;
3
+ export declare function useAverageRoundTime(): number | null;
4
+ export declare function useTransactionsPerSecond(): number | null;
5
+ export declare function useTransactionCount(): bigint | null;
6
+ export declare function useBlockData(): BlockRoundTimeAndTc[] | null;
7
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AASnE,wBAAgB,cAAc,IAAI,MAAM,GAAG,IAAI,CAG9C;AAED,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAGnD;AAED,wBAAgB,wBAAwB,IAAI,MAAM,GAAG,IAAI,CAGxD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAGnD;AAED,wBAAgB,YAAY,IAAI,mBAAmB,EAAE,GAAG,IAAI,CAG3D"}
package/dist/hooks.js ADDED
@@ -0,0 +1,24 @@
1
+ import { useMemo } from 'react';
2
+ import { useAlgoMetricsContext } from './context.js';
3
+ import { getLatestRound, getAverageRoundTime, getTransactionsPerSecond, getTransactionCount, } from './compute.js';
4
+ export function useLatestRound() {
5
+ const { data } = useAlgoMetricsContext();
6
+ return useMemo(() => (data ? getLatestRound(data) : null), [data]);
7
+ }
8
+ export function useAverageRoundTime() {
9
+ const { data } = useAlgoMetricsContext();
10
+ return useMemo(() => (data ? getAverageRoundTime(data) : null), [data]);
11
+ }
12
+ export function useTransactionsPerSecond() {
13
+ const { data } = useAlgoMetricsContext();
14
+ return useMemo(() => (data ? getTransactionsPerSecond(data) : null), [data]);
15
+ }
16
+ export function useTransactionCount() {
17
+ const { data, isMainnet } = useAlgoMetricsContext();
18
+ return useMemo(() => (data ? getTransactionCount(data, isMainnet) : null), [data, isMainnet]);
19
+ }
20
+ export function useBlockData() {
21
+ const { data } = useAlgoMetricsContext();
22
+ return data;
23
+ }
24
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,cAAc,CAAC;AAEtB,MAAM,UAAU,cAAc;IAC5B,MAAM,EAAE,IAAI,EAAE,GAAG,qBAAqB,EAAE,CAAC;IACzC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,MAAM,EAAE,IAAI,EAAE,GAAG,qBAAqB,EAAE,CAAC;IACzC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,MAAM,EAAE,IAAI,EAAE,GAAG,qBAAqB,EAAE,CAAC;IACzC,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,qBAAqB,EAAE,CAAC;IACpD,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC;AAChG,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,EAAE,IAAI,EAAE,GAAG,qBAAqB,EAAE,CAAC;IACzC,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { AlgoMetricsProvider, useAlgoMetricsContext } from './context.js';
2
+ export { useLatestRound, useAverageRoundTime, useTransactionsPerSecond, useTransactionCount, useBlockData, } from './hooks.js';
3
+ export { getLatestRound, getAverageRoundTime, getTransactionsPerSecond, getTransactionCount, isMainnetGenesisHash, MAINNET_TC_OFFSET, MAINNET_GENESIS_HASH, } from './compute.js';
4
+ export type { AlgoMetricsContextValue, AlgoMetricsProviderProps } from './types.js';
5
+ export type { BlockRoundTimeAndTc } from '@d13co/algo-metrics-sdk';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,uBAAuB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AACpF,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { AlgoMetricsProvider, useAlgoMetricsContext } from './context.js';
2
+ export { useLatestRound, useAverageRoundTime, useTransactionsPerSecond, useTransactionCount, useBlockData, } from './hooks.js';
3
+ export { getLatestRound, getAverageRoundTime, getTransactionsPerSecond, getTransactionCount, isMainnetGenesisHash, MAINNET_TC_OFFSET, MAINNET_GENESIS_HASH, } from './compute.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,cAAc,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { BlockRoundTimeAndTc, AlgoMetricsSDK, AlgoMetricsSDKOptions } from '@d13co/algo-metrics-sdk';
2
+ export interface AlgoMetricsContextValue {
3
+ data: BlockRoundTimeAndTc[] | null;
4
+ isLoading: boolean;
5
+ sdk: AlgoMetricsSDK;
6
+ isMainnet: boolean;
7
+ }
8
+ export interface AlgoMetricsProviderProps {
9
+ options?: AlgoMetricsSDKOptions;
10
+ sdk?: AlgoMetricsSDK;
11
+ children: React.ReactNode;
12
+ }
13
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC;IACnC,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,cAAc,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@d13co/algo-metrics-react",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "React hooks for @d13co/algo-metrics-sdk",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git@github.com:d13co/algo-metrics-sdk.git",
25
+ "directory": "packages/react"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/d13co/algo-metrics-sdk/issues"
29
+ },
30
+ "homepage": "https://github.com/d13co/algo-metrics-sdk/tree/main/packages/react#readme",
31
+ "dependencies": {
32
+ "@d13co/algo-metrics-sdk": "1.0.0"
33
+ },
34
+ "peerDependencies": {
35
+ "react": "^18.0.0 || ^19.0.0"
36
+ },
37
+ "scripts": {
38
+ "build": "tsc"
39
+ }
40
+ }