@xyo-network/xl1-react-transaction 1.16.23

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.
Files changed (56) hide show
  1. package/LICENSE +165 -0
  2. package/README.md +2234 -0
  3. package/dist/browser/confirmation/components/TransactionStackProgress.d.ts +10 -0
  4. package/dist/browser/confirmation/components/TransactionStackProgress.d.ts.map +1 -0
  5. package/dist/browser/confirmation/components/TransactionStackProgress.stories.d.ts +13 -0
  6. package/dist/browser/confirmation/components/TransactionStackProgress.stories.d.ts.map +1 -0
  7. package/dist/browser/confirmation/components/index.d.ts +2 -0
  8. package/dist/browser/confirmation/components/index.d.ts.map +1 -0
  9. package/dist/browser/confirmation/components/support/BlockConfirmationStats.d.ts +9 -0
  10. package/dist/browser/confirmation/components/support/BlockConfirmationStats.d.ts.map +1 -0
  11. package/dist/browser/confirmation/components/support/BlockRangeEntryStack.d.ts +17 -0
  12. package/dist/browser/confirmation/components/support/BlockRangeEntryStack.d.ts.map +1 -0
  13. package/dist/browser/confirmation/components/support/index.d.ts +3 -0
  14. package/dist/browser/confirmation/components/support/index.d.ts.map +1 -0
  15. package/dist/browser/confirmation/helpers/BlockFormatters.d.ts +14 -0
  16. package/dist/browser/confirmation/helpers/BlockFormatters.d.ts.map +1 -0
  17. package/dist/browser/confirmation/helpers/blockProgressColor.d.ts +3 -0
  18. package/dist/browser/confirmation/helpers/blockProgressColor.d.ts.map +1 -0
  19. package/dist/browser/confirmation/helpers/createFilledRange.d.ts +2 -0
  20. package/dist/browser/confirmation/helpers/createFilledRange.d.ts.map +1 -0
  21. package/dist/browser/confirmation/helpers/getBlockProgress.d.ts +2 -0
  22. package/dist/browser/confirmation/helpers/getBlockProgress.d.ts.map +1 -0
  23. package/dist/browser/confirmation/helpers/index.d.ts +7 -0
  24. package/dist/browser/confirmation/helpers/index.d.ts.map +1 -0
  25. package/dist/browser/confirmation/helpers/isCurrentBlockPassedRange.d.ts +3 -0
  26. package/dist/browser/confirmation/helpers/isCurrentBlockPassedRange.d.ts.map +1 -0
  27. package/dist/browser/confirmation/helpers/passedBlocksInRange.d.ts +2 -0
  28. package/dist/browser/confirmation/helpers/passedBlocksInRange.d.ts.map +1 -0
  29. package/dist/browser/confirmation/hooks/index.d.ts +2 -0
  30. package/dist/browser/confirmation/hooks/index.d.ts.map +1 -0
  31. package/dist/browser/confirmation/hooks/useBlockRangeState.d.ts +9 -0
  32. package/dist/browser/confirmation/hooks/useBlockRangeState.d.ts.map +1 -0
  33. package/dist/browser/confirmation/index.d.ts +4 -0
  34. package/dist/browser/confirmation/index.d.ts.map +1 -0
  35. package/dist/browser/index.d.ts +2 -0
  36. package/dist/browser/index.d.ts.map +1 -0
  37. package/dist/browser/index.mjs +299 -0
  38. package/dist/browser/index.mjs.map +1 -0
  39. package/package.json +77 -0
  40. package/src/confirmation/components/TransactionStackProgress.stories.tsx +56 -0
  41. package/src/confirmation/components/TransactionStackProgress.tsx +83 -0
  42. package/src/confirmation/components/index.ts +1 -0
  43. package/src/confirmation/components/support/BlockConfirmationStats.tsx +43 -0
  44. package/src/confirmation/components/support/BlockRangeEntryStack.tsx +64 -0
  45. package/src/confirmation/components/support/index.ts +2 -0
  46. package/src/confirmation/helpers/BlockFormatters.ts +52 -0
  47. package/src/confirmation/helpers/blockProgressColor.ts +15 -0
  48. package/src/confirmation/helpers/createFilledRange.ts +20 -0
  49. package/src/confirmation/helpers/getBlockProgress.ts +22 -0
  50. package/src/confirmation/helpers/index.ts +6 -0
  51. package/src/confirmation/helpers/isCurrentBlockPassedRange.ts +13 -0
  52. package/src/confirmation/helpers/passedBlocksInRange.ts +12 -0
  53. package/src/confirmation/hooks/index.ts +1 -0
  54. package/src/confirmation/hooks/useBlockRangeState.ts +27 -0
  55. package/src/confirmation/index.ts +3 -0
  56. package/src/index.ts +1 -0
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "$schema": "http://json.schemastore.org/package.json",
3
+ "name": "@xyo-network/xl1-react-transaction",
4
+ "version": "1.16.23",
5
+ "description": "XYO Layer One API",
6
+ "homepage": "https://xylabs.com",
7
+ "bugs": {
8
+ "url": "git+https://github.com/xylabs/xyo-chain/issues",
9
+ "email": "support@xylabs.com"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/xylabs/xyo-chain.git"
14
+ },
15
+ "license": "LGPL-3.0-only",
16
+ "author": {
17
+ "name": "XY Labs Development Team",
18
+ "email": "support@xylabs.com",
19
+ "url": "https://xylabs.com"
20
+ },
21
+ "sideEffects": false,
22
+ "type": "module",
23
+ "exports": {
24
+ ".": {
25
+ "browser": {
26
+ "types": "./dist/browser/index.d.ts",
27
+ "source": "./src/index.ts",
28
+ "default": "./dist/browser/index.mjs"
29
+ },
30
+ "types": "./dist/browser/index.d.ts",
31
+ "source": "./src/index.ts",
32
+ "default": "./dist/browser/index.mjs"
33
+ },
34
+ "./package.json": "./package.json"
35
+ },
36
+ "module": "./dist/browser/index.mjs",
37
+ "source": "./src/index.ts",
38
+ "types": "./dist/browser/index.d.ts",
39
+ "files": [
40
+ "dist",
41
+ "src",
42
+ "!**/*.bench.*",
43
+ "!**/*.spec.*",
44
+ "!**/*.test.*"
45
+ ],
46
+ "dependencies": {
47
+ "@mui/icons-material": "~7.3.5",
48
+ "@mui/material": "~7.3.5",
49
+ "@xylabs/sdk-js": "~5.0.39",
50
+ "@xyo-network/xl1-protocol": "~1.13.13"
51
+ },
52
+ "devDependencies": {
53
+ "@emotion/react": "~11.14.0",
54
+ "@emotion/styled": "~11.14.1",
55
+ "@storybook/react-vite": "~10.0.8",
56
+ "@types/react": "~19.2.6",
57
+ "@xylabs/ts-scripts-yarn3": "~7.2.8",
58
+ "@xylabs/tsconfig": "~7.2.8",
59
+ "@xylabs/tsconfig-dom": "~7.2.8",
60
+ "@xylabs/tsconfig-react": "~7.2.8",
61
+ "typescript": "~5.9.3"
62
+ },
63
+ "peerDependencies": {
64
+ "react": "~19.1.1"
65
+ },
66
+ "packageManager": "yarn@4.6.0",
67
+ "engines": {
68
+ "node": ">=22"
69
+ },
70
+ "volta": {
71
+ "node": "22.5.1",
72
+ "yarn": "4.6.0"
73
+ },
74
+ "publishConfig": {
75
+ "access": "public"
76
+ }
77
+ }
@@ -0,0 +1,56 @@
1
+ import type { StoryFn } from '@storybook/react-vite'
2
+ import { isUndefined } from '@xylabs/sdk-js'
3
+ import { asBlockRange } from '@xyo-network/xl1-protocol'
4
+ import React, { useEffect, useState } from 'react'
5
+
6
+ import { TransactionStackProgress } from './TransactionStackProgress.tsx'
7
+
8
+ export default {
9
+ title: 'transaction/stack/progress',
10
+ component: TransactionStackProgress,
11
+ }
12
+
13
+ const START_BLOCK = 100_001
14
+ const END_BLOCK = 100_010
15
+
16
+ const Template: StoryFn<typeof TransactionStackProgress> = args => <TransactionStackProgress {...args} />
17
+ const TemplateWithChangingValues: StoryFn<typeof TransactionStackProgress> = (args) => {
18
+ const [currentBlockNumber, setCurrentBlockNumber] = useState<number>()
19
+ useEffect(() => {
20
+ const interval = setInterval(() => {
21
+ setCurrentBlockNumber((prev) => {
22
+ if (isUndefined(prev)) {
23
+ return START_BLOCK
24
+ }
25
+ if (prev >= END_BLOCK + 2) {
26
+ return START_BLOCK
27
+ }
28
+ return prev + 1
29
+ })
30
+ }, 1000)
31
+ return () => clearInterval(interval)
32
+ }, [])
33
+ return <TransactionStackProgress currentBlockNumber={currentBlockNumber} {...args} />
34
+ }
35
+
36
+ const Default = Template.bind({})
37
+ Default.args = {}
38
+
39
+ const WithValues = Template.bind({})
40
+ WithValues.args = { currentBlockNumber: 100_003, blockRange: asBlockRange([START_BLOCK, END_BLOCK]) }
41
+
42
+ const WithConfirmed = Template.bind({})
43
+ WithConfirmed.args = {
44
+ currentBlockNumber: 100_004, blockRange: asBlockRange([START_BLOCK, END_BLOCK]), confirmedInBlock: 100_004,
45
+ }
46
+
47
+ const WithExpired = Template.bind({})
48
+ WithExpired.args = { currentBlockNumber: END_BLOCK + 2, blockRange: asBlockRange([START_BLOCK, END_BLOCK]) }
49
+
50
+ const WithChangingValues = TemplateWithChangingValues.bind({})
51
+ WithChangingValues.args = { blockRange: asBlockRange([START_BLOCK, END_BLOCK]) }
52
+
53
+ export {
54
+ Default, WithChangingValues, WithConfirmed, WithExpired,
55
+ WithValues,
56
+ }
@@ -0,0 +1,83 @@
1
+ import type { StackProps } from '@mui/material'
2
+ import { LinearProgress, Stack } from '@mui/material'
3
+ import { isDefined } from '@xylabs/sdk-js'
4
+ import { type BlockRange } from '@xyo-network/xl1-protocol'
5
+ import React, {
6
+ useLayoutEffect,
7
+ useMemo,
8
+ useRef, useState,
9
+ } from 'react'
10
+
11
+ import { BlockFormatters, getBlockProgress } from '../helpers/index.ts'
12
+ import { useBlockRangeState } from '../hooks/index.ts'
13
+ import { BlockConfirmationStats, BlockRangeEntryStack } from './support/index.ts'
14
+
15
+ export interface TransactionStackProgressProps extends StackProps {
16
+ blockRange?: BlockRange
17
+ confirmedInBlock?: number
18
+ currentBlockNumber?: number
19
+ }
20
+
21
+ export const TransactionStackProgress: React.FC<TransactionStackProgressProps> = ({
22
+ blockRange, confirmedInBlock, currentBlockNumber, ...props
23
+ }) => {
24
+ const blockPositionRefs = useRef<{ [blockNumber: number]: HTMLSpanElement | null }>({})
25
+ const progressElementRef = useRef<HTMLDivElement | null>(null)
26
+
27
+ const {
28
+ passedBlocks, progressColor, range, isConfirmed, isExpired,
29
+ } = useBlockRangeState(blockRange, confirmedInBlock, currentBlockNumber)
30
+
31
+ const blockFormatters = useMemo(() => new BlockFormatters({ confirmedInBlock, currentBlockNumber }), [confirmedInBlock, currentBlockNumber])
32
+
33
+ const [progressValue, setProgressValue] = useState(0)
34
+
35
+ useLayoutEffect(() => {
36
+ // prevent updates if the current block is past the confirmed block
37
+ if (isDefined(currentBlockNumber) && isDefined(confirmedInBlock) && currentBlockNumber > confirmedInBlock) {
38
+ return
39
+ }
40
+ const currentBlockNumberElement = isDefined(currentBlockNumber) ? blockPositionRefs.current[currentBlockNumber] : null
41
+ const progressElement = progressElementRef.current
42
+ // since we are relying on htmlElements, we have to use layout effect
43
+ // eslint-disable-next-line react-hooks-extra/no-direct-set-state-in-use-effect
44
+ setProgressValue(getBlockProgress(
45
+ currentBlockNumber,
46
+ currentBlockNumberElement,
47
+ progressElement,
48
+ ))
49
+ }, [currentBlockNumber])
50
+
51
+ return (
52
+ <Stack direction="row" {...props}>
53
+ <Stack width="100%" gap={1}>
54
+ <Stack>
55
+ <LinearProgress ref={progressElementRef} variant="determinate" value={isExpired ? 100 : progressValue} color={progressColor} />
56
+ <Stack direction="row" justifyContent="space-between">
57
+ {range.map((block) => {
58
+ const blockColor = blockFormatters.color(block)
59
+ const blockStatus = blockFormatters.confirmationStatus(block)
60
+ const formattedBlockNumber = blockFormatters.formatNumber(block)
61
+ return (
62
+ <BlockRangeEntryStack
63
+ key={block}
64
+ blockPositionRefs={blockPositionRefs}
65
+ block={block}
66
+ blockColor={blockColor}
67
+ blockStatus={blockStatus}
68
+ formattedBlockNumber={formattedBlockNumber}
69
+ />
70
+ )
71
+ })}
72
+ </Stack>
73
+ </Stack>
74
+ <BlockConfirmationStats
75
+ confirmed={isConfirmed}
76
+ currentBlockColor={isDefined(currentBlockNumber) ? blockFormatters.color(currentBlockNumber) : 'text.secondary'}
77
+ currentBlockNumberValue={isDefined(currentBlockNumber) ? new Intl.NumberFormat().format(currentBlockNumber) : 'N/A'}
78
+ passedBlocks={passedBlocks}
79
+ />
80
+ </Stack>
81
+ </Stack>
82
+ )
83
+ }
@@ -0,0 +1 @@
1
+ export * from './TransactionStackProgress.tsx'
@@ -0,0 +1,43 @@
1
+ import { CheckCircleOutline } from '@mui/icons-material'
2
+ import {
3
+ Grow, Stack, Typography,
4
+ } from '@mui/material'
5
+ import { isDefined } from '@xylabs/sdk-js'
6
+ import React from 'react'
7
+
8
+ export interface BlockConfirmationStatsProps {
9
+ confirmed?: boolean
10
+ currentBlockColor?: string
11
+ currentBlockNumberValue?: string
12
+ passedBlocks?: number[]
13
+ }
14
+
15
+ export const BlockConfirmationStats: React.FC<BlockConfirmationStatsProps> = ({
16
+ confirmed, currentBlockColor, currentBlockNumberValue, passedBlocks,
17
+ }) => {
18
+ return (
19
+ <Stack>
20
+ <Typography
21
+ variant="caption"
22
+ color={currentBlockColor}
23
+ sx={{
24
+ display: 'inline-flex', alignItems: 'center', gap: 0.5,
25
+ }}
26
+ >
27
+ Current Block:
28
+ {' '}
29
+ {currentBlockNumberValue}
30
+ {' '}
31
+ <Grow in={confirmed}>
32
+ <CheckCircleOutline sx={{ width: '0.8em', height: '0.8em' }} color="success" />
33
+ </Grow>
34
+ </Typography>
35
+ <Typography variant="caption" color="warning.light" sx={{ opacity: 0.75 }}>
36
+ Passed Blocks:
37
+ {' '}
38
+ {isDefined(passedBlocks) && passedBlocks.length > 0 ? passedBlocks.map(block => new Intl.NumberFormat().format(block)).join(', ') : 'N/A'}
39
+ </Typography>
40
+
41
+ </Stack>
42
+ )
43
+ }
@@ -0,0 +1,64 @@
1
+ import type { BoxProps, StackProps } from '@mui/material'
2
+ import {
3
+ Box, Stack, styled, Tooltip, Typography,
4
+ } from '@mui/material'
5
+ import React from 'react'
6
+
7
+ import type { BlockConfirmationStatus } from '../../helpers/index.ts'
8
+
9
+ export interface BlockRangeEntryStackProps extends StackProps {
10
+ block: number
11
+ blockColor: string
12
+ blockPositionRefs: React.RefObject<{ [blockNumber: number]: HTMLSpanElement | null }>
13
+ blockStatus: BlockConfirmationStatus | undefined
14
+ formattedBlockNumber: string
15
+ }
16
+
17
+ export const BlockRangeEntryStack: React.FC<BlockRangeEntryStackProps> = ({
18
+ blockPositionRefs, block, blockColor, blockStatus, formattedBlockNumber, sx, ...props
19
+ }) => {
20
+ return (
21
+ <Stack
22
+ ref={(ref) => { blockPositionRefs.current[block] = ref }}
23
+ key={block}
24
+ sx={{ position: 'relative', ...sx }}
25
+ {...props}
26
+ >
27
+ <Box
28
+ component="span"
29
+ sx={{
30
+ display: 'flex', position: 'relative', width: '100%', height: 5,
31
+ }}
32
+ >
33
+ <StyledBlockNumberIndicator component="span" sx={{ backgroundColor: blockColor }} />
34
+ </Box>
35
+ <Tooltip
36
+ title={`Block: ${new Intl.NumberFormat().format(block)} (${blockStatus})`}
37
+ placement="top"
38
+ arrow
39
+ >
40
+ <Typography
41
+ variant="caption"
42
+ sx={{
43
+ color: blockColor,
44
+ cursor: 'pointer',
45
+ opacity: blockStatus === 'missed' ? 0.75 : 1,
46
+ }}
47
+ >
48
+ {formattedBlockNumber}
49
+ </Typography>
50
+ </Tooltip>
51
+ </Stack>
52
+ )
53
+ }
54
+
55
+ export const StyledBlockNumberIndicator = styled(Box, { name: 'StyledBlockNumberIndicator' })<BoxProps>(({ theme }) => {
56
+ return theme.unstable_sx({
57
+ position: 'absolute',
58
+ left: 'calc(50% - 1px)',
59
+ transform: 'calc(translateX(-50%) - 1px)',
60
+ height: 3,
61
+ width: '1px',
62
+ backgroundColor: 'primary.main',
63
+ })
64
+ })
@@ -0,0 +1,2 @@
1
+ export * from './BlockConfirmationStats.tsx'
2
+ export * from './BlockRangeEntryStack.tsx'
@@ -0,0 +1,52 @@
1
+ import { isDefined } from '@xylabs/sdk-js'
2
+
3
+ export type BlockConfirmationStatus = 'confirmed' | 'missed' | 'pending'
4
+
5
+ type BlockFormattersParams = {
6
+ confirmedInBlock: number | undefined
7
+ currentBlockNumber: number | undefined
8
+ }
9
+
10
+ export class BlockFormatters {
11
+ private readonly params: BlockFormattersParams
12
+
13
+ constructor(params: BlockFormattersParams) {
14
+ this.params = params
15
+ }
16
+
17
+ color(blockNumber: number): string {
18
+ const { currentBlockNumber, confirmedInBlock } = this.params
19
+ if (blockNumber === currentBlockNumber) {
20
+ return isDefined(confirmedInBlock) && confirmedInBlock === blockNumber ? 'success.dark' : 'text'
21
+ }
22
+ const status = this.confirmationStatus(blockNumber)
23
+ switch (status) {
24
+ case 'confirmed': {
25
+ return 'success.dark'
26
+ }
27
+ case 'missed': {
28
+ return 'warning.light'
29
+ }
30
+ case 'pending': {
31
+ return 'text.secondary'
32
+ }
33
+ default: {
34
+ return 'text.secondary'
35
+ }
36
+ }
37
+ }
38
+
39
+ confirmationStatus(blockNumber: number): BlockConfirmationStatus | undefined {
40
+ const { currentBlockNumber, confirmedInBlock } = this.params
41
+ if (isDefined(currentBlockNumber)) {
42
+ if (isDefined(confirmedInBlock) && blockNumber === confirmedInBlock) {
43
+ return 'confirmed'
44
+ }
45
+ return currentBlockNumber > blockNumber ? 'missed' : 'pending'
46
+ }
47
+ }
48
+
49
+ formatNumber(blockNumber: number) {
50
+ return blockNumber.toString().length <= 5 ? new Intl.NumberFormat().format(blockNumber) : `${blockNumber.toString().slice(-2)}`
51
+ }
52
+ }
@@ -0,0 +1,15 @@
1
+ import type { LinearProgressProps } from '@mui/material'
2
+ import { isDefined } from '@xylabs/sdk-js'
3
+
4
+ export const blockProgressColor = (
5
+ confirmedInBlock: number | undefined,
6
+ isExpired: boolean | undefined,
7
+ ): LinearProgressProps['color'] => {
8
+ if (isDefined(confirmedInBlock)) {
9
+ return 'success'
10
+ }
11
+ if (isExpired) {
12
+ return 'error'
13
+ }
14
+ return 'primary'
15
+ }
@@ -0,0 +1,20 @@
1
+ import { isUndefined } from '@xylabs/sdk-js'
2
+
3
+ export const createFilledRange = (range?: [number, number]): number[] => {
4
+ if (isUndefined(range)) {
5
+ return []
6
+ }
7
+ const [start, end] = range
8
+ if (end < start) {
9
+ console.warn('Invalid range: end is less than start')
10
+ return []
11
+ }
12
+
13
+ const result: number[] = []
14
+
15
+ for (let i = start; i <= end; i++) {
16
+ result.push(i)
17
+ }
18
+
19
+ return result
20
+ }
@@ -0,0 +1,22 @@
1
+ import { isUndefined, isUndefinedOrNull } from '@xylabs/sdk-js'
2
+
3
+ export const getBlockProgress = (
4
+ currentBlockNumber: number | undefined,
5
+ currentBlockRef: HTMLSpanElement | null,
6
+ progressElementRef: HTMLDivElement | null,
7
+ ) => {
8
+ if (isUndefined(currentBlockNumber) || isUndefinedOrNull(currentBlockRef) || isUndefinedOrNull(progressElementRef)) {
9
+ return 0
10
+ }
11
+
12
+ const currentBlockOffsetLeft = currentBlockRef.offsetLeft
13
+ const currentBlockOffsetWidth = currentBlockRef.clientWidth / 2
14
+ const currentBlockCenterOffsetLeft = currentBlockOffsetLeft + currentBlockOffsetWidth
15
+ const parentOffsetLeft = progressElementRef.offsetLeft
16
+ const parentWidth = progressElementRef.clientWidth
17
+
18
+ const relativePosition = currentBlockCenterOffsetLeft - parentOffsetLeft
19
+ const progress = (relativePosition / parentWidth) * 100
20
+
21
+ return Math.min(Math.max(progress, 0), 100)
22
+ }
@@ -0,0 +1,6 @@
1
+ export * from './BlockFormatters.ts'
2
+ export * from './blockProgressColor.ts'
3
+ export * from './createFilledRange.ts'
4
+ export * from './getBlockProgress.ts'
5
+ export * from './isCurrentBlockPassedRange.ts'
6
+ export * from './passedBlocksInRange.ts'
@@ -0,0 +1,13 @@
1
+ import { isDefined } from '@xylabs/sdk-js'
2
+ import type { BlockRange } from '@xyo-network/xl1-protocol'
3
+
4
+ export const isCurrentBlockPassedRange = (
5
+ blockRange: BlockRange | undefined,
6
+ currentBlockNumber: number | undefined,
7
+ ) => {
8
+ if (!isDefined(blockRange) || !isDefined(currentBlockNumber)) {
9
+ return false
10
+ }
11
+ const [, end] = blockRange
12
+ return currentBlockNumber > end
13
+ }
@@ -0,0 +1,12 @@
1
+ import { isDefined } from '@xylabs/sdk-js'
2
+
3
+ export const passedBlocksInRange = (
4
+ range: number[] | undefined,
5
+ currentBlockNumber: number | undefined,
6
+ ) => {
7
+ if (!isDefined(currentBlockNumber) || !isDefined(range)) {
8
+ return []
9
+ }
10
+ const [start] = range
11
+ return range.filter(block => block < currentBlockNumber && block >= start)
12
+ }
@@ -0,0 +1 @@
1
+ export * from './useBlockRangeState.ts'
@@ -0,0 +1,27 @@
1
+ import { isDefined } from '@xylabs/sdk-js'
2
+ import type { BlockRange } from '@xyo-network/xl1-protocol'
3
+ import { useMemo } from 'react'
4
+
5
+ import {
6
+ blockProgressColor, createFilledRange, isCurrentBlockPassedRange, passedBlocksInRange,
7
+ } from '../helpers/index.ts'
8
+
9
+ export const useBlockRangeState = (
10
+ blockRange: BlockRange | undefined,
11
+ confirmedInBlock: number | undefined,
12
+ currentBlockNumber?: number | undefined,
13
+ ) => {
14
+ const range = useMemo(() => createFilledRange((blockRange)), [blockRange])
15
+
16
+ const isExpired = useMemo(() => isCurrentBlockPassedRange(blockRange, currentBlockNumber), [blockRange, currentBlockNumber])
17
+
18
+ const passedBlocks = useMemo(() => passedBlocksInRange(range, currentBlockNumber), [currentBlockNumber, range])
19
+
20
+ const progressColor = useMemo(() => blockProgressColor(confirmedInBlock, isExpired), [confirmedInBlock, isExpired])
21
+
22
+ const isConfirmed = isDefined(confirmedInBlock)
23
+
24
+ return {
25
+ isConfirmed, isExpired, passedBlocks, progressColor, range,
26
+ }
27
+ }
@@ -0,0 +1,3 @@
1
+ export * from './components/index.ts'
2
+ export * from './helpers/index.ts'
3
+ export * from './hooks/index.ts'
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './confirmation/index.ts'