@xyo-network/react-chain-network 1.19.9 → 1.19.11
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/dist/browser/components/broadcast/Drawer.d.ts +5 -2
- package/dist/browser/components/broadcast/Drawer.d.ts.map +1 -1
- package/dist/browser/components/broadcast/details/Card.d.ts +3 -2
- package/dist/browser/components/broadcast/details/Card.d.ts.map +1 -1
- package/dist/browser/components/broadcast/details/SummaryStack.d.ts +2 -0
- package/dist/browser/components/broadcast/details/SummaryStack.d.ts.map +1 -1
- package/dist/browser/components/broadcast/details/SummaryStack.stories.d.ts +8 -0
- package/dist/browser/components/broadcast/details/SummaryStack.stories.d.ts.map +1 -0
- package/dist/browser/components/broadcast/usePaginatedEventPairs.d.ts +13 -0
- package/dist/browser/components/broadcast/usePaginatedEventPairs.d.ts.map +1 -0
- package/dist/browser/context/network/settings/types.d.ts +1 -1
- package/dist/browser/context/network/settings/types.d.ts.map +1 -1
- package/dist/browser/hooks/provider/UseViewerInPage.stories.d.ts.map +1 -1
- package/dist/browser/hooks/provider/useRpcBroadcastListener.d.ts +3 -2
- package/dist/browser/hooks/provider/useRpcBroadcastListener.d.ts.map +1 -1
- package/dist/browser/index.mjs +468 -337
- package/dist/browser/index.mjs.map +1 -1
- package/dist/browser/model/BroadcastRpc.d.ts +3 -0
- package/dist/browser/model/BroadcastRpc.d.ts.map +1 -1
- package/package.json +11 -10
- package/src/components/broadcast/Drawer.tsx +66 -14
- package/src/components/broadcast/details/Card.tsx +25 -9
- package/src/components/broadcast/details/SummaryStack.stories.tsx +36 -0
- package/src/components/broadcast/details/SummaryStack.tsx +41 -3
- package/src/components/broadcast/usePaginatedEventPairs.ts +64 -0
- package/src/context/network/settings/types.ts +1 -1
- package/src/hooks/provider/UseViewerInPage.stories.tsx +10 -8
- package/src/hooks/provider/useRpcBroadcastListener.ts +36 -6
- package/src/model/BroadcastRpc.ts +4 -0
- package/dist/browser/components/broadcast/helpers/formatEvents.d.ts +0 -7
- package/dist/browser/components/broadcast/helpers/formatEvents.d.ts.map +0 -1
- package/dist/browser/components/broadcast/helpers/index.d.ts +0 -2
- package/dist/browser/components/broadcast/helpers/index.d.ts.map +0 -1
- package/src/components/broadcast/helpers/formatEvents.ts +0 -40
- package/src/components/broadcast/helpers/index.ts +0 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { ChangeEvent } from 'react'
|
|
2
|
+
import {
|
|
3
|
+
useCallback, useMemo, useState,
|
|
4
|
+
} from 'react'
|
|
5
|
+
|
|
6
|
+
import type { RpcRequestResponsePairsById } from '../../model/index.ts'
|
|
7
|
+
|
|
8
|
+
export const usePaginatedEventPairs = (
|
|
9
|
+
formattedEvents: RpcRequestResponsePairsById,
|
|
10
|
+
numberOfVisiblePairs: number,
|
|
11
|
+
onClearEvents?: () => void,
|
|
12
|
+
) => {
|
|
13
|
+
const [currentPage, setCurrentPage] = useState(0)
|
|
14
|
+
|
|
15
|
+
const allEventEntries = useMemo(() => {
|
|
16
|
+
return Object.entries(formattedEvents ?? {})
|
|
17
|
+
}, [formattedEvents])
|
|
18
|
+
|
|
19
|
+
const totalPages = useMemo(() => {
|
|
20
|
+
return Math.ceil(allEventEntries.length / numberOfVisiblePairs)
|
|
21
|
+
}, [allEventEntries.length, numberOfVisiblePairs])
|
|
22
|
+
|
|
23
|
+
// Clamp current page to valid range
|
|
24
|
+
const effectiveCurrentPage = useMemo(() => {
|
|
25
|
+
if (totalPages === 0) return 0
|
|
26
|
+
return Math.min(currentPage, totalPages - 1)
|
|
27
|
+
}, [currentPage, totalPages])
|
|
28
|
+
|
|
29
|
+
const visibleEvents = useMemo(() => {
|
|
30
|
+
const startIndex = effectiveCurrentPage * numberOfVisiblePairs
|
|
31
|
+
const endIndex = startIndex + numberOfVisiblePairs
|
|
32
|
+
return allEventEntries.slice(startIndex, endIndex)
|
|
33
|
+
}, [allEventEntries, effectiveCurrentPage, numberOfVisiblePairs])
|
|
34
|
+
|
|
35
|
+
const handlePreviousPage = useCallback(() => {
|
|
36
|
+
setCurrentPage(prev => Math.max(0, prev - 1))
|
|
37
|
+
}, [])
|
|
38
|
+
|
|
39
|
+
const handleNextPage = useCallback(() => {
|
|
40
|
+
setCurrentPage(prev => Math.min(totalPages - 1, prev + 1))
|
|
41
|
+
}, [totalPages])
|
|
42
|
+
|
|
43
|
+
const handleClearEvents = useCallback(() => {
|
|
44
|
+
setCurrentPage(0)
|
|
45
|
+
onClearEvents?.()
|
|
46
|
+
}, [onClearEvents])
|
|
47
|
+
|
|
48
|
+
// Compatible with TablePagination's onPageChange signature
|
|
49
|
+
// Accepts 1-indexed page, converts to 0-indexed internally
|
|
50
|
+
const handlePageChange = useCallback((_event: ChangeEvent<unknown>, page: number) => {
|
|
51
|
+
setCurrentPage(page - 1)
|
|
52
|
+
}, [])
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
allEventEntries,
|
|
56
|
+
visibleEvents,
|
|
57
|
+
effectiveCurrentPage: effectiveCurrentPage + 1, // Return 1-indexed page
|
|
58
|
+
totalPages,
|
|
59
|
+
handlePreviousPage,
|
|
60
|
+
handleNextPage,
|
|
61
|
+
handleClearEvents,
|
|
62
|
+
handlePageChange,
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -14,11 +14,7 @@ import type { HydratedBlock, NetworkId } from '@xyo-network/xl1-sdk'
|
|
|
14
14
|
import {
|
|
15
15
|
LocalNetwork, MainNetwork, SequenceNetwork,
|
|
16
16
|
} from '@xyo-network/xl1-sdk'
|
|
17
|
-
import React, {
|
|
18
|
-
useCallback,
|
|
19
|
-
useEffect,
|
|
20
|
-
useState,
|
|
21
|
-
} from 'react'
|
|
17
|
+
import React, { useCallback, useState } from 'react'
|
|
22
18
|
|
|
23
19
|
import { BroadcastedRpcCallsDrawer } from '../../components/index.ts'
|
|
24
20
|
import type { ChainNetworkSettings } from '../../context/index.ts'
|
|
@@ -67,7 +63,7 @@ const UseViewerInPageStoryTemplate: React.FC = () => {
|
|
|
67
63
|
const [result, setResult] = useState<HydratedBlock | null | undefined>()
|
|
68
64
|
const [loading, setLoading] = useState(false)
|
|
69
65
|
const [drawerOpen, setDrawerOpen] = useState(false)
|
|
70
|
-
const { events } = useRpcBroadcastListener()
|
|
66
|
+
const { clearEvents, events } = useRpcBroadcastListener()
|
|
71
67
|
|
|
72
68
|
const handleClick = useCallback(async () => {
|
|
73
69
|
if (isDefinedNotNull(viewer)) {
|
|
@@ -107,8 +103,13 @@ const UseViewerInPageStoryTemplate: React.FC = () => {
|
|
|
107
103
|
No wallet extension found. Please install the Xyo Wallet Chrome Extension.
|
|
108
104
|
</Alert>
|
|
109
105
|
)}
|
|
110
|
-
<BroadcastedRpcCallsDrawer
|
|
111
|
-
|
|
106
|
+
<BroadcastedRpcCallsDrawer
|
|
107
|
+
open={drawerOpen}
|
|
108
|
+
events={events}
|
|
109
|
+
onClearEvents={clearEvents}
|
|
110
|
+
onClose={() => setDrawerOpen(false)}
|
|
111
|
+
/>
|
|
112
|
+
<ButtonEx disabled={Object.keys(events).length === 0} variant="contained" onClick={() => setDrawerOpen(true)}>
|
|
112
113
|
Show Broadcasted RPC Calls
|
|
113
114
|
</ButtonEx>
|
|
114
115
|
<ButtonEx loading={loading} variant="contained" onClick={() => void handleClick()} disabled={!isDefined(viewer)}>
|
|
@@ -138,6 +139,7 @@ export default {
|
|
|
138
139
|
const Template: StoryFn<typeof UseViewerInPageStoryTemplate> = args => <UseViewerInPageStoryTemplate {...args} />
|
|
139
140
|
|
|
140
141
|
const Default = Template.bind({})
|
|
142
|
+
Default.decorators = [UseViewerInPageStoryDecorator]
|
|
141
143
|
Default.args = {}
|
|
142
144
|
const Proxy = Template.bind({})
|
|
143
145
|
Proxy.decorators = [UseViewerInPageStoryProxyDecorator]
|
|
@@ -1,10 +1,30 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { JsonRpcRequest, JsonRpcResponse } from '@metamask/utils'
|
|
2
|
+
import { isJsonRpcRequest, isJsonRpcResponse } from '@metamask/utils'
|
|
3
|
+
import { isDefined, isString } from '@xylabs/sdk-js'
|
|
2
4
|
import { useEffect, useState } from 'react'
|
|
3
5
|
|
|
4
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
BroadcastedRpcCall, RpcRequestResponsePairs, RpcRequestResponsePairsById,
|
|
8
|
+
} from '../../model/index.ts'
|
|
9
|
+
|
|
10
|
+
const parseRpcCall = (acc: RpcRequestResponsePairsById, event: BroadcastedRpcCall) => {
|
|
11
|
+
if (isJsonRpcResponse(event.rpcCall)) {
|
|
12
|
+
const castedEvent = event as BroadcastedRpcCall<JsonRpcResponse>
|
|
13
|
+
acc[castedEvent.rpcCall.id as string].result = castedEvent
|
|
14
|
+
} else if (isJsonRpcRequest(event.rpcCall)) {
|
|
15
|
+
const castedEvent = event as BroadcastedRpcCall<JsonRpcRequest>
|
|
16
|
+
acc[castedEvent.rpcCall.id as string].request = castedEvent
|
|
17
|
+
} else {
|
|
18
|
+
console.error('Unknown RPC call type', event)
|
|
19
|
+
}
|
|
20
|
+
acc[event.rpcCall.id as string].source = event.source
|
|
21
|
+
|
|
22
|
+
return acc
|
|
23
|
+
}
|
|
5
24
|
|
|
6
25
|
export const useRpcBroadcastListener = () => {
|
|
7
|
-
const [events, setEvents] = useState<
|
|
26
|
+
const [events, setEvents] = useState<RpcRequestResponsePairsById>({})
|
|
27
|
+
const clearEvents = () => setEvents({})
|
|
8
28
|
|
|
9
29
|
useEffect(() => {
|
|
10
30
|
const listener = (e: Event) => {
|
|
@@ -18,9 +38,19 @@ export const useRpcBroadcastListener = () => {
|
|
|
18
38
|
const broadcastedRpcCall: BroadcastedRpcCall = {
|
|
19
39
|
rpcCall,
|
|
20
40
|
source,
|
|
21
|
-
timestamp:
|
|
41
|
+
timestamp: Date.now(),
|
|
22
42
|
}
|
|
23
|
-
setEvents(prev =>
|
|
43
|
+
setEvents((prev) => {
|
|
44
|
+
const { id } = broadcastedRpcCall.rpcCall
|
|
45
|
+
const newState = { ...prev }
|
|
46
|
+
if (isDefined(newState[id as string])) {
|
|
47
|
+
parseRpcCall(newState, broadcastedRpcCall)
|
|
48
|
+
} else {
|
|
49
|
+
newState[id as string] = {} as RpcRequestResponsePairs
|
|
50
|
+
parseRpcCall(newState, broadcastedRpcCall)
|
|
51
|
+
}
|
|
52
|
+
return newState
|
|
53
|
+
})
|
|
24
54
|
} catch (err) {
|
|
25
55
|
console.error(err)
|
|
26
56
|
}
|
|
@@ -36,5 +66,5 @@ export const useRpcBroadcastListener = () => {
|
|
|
36
66
|
}
|
|
37
67
|
}, [])
|
|
38
68
|
|
|
39
|
-
return { events }
|
|
69
|
+
return { events, clearEvents }
|
|
40
70
|
}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { BroadcastedRpcCall, RpcRequestResponsePairs } from '../../../model/index.ts';
|
|
2
|
-
type RpcRequestResponsePairsById = {
|
|
3
|
-
[id: string]: RpcRequestResponsePairs;
|
|
4
|
-
};
|
|
5
|
-
export declare const formatEvents: (events: BroadcastedRpcCall[]) => RpcRequestResponsePairsById;
|
|
6
|
-
export {};
|
|
7
|
-
//# sourceMappingURL=formatEvents.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatEvents.d.ts","sourceRoot":"","sources":["../../../../../src/components/broadcast/helpers/formatEvents.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AAE1F,KAAK,2BAA2B,GAAG;IACjC,CAAC,EAAE,EAAE,MAAM,GAAG,uBAAuB,CAAA;CACtC,CAAA;AAED,eAAO,MAAM,YAAY,GAAI,QAAQ,kBAAkB,EAAE,KAAG,2BA6B3D,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/components/broadcast/helpers/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA"}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { JsonRpcRequest, JsonRpcResponse } from '@metamask/utils'
|
|
2
|
-
import { isJsonRpcRequest, isJsonRpcResponse } from '@metamask/utils'
|
|
3
|
-
import { isArray, isDefined } from '@xylabs/sdk-js'
|
|
4
|
-
|
|
5
|
-
import type { BroadcastedRpcCall, RpcRequestResponsePairs } from '../../../model/index.ts'
|
|
6
|
-
|
|
7
|
-
type RpcRequestResponsePairsById = {
|
|
8
|
-
[id: string]: RpcRequestResponsePairs
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const formatEvents = (events: BroadcastedRpcCall[]): RpcRequestResponsePairsById => {
|
|
12
|
-
if (!isArray(events) || events.length === 0) return {} as RpcRequestResponsePairsById
|
|
13
|
-
|
|
14
|
-
const parseRpcCall = (acc: RpcRequestResponsePairsById, event: BroadcastedRpcCall) => {
|
|
15
|
-
if (isJsonRpcResponse(event.rpcCall)) {
|
|
16
|
-
const castedEvent = event as BroadcastedRpcCall<JsonRpcResponse>
|
|
17
|
-
acc[castedEvent.rpcCall.id as string].result = castedEvent
|
|
18
|
-
} else if (isJsonRpcRequest(event.rpcCall)) {
|
|
19
|
-
const castedEvent = event as BroadcastedRpcCall<JsonRpcRequest>
|
|
20
|
-
acc[castedEvent.rpcCall.id as string].request = castedEvent
|
|
21
|
-
} else {
|
|
22
|
-
console.error('Unknown RPC call type', event)
|
|
23
|
-
}
|
|
24
|
-
acc[event.rpcCall.id as string].source = event.source
|
|
25
|
-
|
|
26
|
-
return acc
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
let acc: RpcRequestResponsePairsById = {}
|
|
30
|
-
for (const event of events) {
|
|
31
|
-
const { id } = event.rpcCall
|
|
32
|
-
if (isDefined(acc[id as string])) {
|
|
33
|
-
acc = parseRpcCall(acc, event)
|
|
34
|
-
} else {
|
|
35
|
-
acc[id as string] = {} as RpcRequestResponsePairs
|
|
36
|
-
acc = parseRpcCall(acc, event)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return acc
|
|
40
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './formatEvents.ts'
|