@xyo-network/react-price-forecast-plugin 7.5.8 → 7.5.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/index.mjs +49 -92
- package/dist/browser/index.mjs.map +1 -1
- package/package.json +160 -36
- package/src/Plugin.ts +0 -12
- package/src/components/DetailsBox.stories.tsx +0 -78
- package/src/components/DetailsBox.tsx +0 -60
- package/src/components/index.ts +0 -1
- package/src/global.d.ts +0 -1
- package/src/index.ts +0 -2
- package/src/lib/DataLineStyles.ts +0 -6
- package/src/lib/DataPointStyles.ts +0 -7
- package/src/lib/ForecastLineChartConfigBuilder.ts +0 -162
- package/src/lib/MockSourcePayloads.ts +0 -29
- package/src/lib/SourcePayloads.ts +0 -50
- package/src/lib/index.ts +0 -3
package/dist/browser/index.mjs
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
-
|
|
4
1
|
// src/components/DetailsBox.tsx
|
|
5
2
|
import "chartjs-adapter-luxon";
|
|
6
3
|
import { useTheme } from "@mui/material";
|
|
7
4
|
import { useAsyncEffect } from "@xylabs/react-async-effect";
|
|
8
5
|
import { FlexCol } from "@xylabs/react-flexbox";
|
|
9
|
-
import {
|
|
10
|
-
|
|
6
|
+
import {
|
|
7
|
+
CategoryScale,
|
|
8
|
+
Chart as ChartJS,
|
|
9
|
+
Legend,
|
|
10
|
+
LinearScale,
|
|
11
|
+
LineElement,
|
|
12
|
+
PointElement,
|
|
13
|
+
TimeScale,
|
|
14
|
+
Title,
|
|
15
|
+
Tooltip
|
|
16
|
+
} from "chart.js";
|
|
17
|
+
import { useState } from "react";
|
|
11
18
|
import { Line } from "react-chartjs-2";
|
|
12
19
|
|
|
13
20
|
// src/lib/ForecastLineChartConfigBuilder.ts
|
|
@@ -15,23 +22,23 @@ import { useIsDark } from "@xylabs/react-theme";
|
|
|
15
22
|
|
|
16
23
|
// src/lib/DataLineStyles.ts
|
|
17
24
|
import { alphaCss } from "@xylabs/react-theme";
|
|
18
|
-
var DataLineStyles =
|
|
25
|
+
var DataLineStyles = (color) => ({
|
|
19
26
|
backgroundColor: color ? alphaCss(color, 0.5) : void 0,
|
|
20
27
|
borderColor: color
|
|
21
|
-
})
|
|
28
|
+
});
|
|
22
29
|
|
|
23
30
|
// src/lib/DataPointStyles.ts
|
|
24
|
-
var DataPointStyles =
|
|
31
|
+
var DataPointStyles = (pointHoverBackgroundColor) => ({
|
|
25
32
|
pointHitRadius: 20,
|
|
26
33
|
pointHoverBackgroundColor,
|
|
27
34
|
pointHoverRadius: 10,
|
|
28
35
|
pointRadius: 5,
|
|
29
36
|
pointStyle: "circle"
|
|
30
|
-
})
|
|
37
|
+
});
|
|
31
38
|
|
|
32
39
|
// src/lib/MockSourcePayloads.ts
|
|
33
40
|
import { asSchema } from "@xyo-network/payload-model";
|
|
34
|
-
var MockSourcePayloads =
|
|
41
|
+
var MockSourcePayloads = () => {
|
|
35
42
|
const tenMin = 6e5;
|
|
36
43
|
return [
|
|
37
44
|
{
|
|
@@ -69,13 +76,10 @@ var MockSourcePayloads = /* @__PURE__ */ __name(() => {
|
|
|
69
76
|
timestamp: Date.now()
|
|
70
77
|
}
|
|
71
78
|
];
|
|
72
|
-
}
|
|
79
|
+
};
|
|
73
80
|
|
|
74
81
|
// src/lib/SourcePayloads.ts
|
|
75
82
|
var SourcePayloads = class {
|
|
76
|
-
static {
|
|
77
|
-
__name(this, "SourcePayloads");
|
|
78
|
-
}
|
|
79
83
|
sourcePayloads;
|
|
80
84
|
sourcePrices = [];
|
|
81
85
|
constructor(sourcePayloads) {
|
|
@@ -89,10 +93,7 @@ var SourcePayloads = class {
|
|
|
89
93
|
const instance = new this(sourcePayloads);
|
|
90
94
|
const paths = jsonPath.split(".");
|
|
91
95
|
instance.sourcePrices = sourcePayloads.map((payload) => {
|
|
92
|
-
return {
|
|
93
|
-
x: payload.timestamp,
|
|
94
|
-
y: instance.jsonPathTraverser(payload, paths)
|
|
95
|
-
};
|
|
96
|
+
return { x: payload.timestamp, y: instance.jsonPathTraverser(payload, paths) };
|
|
96
97
|
});
|
|
97
98
|
return instance;
|
|
98
99
|
}
|
|
@@ -117,21 +118,12 @@ var SourcePayloads = class {
|
|
|
117
118
|
};
|
|
118
119
|
|
|
119
120
|
// src/lib/ForecastLineChartConfigBuilder.ts
|
|
120
|
-
var defaultOptions =
|
|
121
|
-
plugins: {
|
|
122
|
-
legend: {
|
|
123
|
-
position: "top"
|
|
124
|
-
}
|
|
125
|
-
},
|
|
121
|
+
var defaultOptions = () => ({
|
|
122
|
+
plugins: { legend: { position: "top" } },
|
|
126
123
|
responsive: true
|
|
127
|
-
})
|
|
124
|
+
});
|
|
128
125
|
var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
|
|
129
|
-
|
|
130
|
-
__name(this, "ForecastLineChartConfigBuilder");
|
|
131
|
-
}
|
|
132
|
-
data = {
|
|
133
|
-
datasets: []
|
|
134
|
-
};
|
|
126
|
+
data = { datasets: [] };
|
|
135
127
|
options = defaultOptions();
|
|
136
128
|
themeColors;
|
|
137
129
|
payload;
|
|
@@ -159,18 +151,14 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
|
|
|
159
151
|
}
|
|
160
152
|
async buildData(includeSources) {
|
|
161
153
|
const forecastData = this.generateDataSetForecastData();
|
|
162
|
-
const datasets = [
|
|
163
|
-
forecastData
|
|
164
|
-
];
|
|
154
|
+
const datasets = [forecastData];
|
|
165
155
|
if (includeSources) {
|
|
166
156
|
const sourceData = await this.generateDataSetSourcePayloads();
|
|
167
157
|
datasets.unshift(sourceData);
|
|
168
158
|
const lastSourceDataItem = sourceData.data.at(-1);
|
|
169
159
|
forecastData.data.unshift(lastSourceDataItem);
|
|
170
160
|
}
|
|
171
|
-
this.data = {
|
|
172
|
-
datasets
|
|
173
|
-
};
|
|
161
|
+
this.data = { datasets };
|
|
174
162
|
return this;
|
|
175
163
|
}
|
|
176
164
|
buildOptions() {
|
|
@@ -182,12 +170,8 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
|
|
|
182
170
|
return this;
|
|
183
171
|
}
|
|
184
172
|
refreshValues() {
|
|
185
|
-
this.data = {
|
|
186
|
-
|
|
187
|
-
};
|
|
188
|
-
this.options = {
|
|
189
|
-
...this.options
|
|
190
|
-
};
|
|
173
|
+
this.data = { ...this.data };
|
|
174
|
+
this.options = { ...this.options };
|
|
191
175
|
}
|
|
192
176
|
generateLegend() {
|
|
193
177
|
return {
|
|
@@ -200,19 +184,11 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
|
|
|
200
184
|
generateScales() {
|
|
201
185
|
return {
|
|
202
186
|
x: {
|
|
203
|
-
grid: {
|
|
204
|
-
|
|
205
|
-
},
|
|
206
|
-
time: {
|
|
207
|
-
unit: "minute"
|
|
208
|
-
},
|
|
187
|
+
grid: { color: this.themeColors?.gridColor },
|
|
188
|
+
time: { unit: "minute" },
|
|
209
189
|
type: "time"
|
|
210
190
|
},
|
|
211
|
-
y: {
|
|
212
|
-
grid: {
|
|
213
|
-
color: this.themeColors?.gridColor
|
|
214
|
-
}
|
|
215
|
-
}
|
|
191
|
+
y: { grid: { color: this.themeColors?.gridColor } }
|
|
216
192
|
};
|
|
217
193
|
}
|
|
218
194
|
generateTitle() {
|
|
@@ -231,14 +207,9 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
|
|
|
231
207
|
}
|
|
232
208
|
generateDataSetForecastData() {
|
|
233
209
|
return {
|
|
234
|
-
borderDash: [
|
|
235
|
-
5
|
|
236
|
-
],
|
|
210
|
+
borderDash: [5],
|
|
237
211
|
borderDashOffset: 0.5,
|
|
238
|
-
data: this.forecastPayload.values.map((price) => ({
|
|
239
|
-
x: price.timestamp ?? 0,
|
|
240
|
-
y: price.value
|
|
241
|
-
})),
|
|
212
|
+
data: this.forecastPayload.values.map((price) => ({ x: price.timestamp ?? 0, y: price.value })),
|
|
242
213
|
label: "Forecast Price",
|
|
243
214
|
...DataPointStyles(this.themeColors?.dataSetColorPrimary),
|
|
244
215
|
...DataLineStyles(this.themeColors?.dataSetColorPrimary)
|
|
@@ -256,46 +227,32 @@ var ForecastLineChartConfigBuilder = class _ForecastLineChartConfigBuilder {
|
|
|
256
227
|
};
|
|
257
228
|
|
|
258
229
|
// src/components/DetailsBox.tsx
|
|
230
|
+
import { jsx } from "react/jsx-runtime";
|
|
259
231
|
ChartJS.register(CategoryScale, TimeScale, PointElement, LineElement, LinearScale, Title, Tooltip, Legend);
|
|
260
|
-
var PriceForecastDetailsBox =
|
|
232
|
+
var PriceForecastDetailsBox = ({ payload, ...props }) => {
|
|
261
233
|
const priceForecastPayload = payload;
|
|
262
234
|
const theme = useTheme();
|
|
263
|
-
const [data, setData] = useState({
|
|
264
|
-
datasets: []
|
|
265
|
-
});
|
|
235
|
+
const [data, setData] = useState({ datasets: [] });
|
|
266
236
|
const [options, setOptions] = useState({});
|
|
267
|
-
useAsyncEffect(
|
|
268
|
-
|
|
269
|
-
fetch: true
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
return /* @__PURE__ */ React.createElement(FlexCol, {
|
|
280
|
-
...props,
|
|
281
|
-
busy: priceForecastPayload === void 0,
|
|
282
|
-
minHeight: "25vh"
|
|
283
|
-
}, priceForecastPayload ? /* @__PURE__ */ React.createElement(Line, {
|
|
284
|
-
options,
|
|
285
|
-
data
|
|
286
|
-
}) : null);
|
|
287
|
-
}, "PriceForecastDetailsBox");
|
|
237
|
+
useAsyncEffect(
|
|
238
|
+
async (mounted) => {
|
|
239
|
+
const { data: data2, options: options2 } = await ForecastLineChartConfigBuilder.create(theme, priceForecastPayload, { fetch: true });
|
|
240
|
+
if (mounted()) {
|
|
241
|
+
setData(data2);
|
|
242
|
+
setOptions(options2);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
[priceForecastPayload, theme]
|
|
246
|
+
);
|
|
247
|
+
return /* @__PURE__ */ jsx(FlexCol, { ...props, busy: priceForecastPayload === void 0, minHeight: "25vh", children: priceForecastPayload ? /* @__PURE__ */ jsx(Line, { options, data }) : null });
|
|
248
|
+
};
|
|
288
249
|
|
|
289
250
|
// src/Plugin.ts
|
|
290
251
|
import { createPayloadRenderPlugin } from "@xyo-network/react-payload-plugin";
|
|
291
252
|
var PriceForecastRenderPlugin = {
|
|
292
253
|
...createPayloadRenderPlugin({
|
|
293
|
-
canRender:
|
|
294
|
-
components: {
|
|
295
|
-
box: {
|
|
296
|
-
detailsBox: PriceForecastDetailsBox
|
|
297
|
-
}
|
|
298
|
-
},
|
|
254
|
+
canRender: () => true,
|
|
255
|
+
components: { box: { detailsBox: PriceForecastDetailsBox } },
|
|
299
256
|
name: "PriceForecast"
|
|
300
257
|
})
|
|
301
258
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/DetailsBox.tsx","../../src/lib/ForecastLineChartConfigBuilder.ts","../../src/lib/DataLineStyles.ts","../../src/lib/DataPointStyles.ts","../../src/lib/MockSourcePayloads.ts","../../src/lib/SourcePayloads.ts","../../src/Plugin.ts"],"sourcesContent":["import 'chartjs-adapter-luxon'\n\nimport { useTheme } from '@mui/material'\nimport { useAsyncEffect } from '@xylabs/react-async-effect'\nimport type { FlexBoxProps } from '@xylabs/react-flexbox'\nimport { FlexCol } from '@xylabs/react-flexbox'\nimport type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'\nimport type { Payload } from '@xyo-network/payload-model'\nimport type {\n ChartData,\n ChartOptions,\n} from 'chart.js'\nimport {\n CategoryScale,\n Chart as ChartJS,\n Legend,\n LinearScale,\n LineElement,\n PointElement,\n TimeScale,\n Title,\n Tooltip,\n} from 'chart.js'\nimport React, { useState } from 'react'\nimport { Line } from 'react-chartjs-2'\n\nimport { ForecastLineChartConfigBuilder } from '../lib/index.ts'\n\nChartJS.register(CategoryScale, TimeScale, PointElement, LineElement, LinearScale, Title, Tooltip, Legend)\n\nexport interface PriceForecastDetailsBoxProps extends FlexBoxProps {\n payload?: Payload\n}\n\nexport const PriceForecastDetailsBox: React.FC<PriceForecastDetailsBoxProps> = ({ payload, ...props }) => {\n const priceForecastPayload = payload as ForecastPayload | undefined\n const theme = useTheme()\n const [data, setData] = useState<ChartData<'line'>>({ datasets: [] })\n const [options, setOptions] = useState<ChartOptions<'line'>>({})\n\n useAsyncEffect(\n\n async (mounted) => {\n const { data, options } = await ForecastLineChartConfigBuilder.create(theme, priceForecastPayload, { fetch: true })\n if (mounted()) {\n setData(data)\n setOptions(options)\n }\n },\n [priceForecastPayload, theme],\n )\n\n return (\n <FlexCol {...props} busy={priceForecastPayload === undefined} minHeight=\"25vh\">\n {priceForecastPayload\n ? <Line options={options} data={data} />\n : null}\n </FlexCol>\n )\n}\n","import type { Theme } from '@mui/material'\nimport { useIsDark } from '@xylabs/react-theme'\nimport type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'\nimport type {\n ChartData, ChartDataset, ChartOptions, LegendOptions, Point, ScaleChartOptions,\n} from 'chart.js'\n\nimport { DataLineStyles } from './DataLineStyles.ts'\nimport { DataPointStyles } from './DataPointStyles.ts'\nimport { SourcePayloads } from './SourcePayloads.ts'\n\ninterface SourcePayloadConfig {\n fetch: boolean\n sampleSize?: number\n}\n\ninterface ThemeColors {\n dataSetColorPrimary: string\n dataSetColorSecondary: string\n gridColor: string\n}\n\nconst defaultOptions: () => ChartOptions<'line'> = () => ({\n plugins: { legend: { position: 'top' as const } },\n responsive: true,\n})\n\nexport class ForecastLineChartConfigBuilder {\n data: ChartData<'line'> = { datasets: [] }\n\n options: ChartOptions<'line'> = defaultOptions()\n themeColors: ThemeColors | undefined\n\n private payload?: ForecastPayload\n\n constructor(\n theme: Theme,\n payload?: ForecastPayload,\n ) {\n this.payload = payload\n this.themeColors = this.parseTheme(theme)\n }\n\n get forecastPayload() {\n if (this.payload) {\n return this.payload\n } else {\n throw new Error('ForecastPayload was not defined')\n }\n }\n\n static async create(theme: Theme, payload?: ForecastPayload, sourcePayloadConfig?: SourcePayloadConfig) {\n const instance = new ForecastLineChartConfigBuilder(theme, payload)\n\n await instance.build(sourcePayloadConfig?.fetch)\n\n instance.refreshValues()\n\n return instance\n }\n\n async build(includeSources?: boolean) {\n this.buildOptions()\n await this.buildData(includeSources)\n return this\n }\n\n async buildData(includeSources?: boolean) {\n const forecastData = this.generateDataSetForecastData()\n\n const datasets: ChartDataset<'line'>[] = [forecastData]\n\n if (includeSources) {\n // build data from sources in forecastPayload\n const sourceData = await this.generateDataSetSourcePayloads()\n datasets.unshift(sourceData)\n\n // add last source point as first item in prediction to connect the lines\n const lastSourceDataItem = sourceData.data.at(-1) as Point\n forecastData.data.unshift(lastSourceDataItem)\n }\n\n this.data = { datasets }\n\n return this\n }\n\n buildOptions() {\n if (this.options.plugins) {\n this.options.plugins.title = this.generateTitle()\n this.options.plugins.legend = this.generateLegend()\n }\n this.options.scales = this.generateScales()\n\n return this\n }\n\n refreshValues() {\n this.data = { ...this.data }\n this.options = { ...this.options }\n }\n\n protected generateLegend() {\n return {\n labels: {\n pointStyle: 'circle',\n usePointStyle: true,\n },\n } as LegendOptions<'line'>\n }\n\n protected generateScales() {\n return {\n x: {\n grid: { color: this.themeColors?.gridColor },\n time: { unit: 'minute' },\n type: 'time',\n },\n y: { grid: { color: this.themeColors?.gridColor } },\n } as unknown as ScaleChartOptions<'line'>['scales']\n }\n\n protected generateTitle() {\n return {\n display: true,\n text: `Gas Price Forecaster (GWEI over time from ${\n this.forecastPayload?.values[0].timestamp ? new Date(this.forecastPayload.values[0].timestamp).toLocaleDateString() : ''\n })`,\n }\n }\n\n protected parseTheme(theme: Theme) {\n // eslint-disable-next-line react-x/rules-of-hooks, react-hooks/rules-of-hooks\n const dark = useIsDark()\n return {\n dataSetColorPrimary: theme.vars.palette.primary.light,\n dataSetColorSecondary: theme.vars.palette.secondary.light,\n gridColor: dark ? theme.vars.palette.grey[800] : theme.vars.palette.grey[300],\n }\n }\n\n private generateDataSetForecastData(): ChartDataset<'line'> {\n return {\n borderDash: [5],\n borderDashOffset: 0.5,\n data: this.forecastPayload.values.map(price => ({ x: price.timestamp ?? 0, y: price.value })),\n label: 'Forecast Price',\n ...DataPointStyles(this.themeColors?.dataSetColorPrimary),\n ...DataLineStyles(this.themeColors?.dataSetColorPrimary),\n }\n }\n\n private async generateDataSetSourcePayloads(): Promise<ChartDataset<'line'>> {\n const { sourcePrices } = await SourcePayloads.build('feePerGas.medium')\n return {\n data: sourcePrices,\n label: 'Source Prices',\n ...DataLineStyles(this.themeColors?.dataSetColorSecondary),\n ...DataPointStyles(this.themeColors?.dataSetColorSecondary),\n }\n }\n}\n","import { alphaCss } from '@xylabs/react-theme'\n\nexport const DataLineStyles = (color?: string) => ({\n backgroundColor: color ? alphaCss(color, 0.5) : undefined,\n borderColor: color,\n})\n","export const DataPointStyles = (pointHoverBackgroundColor?: string) => ({\n pointHitRadius: 20,\n pointHoverBackgroundColor,\n pointHoverRadius: 10,\n pointRadius: 5,\n pointStyle: 'circle',\n})\n","import { asSchema } from '@xyo-network/payload-model'\n\nexport const MockSourcePayloads = () => {\n const tenMin = 600_000\n return [\n {\n baseFee: 38.901_553_878_25,\n feePerGas: {\n high: 47.994_586_439_6, low: 39.006_868_093, medium: 39.306_868_093, veryHigh: 44.453_843_805_25,\n },\n priorityFeePerGas: {\n high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,\n },\n schema: asSchema('network.xyo.blockchain.ethereum.gas', true),\n timestamp: Date.now() - tenMin,\n },\n {\n baseFee: 38.901_553_878_25,\n feePerGas: {\n high: 47.994_586_439_6, low: 39.006_868_093, medium: 100, veryHigh: 44.453_843_805_25,\n },\n priorityFeePerGas: {\n high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,\n },\n schema: asSchema('network.xyo.blockchain.ethereum.gas', true),\n timestamp: Date.now(),\n },\n ]\n}\n","import type { Payload } from '@xyo-network/payload-model'\nimport type { Point } from 'chart.js'\n\nimport { MockSourcePayloads } from './MockSourcePayloads.ts'\n\nexport class SourcePayloads {\n sourcePayloads: Payload[]\n sourcePrices: Point[] = []\n\n constructor(sourcePayloads: Payload[]) {\n this.sourcePayloads = sourcePayloads\n }\n\n get payloads() {\n return this.sourcePayloads\n }\n\n static async build(jsonPath: string) {\n const sourcePayloads = await this.fetchSourcePayloads()\n const instance = new this(sourcePayloads)\n\n const paths = jsonPath.split('.')\n instance.sourcePrices = sourcePayloads.map((payload) => {\n return { x: payload.timestamp, y: instance.jsonPathTraverser(payload, paths) }\n })\n return instance\n }\n\n // TODO - fetch from archivist\n static async fetchSourcePayloads() {\n const payloads = await Promise.resolve(MockSourcePayloads())\n return payloads\n }\n\n jsonPathTraverser(obj: Payload, path: string[]) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let result: any = obj\n for (const key of path) {\n if (key in result) {\n const foundKey = key as keyof typeof result\n result = result[foundKey]\n } else {\n result = undefined\n break\n }\n }\n\n return result\n }\n}\n","import type { PayloadRenderPlugin } from '@xyo-network/react-payload-plugin'\nimport { createPayloadRenderPlugin } from '@xyo-network/react-payload-plugin'\n\nimport { PriceForecastDetailsBox } from './components/index.ts'\n\nexport const PriceForecastRenderPlugin: PayloadRenderPlugin = {\n ...createPayloadRenderPlugin({\n canRender: () => true,\n components: { box: { detailsBox: PriceForecastDetailsBox } },\n name: 'PriceForecast',\n }),\n}\n"],"mappings":"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","names":["useTheme","useAsyncEffect","FlexCol","CategoryScale","Chart","ChartJS","Legend","LinearScale","LineElement","PointElement","TimeScale","Title","Tooltip","React","useState","Line","useIsDark","alphaCss","DataLineStyles","color","backgroundColor","alphaCss","undefined","borderColor","DataPointStyles","pointHoverBackgroundColor","pointHitRadius","pointHoverRadius","pointRadius","pointStyle","asSchema","MockSourcePayloads","tenMin","baseFee","feePerGas","high","low","medium","veryHigh","priorityFeePerGas","schema","asSchema","timestamp","Date","now","SourcePayloads","sourcePayloads","sourcePrices","payloads","build","jsonPath","fetchSourcePayloads","instance","paths","split","map","payload","x","timestamp","y","jsonPathTraverser","Promise","resolve","MockSourcePayloads","obj","path","result","key","foundKey","undefined","defaultOptions","plugins","legend","position","responsive","ForecastLineChartConfigBuilder","data","datasets","options","themeColors","payload","theme","parseTheme","forecastPayload","Error","create","sourcePayloadConfig","instance","build","fetch","refreshValues","includeSources","buildOptions","buildData","forecastData","generateDataSetForecastData","sourceData","generateDataSetSourcePayloads","unshift","lastSourceDataItem","at","title","generateTitle","generateLegend","scales","generateScales","labels","pointStyle","usePointStyle","x","grid","color","gridColor","time","unit","type","y","display","text","values","timestamp","Date","toLocaleDateString","dark","useIsDark","dataSetColorPrimary","vars","palette","primary","light","dataSetColorSecondary","secondary","grey","borderDash","borderDashOffset","map","price","value","label","DataPointStyles","DataLineStyles","sourcePrices","SourcePayloads","ChartJS","register","CategoryScale","TimeScale","PointElement","LineElement","LinearScale","Title","Tooltip","Legend","PriceForecastDetailsBox","payload","props","priceForecastPayload","theme","useTheme","data","setData","useState","datasets","options","setOptions","useAsyncEffect","mounted","ForecastLineChartConfigBuilder","create","fetch","FlexCol","busy","undefined","minHeight","Line","createPayloadRenderPlugin","PriceForecastRenderPlugin","createPayloadRenderPlugin","canRender","components","box","detailsBox","PriceForecastDetailsBox","name"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/DetailsBox.tsx","../../src/lib/ForecastLineChartConfigBuilder.ts","../../src/lib/DataLineStyles.ts","../../src/lib/DataPointStyles.ts","../../src/lib/MockSourcePayloads.ts","../../src/lib/SourcePayloads.ts","../../src/Plugin.ts"],"sourcesContent":["import 'chartjs-adapter-luxon'\n\nimport { useTheme } from '@mui/material'\nimport { useAsyncEffect } from '@xylabs/react-async-effect'\nimport type { FlexBoxProps } from '@xylabs/react-flexbox'\nimport { FlexCol } from '@xylabs/react-flexbox'\nimport type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'\nimport type { Payload } from '@xyo-network/payload-model'\nimport type {\n ChartData,\n ChartOptions,\n} from 'chart.js'\nimport {\n CategoryScale,\n Chart as ChartJS,\n Legend,\n LinearScale,\n LineElement,\n PointElement,\n TimeScale,\n Title,\n Tooltip,\n} from 'chart.js'\nimport React, { useState } from 'react'\nimport { Line } from 'react-chartjs-2'\n\nimport { ForecastLineChartConfigBuilder } from '../lib/index.ts'\n\nChartJS.register(CategoryScale, TimeScale, PointElement, LineElement, LinearScale, Title, Tooltip, Legend)\n\nexport interface PriceForecastDetailsBoxProps extends FlexBoxProps {\n payload?: Payload\n}\n\nexport const PriceForecastDetailsBox: React.FC<PriceForecastDetailsBoxProps> = ({ payload, ...props }) => {\n const priceForecastPayload = payload as ForecastPayload | undefined\n const theme = useTheme()\n const [data, setData] = useState<ChartData<'line'>>({ datasets: [] })\n const [options, setOptions] = useState<ChartOptions<'line'>>({})\n\n useAsyncEffect(\n\n async (mounted) => {\n const { data, options } = await ForecastLineChartConfigBuilder.create(theme, priceForecastPayload, { fetch: true })\n if (mounted()) {\n setData(data)\n setOptions(options)\n }\n },\n [priceForecastPayload, theme],\n )\n\n return (\n <FlexCol {...props} busy={priceForecastPayload === undefined} minHeight=\"25vh\">\n {priceForecastPayload\n ? <Line options={options} data={data} />\n : null}\n </FlexCol>\n )\n}\n","import type { Theme } from '@mui/material'\nimport { useIsDark } from '@xylabs/react-theme'\nimport type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'\nimport type {\n ChartData, ChartDataset, ChartOptions, LegendOptions, Point, ScaleChartOptions,\n} from 'chart.js'\n\nimport { DataLineStyles } from './DataLineStyles.ts'\nimport { DataPointStyles } from './DataPointStyles.ts'\nimport { SourcePayloads } from './SourcePayloads.ts'\n\ninterface SourcePayloadConfig {\n fetch: boolean\n sampleSize?: number\n}\n\ninterface ThemeColors {\n dataSetColorPrimary: string\n dataSetColorSecondary: string\n gridColor: string\n}\n\nconst defaultOptions: () => ChartOptions<'line'> = () => ({\n plugins: { legend: { position: 'top' as const } },\n responsive: true,\n})\n\nexport class ForecastLineChartConfigBuilder {\n data: ChartData<'line'> = { datasets: [] }\n\n options: ChartOptions<'line'> = defaultOptions()\n themeColors: ThemeColors | undefined\n\n private payload?: ForecastPayload\n\n constructor(\n theme: Theme,\n payload?: ForecastPayload,\n ) {\n this.payload = payload\n this.themeColors = this.parseTheme(theme)\n }\n\n get forecastPayload() {\n if (this.payload) {\n return this.payload\n } else {\n throw new Error('ForecastPayload was not defined')\n }\n }\n\n static async create(theme: Theme, payload?: ForecastPayload, sourcePayloadConfig?: SourcePayloadConfig) {\n const instance = new ForecastLineChartConfigBuilder(theme, payload)\n\n await instance.build(sourcePayloadConfig?.fetch)\n\n instance.refreshValues()\n\n return instance\n }\n\n async build(includeSources?: boolean) {\n this.buildOptions()\n await this.buildData(includeSources)\n return this\n }\n\n async buildData(includeSources?: boolean) {\n const forecastData = this.generateDataSetForecastData()\n\n const datasets: ChartDataset<'line'>[] = [forecastData]\n\n if (includeSources) {\n // build data from sources in forecastPayload\n const sourceData = await this.generateDataSetSourcePayloads()\n datasets.unshift(sourceData)\n\n // add last source point as first item in prediction to connect the lines\n const lastSourceDataItem = sourceData.data.at(-1) as Point\n forecastData.data.unshift(lastSourceDataItem)\n }\n\n this.data = { datasets }\n\n return this\n }\n\n buildOptions() {\n if (this.options.plugins) {\n this.options.plugins.title = this.generateTitle()\n this.options.plugins.legend = this.generateLegend()\n }\n this.options.scales = this.generateScales()\n\n return this\n }\n\n refreshValues() {\n this.data = { ...this.data }\n this.options = { ...this.options }\n }\n\n protected generateLegend() {\n return {\n labels: {\n pointStyle: 'circle',\n usePointStyle: true,\n },\n } as LegendOptions<'line'>\n }\n\n protected generateScales() {\n return {\n x: {\n grid: { color: this.themeColors?.gridColor },\n time: { unit: 'minute' },\n type: 'time',\n },\n y: { grid: { color: this.themeColors?.gridColor } },\n } as unknown as ScaleChartOptions<'line'>['scales']\n }\n\n protected generateTitle() {\n return {\n display: true,\n text: `Gas Price Forecaster (GWEI over time from ${\n this.forecastPayload?.values[0].timestamp ? new Date(this.forecastPayload.values[0].timestamp).toLocaleDateString() : ''\n })`,\n }\n }\n\n protected parseTheme(theme: Theme) {\n // eslint-disable-next-line react-x/rules-of-hooks, react-hooks/rules-of-hooks\n const dark = useIsDark()\n return {\n dataSetColorPrimary: theme.vars.palette.primary.light,\n dataSetColorSecondary: theme.vars.palette.secondary.light,\n gridColor: dark ? theme.vars.palette.grey[800] : theme.vars.palette.grey[300],\n }\n }\n\n private generateDataSetForecastData(): ChartDataset<'line'> {\n return {\n borderDash: [5],\n borderDashOffset: 0.5,\n data: this.forecastPayload.values.map(price => ({ x: price.timestamp ?? 0, y: price.value })),\n label: 'Forecast Price',\n ...DataPointStyles(this.themeColors?.dataSetColorPrimary),\n ...DataLineStyles(this.themeColors?.dataSetColorPrimary),\n }\n }\n\n private async generateDataSetSourcePayloads(): Promise<ChartDataset<'line'>> {\n const { sourcePrices } = await SourcePayloads.build('feePerGas.medium')\n return {\n data: sourcePrices,\n label: 'Source Prices',\n ...DataLineStyles(this.themeColors?.dataSetColorSecondary),\n ...DataPointStyles(this.themeColors?.dataSetColorSecondary),\n }\n }\n}\n","import { alphaCss } from '@xylabs/react-theme'\n\nexport const DataLineStyles = (color?: string) => ({\n backgroundColor: color ? alphaCss(color, 0.5) : undefined,\n borderColor: color,\n})\n","export const DataPointStyles = (pointHoverBackgroundColor?: string) => ({\n pointHitRadius: 20,\n pointHoverBackgroundColor,\n pointHoverRadius: 10,\n pointRadius: 5,\n pointStyle: 'circle',\n})\n","import { asSchema } from '@xyo-network/payload-model'\n\nexport const MockSourcePayloads = () => {\n const tenMin = 600_000\n return [\n {\n baseFee: 38.901_553_878_25,\n feePerGas: {\n high: 47.994_586_439_6, low: 39.006_868_093, medium: 39.306_868_093, veryHigh: 44.453_843_805_25,\n },\n priorityFeePerGas: {\n high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,\n },\n schema: asSchema('network.xyo.blockchain.ethereum.gas', true),\n timestamp: Date.now() - tenMin,\n },\n {\n baseFee: 38.901_553_878_25,\n feePerGas: {\n high: 47.994_586_439_6, low: 39.006_868_093, medium: 100, veryHigh: 44.453_843_805_25,\n },\n priorityFeePerGas: {\n high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,\n },\n schema: asSchema('network.xyo.blockchain.ethereum.gas', true),\n timestamp: Date.now(),\n },\n ]\n}\n","import type { Payload } from '@xyo-network/payload-model'\nimport type { Point } from 'chart.js'\n\nimport { MockSourcePayloads } from './MockSourcePayloads.ts'\n\nexport class SourcePayloads {\n sourcePayloads: Payload[]\n sourcePrices: Point[] = []\n\n constructor(sourcePayloads: Payload[]) {\n this.sourcePayloads = sourcePayloads\n }\n\n get payloads() {\n return this.sourcePayloads\n }\n\n static async build(jsonPath: string) {\n const sourcePayloads = await this.fetchSourcePayloads()\n const instance = new this(sourcePayloads)\n\n const paths = jsonPath.split('.')\n instance.sourcePrices = sourcePayloads.map((payload) => {\n return { x: payload.timestamp, y: instance.jsonPathTraverser(payload, paths) }\n })\n return instance\n }\n\n // TODO - fetch from archivist\n static async fetchSourcePayloads() {\n const payloads = await Promise.resolve(MockSourcePayloads())\n return payloads\n }\n\n jsonPathTraverser(obj: Payload, path: string[]) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let result: any = obj\n for (const key of path) {\n if (key in result) {\n const foundKey = key as keyof typeof result\n result = result[foundKey]\n } else {\n result = undefined\n break\n }\n }\n\n return result\n }\n}\n","import type { PayloadRenderPlugin } from '@xyo-network/react-payload-plugin'\nimport { createPayloadRenderPlugin } from '@xyo-network/react-payload-plugin'\n\nimport { PriceForecastDetailsBox } from './components/index.ts'\n\nexport const PriceForecastRenderPlugin: PayloadRenderPlugin = {\n ...createPayloadRenderPlugin({\n canRender: () => true,\n components: { box: { detailsBox: PriceForecastDetailsBox } },\n name: 'PriceForecast',\n }),\n}\n"],"mappings":"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","names":["data","options"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xyo-network/react-price-forecast-plugin",
|
|
3
|
-
"version": "7.5.
|
|
3
|
+
"version": "7.5.11",
|
|
4
4
|
"description": "Common React library for all XYO projects that use React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"xyo",
|
|
@@ -36,55 +36,179 @@
|
|
|
36
36
|
},
|
|
37
37
|
"./package.json": "./package.json"
|
|
38
38
|
},
|
|
39
|
-
"module": "dist/browser/index.mjs",
|
|
40
|
-
"types": "dist/browser/index.d.ts",
|
|
41
39
|
"files": [
|
|
42
40
|
"dist",
|
|
43
|
-
"
|
|
41
|
+
"README.md"
|
|
44
42
|
],
|
|
45
43
|
"dependencies": {
|
|
46
|
-
"@
|
|
47
|
-
"@xylabs/react-flexbox": "~7.1.17",
|
|
48
|
-
"@xylabs/react-theme": "~7.1.17",
|
|
49
|
-
"@xyo-network/diviner-forecasting-model": "~5.3.17",
|
|
50
|
-
"@xyo-network/payload-model": "~5.3.17",
|
|
51
|
-
"@xyo-network/react-payload-plugin": "7.5.8",
|
|
52
|
-
"chart.js": "~4.5.1",
|
|
53
|
-
"chartjs-adapter-luxon": "~1.3.1",
|
|
54
|
-
"react-chartjs-2": "~5.3.1"
|
|
44
|
+
"@xyo-network/react-payload-plugin": "~7.5.11"
|
|
55
45
|
},
|
|
56
46
|
"devDependencies": {
|
|
57
|
-
"@
|
|
58
|
-
"@emotion/
|
|
59
|
-
"@
|
|
60
|
-
"@mui/material": "
|
|
61
|
-
"@
|
|
47
|
+
"@bitauth/libauth": "~3.0.0",
|
|
48
|
+
"@emotion/react": "^11.14.0",
|
|
49
|
+
"@emotion/styled": "^11.14.1",
|
|
50
|
+
"@mui/icons-material": "^7.3.10",
|
|
51
|
+
"@mui/material": "^7.3.10",
|
|
52
|
+
"@mui/system": "^7.3.10",
|
|
53
|
+
"@mui/x-tree-view": "~8.27.2",
|
|
54
|
+
"@opentelemetry/api": "^1.9.1",
|
|
55
|
+
"@opentelemetry/sdk-trace-base": "^2.7.0",
|
|
56
|
+
"@scure/base": "~2.2.0",
|
|
57
|
+
"@storybook/react-vite": "~10.3.5",
|
|
58
|
+
"@textea/json-viewer": "~4.0.1",
|
|
59
|
+
"@types/node": "~25.6.0",
|
|
62
60
|
"@types/react": "^19.2.14",
|
|
63
|
-
"@xylabs/
|
|
64
|
-
"@xylabs/
|
|
65
|
-
"@xylabs/
|
|
66
|
-
"@xylabs/
|
|
67
|
-
"@xylabs/
|
|
61
|
+
"@xylabs/react-async-effect": "~7.1.20",
|
|
62
|
+
"@xylabs/react-button": "~7.1.20",
|
|
63
|
+
"@xylabs/react-dialogs": "~7.1.20",
|
|
64
|
+
"@xylabs/react-flexbox": "~7.1.20",
|
|
65
|
+
"@xylabs/react-hooks": "~7.1.20",
|
|
66
|
+
"@xylabs/react-identicon": "~7.1.20",
|
|
67
|
+
"@xylabs/react-link": "~7.1.20",
|
|
68
|
+
"@xylabs/react-promise": "~7.1.20",
|
|
69
|
+
"@xylabs/react-quick-tip-button": "~7.1.20",
|
|
70
|
+
"@xylabs/react-select": "~7.1.20",
|
|
71
|
+
"@xylabs/react-shared": "~7.1.20",
|
|
72
|
+
"@xylabs/react-theme": "~7.1.20",
|
|
73
|
+
"@xylabs/sdk-js": "^5.0.100",
|
|
74
|
+
"@xylabs/threads": "~5.0.100",
|
|
75
|
+
"@xylabs/toolchain": "~7.11.9",
|
|
76
|
+
"@xylabs/tsconfig": "^7.11.9",
|
|
77
|
+
"@xylabs/tsconfig-dom": "^7.11.9",
|
|
78
|
+
"@xylabs/tsconfig-react": "~7.11.9",
|
|
79
|
+
"@xylabs/zod": "~5.0.100",
|
|
80
|
+
"@xyo-network/account": "~5.5.1",
|
|
81
|
+
"@xyo-network/account-model": "^5.5.1",
|
|
82
|
+
"@xyo-network/boundwitness-builder": "^5.5.1",
|
|
83
|
+
"@xyo-network/boundwitness-model": "^5.5.1",
|
|
84
|
+
"@xyo-network/boundwitness-validator": "^5.5.1",
|
|
85
|
+
"@xyo-network/boundwitness-wrapper": "~5.5.1",
|
|
86
|
+
"@xyo-network/config-payload-plugin": "~5.5.1",
|
|
87
|
+
"@xyo-network/diviner-forecasting-model": "~5.5.5",
|
|
88
|
+
"@xyo-network/diviner-model": "^5.5.5",
|
|
89
|
+
"@xyo-network/diviner-schema-list-model": "~5.5.2",
|
|
90
|
+
"@xyo-network/diviner-schema-stats-model": "~5.5.2",
|
|
91
|
+
"@xyo-network/manifest-model": "~5.5.1",
|
|
92
|
+
"@xyo-network/module-abstract": "^5.5.5",
|
|
93
|
+
"@xyo-network/module-model": "^5.5.5",
|
|
94
|
+
"@xyo-network/node-core-types": "~4.1.10",
|
|
95
|
+
"@xyo-network/node-memory": "~5.5.5",
|
|
96
|
+
"@xyo-network/node-model": "^5.5.5",
|
|
97
|
+
"@xyo-network/payload-builder": "^5.5.1",
|
|
98
|
+
"@xyo-network/payload-model": "^5.5.1",
|
|
99
|
+
"@xyo-network/payload-validator": "^5.5.1",
|
|
100
|
+
"@xyo-network/query-payload-plugin": "~5.5.1",
|
|
101
|
+
"@xyo-network/schema-cache": "~5.5.1",
|
|
102
|
+
"@xyo-network/schema-payload-plugin": "~5.5.1",
|
|
103
|
+
"@xyo-network/typeof": "~5.3.30",
|
|
104
|
+
"@xyo-network/wallet-model": "^5.5.1",
|
|
105
|
+
"ajv": "^8.18.0",
|
|
106
|
+
"async-mutex": "^0.5.0",
|
|
107
|
+
"axios": "^1.15.2",
|
|
108
|
+
"bn.js": "^5.2.3",
|
|
109
|
+
"bowser": "^2.14.1",
|
|
110
|
+
"buffer": "^6.0.3",
|
|
111
|
+
"chalk": "^5.6.2",
|
|
112
|
+
"chart.js": "^4.5.1",
|
|
113
|
+
"chartjs-adapter-luxon": "~1.3.1",
|
|
114
|
+
"debug": "~4.4.3",
|
|
115
|
+
"esbuild": "~0.28.0",
|
|
116
|
+
"eslint": "^10.2.1",
|
|
117
|
+
"ethers": "^6.16.0",
|
|
118
|
+
"fast-deep-equal": "~3.1.3",
|
|
119
|
+
"hash-wasm": "~4.12.0",
|
|
120
|
+
"js-cookie": "~3.0.5",
|
|
121
|
+
"lru-cache": "^11.3.5",
|
|
68
122
|
"luxon": "^3.7.2",
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"react
|
|
72
|
-
"
|
|
123
|
+
"observable-fns": "~0.6.1",
|
|
124
|
+
"pako": "^2.1.0",
|
|
125
|
+
"react": "^19.2.5",
|
|
126
|
+
"react-chartjs-2": "~5.3.1",
|
|
127
|
+
"react-dom": "^19.2.5",
|
|
128
|
+
"react-router-dom": "^7.14.2",
|
|
129
|
+
"spark-md5": "~3.0.2",
|
|
130
|
+
"storybook": "^10.3.5",
|
|
73
131
|
"typescript": "^5.9.3",
|
|
74
|
-
"vite": "
|
|
132
|
+
"vite": "^8.0.10",
|
|
133
|
+
"wasm-feature-detect": "~1.8.0",
|
|
75
134
|
"zod": "^4.3.6"
|
|
76
135
|
},
|
|
77
136
|
"peerDependencies": {
|
|
78
|
-
"@
|
|
79
|
-
"@
|
|
80
|
-
"
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"
|
|
137
|
+
"@emotion/react": "^11.14.0",
|
|
138
|
+
"@emotion/styled": "^11.14.1",
|
|
139
|
+
"@mui/icons-material": "^7.3.10",
|
|
140
|
+
"@mui/material": "^7.3.10",
|
|
141
|
+
"@mui/system": "^7.3.10",
|
|
142
|
+
"@mui/x-tree-view": "~8.27.2",
|
|
143
|
+
"@opentelemetry/api": "^1.9.1",
|
|
144
|
+
"@opentelemetry/sdk-trace-base": "^2.7.0",
|
|
145
|
+
"@scure/base": "~2.2.0",
|
|
146
|
+
"@textea/json-viewer": "~4.0.1",
|
|
147
|
+
"@xylabs/react-async-effect": "~7.1.20",
|
|
148
|
+
"@xylabs/react-button": "~7.1.20",
|
|
149
|
+
"@xylabs/react-dialogs": "~7.1.20",
|
|
150
|
+
"@xylabs/react-flexbox": "~7.1.20",
|
|
151
|
+
"@xylabs/react-hooks": "~7.1.20",
|
|
152
|
+
"@xylabs/react-identicon": "~7.1.20",
|
|
153
|
+
"@xylabs/react-link": "~7.1.20",
|
|
154
|
+
"@xylabs/react-promise": "~7.1.20",
|
|
155
|
+
"@xylabs/react-quick-tip-button": "~7.1.20",
|
|
156
|
+
"@xylabs/react-select": "~7.1.20",
|
|
157
|
+
"@xylabs/react-shared": "~7.1.20",
|
|
158
|
+
"@xylabs/react-theme": "~7.1.20",
|
|
159
|
+
"@xylabs/sdk-js": "^5.0.100",
|
|
160
|
+
"@xylabs/tsconfig": "^7.11.9",
|
|
161
|
+
"@xylabs/tsconfig-dom": "^7.11.9",
|
|
162
|
+
"@xylabs/zod": "~5.0.100",
|
|
163
|
+
"@xyo-network/account": "~5.5.1",
|
|
164
|
+
"@xyo-network/account-model": "^5.5.1",
|
|
165
|
+
"@xyo-network/boundwitness-builder": "^5.5.1",
|
|
166
|
+
"@xyo-network/boundwitness-model": "^5.5.1",
|
|
167
|
+
"@xyo-network/boundwitness-validator": "^5.5.1",
|
|
168
|
+
"@xyo-network/boundwitness-wrapper": "~5.5.1",
|
|
169
|
+
"@xyo-network/config-payload-plugin": "~5.5.1",
|
|
170
|
+
"@xyo-network/diviner-forecasting-model": "~5.5.5",
|
|
171
|
+
"@xyo-network/diviner-model": "^5.5.5",
|
|
172
|
+
"@xyo-network/diviner-schema-list-model": "~5.5.2",
|
|
173
|
+
"@xyo-network/diviner-schema-stats-model": "~5.5.2",
|
|
174
|
+
"@xyo-network/manifest-model": "~5.5.1",
|
|
175
|
+
"@xyo-network/module-abstract": "^5.5.5",
|
|
176
|
+
"@xyo-network/module-model": "^5.5.5",
|
|
177
|
+
"@xyo-network/node-core-types": "~4.1.10",
|
|
178
|
+
"@xyo-network/node-memory": "~5.5.5",
|
|
179
|
+
"@xyo-network/node-model": "^5.5.5",
|
|
180
|
+
"@xyo-network/payload-builder": "^5.5.1",
|
|
181
|
+
"@xyo-network/payload-model": "^5.5.1",
|
|
182
|
+
"@xyo-network/payload-validator": "^5.5.1",
|
|
183
|
+
"@xyo-network/query-payload-plugin": "~5.5.1",
|
|
184
|
+
"@xyo-network/schema-cache": "~5.5.1",
|
|
185
|
+
"@xyo-network/schema-payload-plugin": "~5.5.1",
|
|
186
|
+
"@xyo-network/typeof": "~5.3.30",
|
|
187
|
+
"@xyo-network/wallet-model": "^5.5.1",
|
|
188
|
+
"ajv": "^8.18.0",
|
|
189
|
+
"async-mutex": "^0.5.0",
|
|
190
|
+
"axios": "^1.15.2",
|
|
191
|
+
"bn.js": "^5.2.3",
|
|
192
|
+
"bowser": "^2.14.1",
|
|
193
|
+
"buffer": "^6.0.3",
|
|
194
|
+
"chalk": "^5.6.2",
|
|
195
|
+
"chart.js": "^4.5.1",
|
|
196
|
+
"chartjs-adapter-luxon": "~1.3.1",
|
|
197
|
+
"ethers": "^6.16.0",
|
|
198
|
+
"fast-deep-equal": "~3.1.3",
|
|
199
|
+
"js-cookie": "~3.0.5",
|
|
200
|
+
"lru-cache": "^11.3.5",
|
|
201
|
+
"luxon": "^3.7.2",
|
|
202
|
+
"pako": "^2.1.0",
|
|
203
|
+
"react": "^19.2.5",
|
|
204
|
+
"react-chartjs-2": "~5.3.1",
|
|
205
|
+
"react-dom": "^19.2.5",
|
|
206
|
+
"react-router-dom": "^7.14.2",
|
|
207
|
+
"spark-md5": "~3.0.2",
|
|
208
|
+
"zod": "^4.3.6"
|
|
85
209
|
},
|
|
86
210
|
"publishConfig": {
|
|
87
211
|
"access": "public"
|
|
88
212
|
},
|
|
89
213
|
"docs": "dist/docs.json"
|
|
90
|
-
}
|
|
214
|
+
}
|
package/src/Plugin.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { PayloadRenderPlugin } from '@xyo-network/react-payload-plugin'
|
|
2
|
-
import { createPayloadRenderPlugin } from '@xyo-network/react-payload-plugin'
|
|
3
|
-
|
|
4
|
-
import { PriceForecastDetailsBox } from './components/index.ts'
|
|
5
|
-
|
|
6
|
-
export const PriceForecastRenderPlugin: PayloadRenderPlugin = {
|
|
7
|
-
...createPayloadRenderPlugin({
|
|
8
|
-
canRender: () => true,
|
|
9
|
-
components: { box: { detailsBox: PriceForecastDetailsBox } },
|
|
10
|
-
name: 'PriceForecast',
|
|
11
|
-
}),
|
|
12
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Button, ButtonGroup, Typography,
|
|
3
|
-
} from '@mui/material'
|
|
4
|
-
import type { Meta, StoryFn } from '@storybook/react-vite'
|
|
5
|
-
import { FlexCol } from '@xylabs/react-flexbox'
|
|
6
|
-
import { ForecastPayloadSchema } from '@xyo-network/diviner-forecasting-model'
|
|
7
|
-
import type { RefObject } from 'react'
|
|
8
|
-
import React, { useRef, useState } from 'react'
|
|
9
|
-
|
|
10
|
-
import { MockSourcePayloads } from '../lib/index.ts'
|
|
11
|
-
import { PriceForecastDetailsBox } from './DetailsBox.tsx'
|
|
12
|
-
|
|
13
|
-
const tenMin = 600_000
|
|
14
|
-
|
|
15
|
-
const ForecastingDivinerPayload = {
|
|
16
|
-
schema: ForecastPayloadSchema,
|
|
17
|
-
values: [1, 2, 3, 4, 5, 6, 7, 8].map(item => ({
|
|
18
|
-
error: 0,
|
|
19
|
-
timestamp: Date.now() + tenMin * item,
|
|
20
|
-
value: 100 * item,
|
|
21
|
-
})),
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const StorybookEntry = {
|
|
25
|
-
argTypes: {},
|
|
26
|
-
component: PriceForecastDetailsBox,
|
|
27
|
-
parameters: { docs: { page: null } },
|
|
28
|
-
title: 'plugin/price-forecast/DetailsBox',
|
|
29
|
-
} as Meta<typeof PriceForecastDetailsBox>
|
|
30
|
-
|
|
31
|
-
const Template: StoryFn<typeof PriceForecastDetailsBox> = ({ payload, ...args }) => {
|
|
32
|
-
const [showPayloads, setShowPayloads] = useState(false)
|
|
33
|
-
const forecastPayloadRef = useRef<HTMLParagraphElement>(null)
|
|
34
|
-
const sourcePayloadsRef = useRef<HTMLParagraphElement>(null)
|
|
35
|
-
const handleClick = (ref: RefObject<HTMLParagraphElement | null>) => {
|
|
36
|
-
setShowPayloads(!showPayloads)
|
|
37
|
-
if (ref.current) ref.current.scrollIntoView({ behavior: 'smooth', block: 'start' })
|
|
38
|
-
}
|
|
39
|
-
return (
|
|
40
|
-
<>
|
|
41
|
-
<PriceForecastDetailsBox mb={3} payload={payload} {...args} />
|
|
42
|
-
<FlexCol>
|
|
43
|
-
<ButtonGroup>
|
|
44
|
-
<Button variant="contained" onClick={() => handleClick(forecastPayloadRef)}>
|
|
45
|
-
Forecast Payload
|
|
46
|
-
</Button>
|
|
47
|
-
<Button variant="contained" onClick={() => handleClick(sourcePayloadsRef)}>
|
|
48
|
-
Source Payloads
|
|
49
|
-
</Button>
|
|
50
|
-
</ButtonGroup>
|
|
51
|
-
</FlexCol>
|
|
52
|
-
<pre>
|
|
53
|
-
<Typography ref={forecastPayloadRef}>
|
|
54
|
-
ForecastPayload:
|
|
55
|
-
{' '}
|
|
56
|
-
<code>{JSON.stringify(payload, null, 2)}</code>
|
|
57
|
-
</Typography>
|
|
58
|
-
</pre>
|
|
59
|
-
<pre>
|
|
60
|
-
<Typography ref={sourcePayloadsRef}>
|
|
61
|
-
SourcePayloads:
|
|
62
|
-
{' '}
|
|
63
|
-
<pre>{JSON.stringify(MockSourcePayloads(), null, 2)}</pre>
|
|
64
|
-
</Typography>
|
|
65
|
-
</pre>
|
|
66
|
-
</>
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const Default = Template.bind({})
|
|
71
|
-
Default.args = {}
|
|
72
|
-
|
|
73
|
-
const WithData = Template.bind({})
|
|
74
|
-
WithData.args = { payload: ForecastingDivinerPayload }
|
|
75
|
-
|
|
76
|
-
export { Default, WithData }
|
|
77
|
-
|
|
78
|
-
export default StorybookEntry
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import 'chartjs-adapter-luxon'
|
|
2
|
-
|
|
3
|
-
import { useTheme } from '@mui/material'
|
|
4
|
-
import { useAsyncEffect } from '@xylabs/react-async-effect'
|
|
5
|
-
import type { FlexBoxProps } from '@xylabs/react-flexbox'
|
|
6
|
-
import { FlexCol } from '@xylabs/react-flexbox'
|
|
7
|
-
import type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'
|
|
8
|
-
import type { Payload } from '@xyo-network/payload-model'
|
|
9
|
-
import type {
|
|
10
|
-
ChartData,
|
|
11
|
-
ChartOptions,
|
|
12
|
-
} from 'chart.js'
|
|
13
|
-
import {
|
|
14
|
-
CategoryScale,
|
|
15
|
-
Chart as ChartJS,
|
|
16
|
-
Legend,
|
|
17
|
-
LinearScale,
|
|
18
|
-
LineElement,
|
|
19
|
-
PointElement,
|
|
20
|
-
TimeScale,
|
|
21
|
-
Title,
|
|
22
|
-
Tooltip,
|
|
23
|
-
} from 'chart.js'
|
|
24
|
-
import React, { useState } from 'react'
|
|
25
|
-
import { Line } from 'react-chartjs-2'
|
|
26
|
-
|
|
27
|
-
import { ForecastLineChartConfigBuilder } from '../lib/index.ts'
|
|
28
|
-
|
|
29
|
-
ChartJS.register(CategoryScale, TimeScale, PointElement, LineElement, LinearScale, Title, Tooltip, Legend)
|
|
30
|
-
|
|
31
|
-
export interface PriceForecastDetailsBoxProps extends FlexBoxProps {
|
|
32
|
-
payload?: Payload
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const PriceForecastDetailsBox: React.FC<PriceForecastDetailsBoxProps> = ({ payload, ...props }) => {
|
|
36
|
-
const priceForecastPayload = payload as ForecastPayload | undefined
|
|
37
|
-
const theme = useTheme()
|
|
38
|
-
const [data, setData] = useState<ChartData<'line'>>({ datasets: [] })
|
|
39
|
-
const [options, setOptions] = useState<ChartOptions<'line'>>({})
|
|
40
|
-
|
|
41
|
-
useAsyncEffect(
|
|
42
|
-
|
|
43
|
-
async (mounted) => {
|
|
44
|
-
const { data, options } = await ForecastLineChartConfigBuilder.create(theme, priceForecastPayload, { fetch: true })
|
|
45
|
-
if (mounted()) {
|
|
46
|
-
setData(data)
|
|
47
|
-
setOptions(options)
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
[priceForecastPayload, theme],
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<FlexCol {...props} busy={priceForecastPayload === undefined} minHeight="25vh">
|
|
55
|
-
{priceForecastPayload
|
|
56
|
-
? <Line options={options} data={data} />
|
|
57
|
-
: null}
|
|
58
|
-
</FlexCol>
|
|
59
|
-
)
|
|
60
|
-
}
|
package/src/components/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './DetailsBox.tsx'
|
package/src/global.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import '@mui/material/themeCssVarsAugmentation'
|
package/src/index.ts
DELETED
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
import type { Theme } from '@mui/material'
|
|
2
|
-
import { useIsDark } from '@xylabs/react-theme'
|
|
3
|
-
import type { ForecastPayload } from '@xyo-network/diviner-forecasting-model'
|
|
4
|
-
import type {
|
|
5
|
-
ChartData, ChartDataset, ChartOptions, LegendOptions, Point, ScaleChartOptions,
|
|
6
|
-
} from 'chart.js'
|
|
7
|
-
|
|
8
|
-
import { DataLineStyles } from './DataLineStyles.ts'
|
|
9
|
-
import { DataPointStyles } from './DataPointStyles.ts'
|
|
10
|
-
import { SourcePayloads } from './SourcePayloads.ts'
|
|
11
|
-
|
|
12
|
-
interface SourcePayloadConfig {
|
|
13
|
-
fetch: boolean
|
|
14
|
-
sampleSize?: number
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface ThemeColors {
|
|
18
|
-
dataSetColorPrimary: string
|
|
19
|
-
dataSetColorSecondary: string
|
|
20
|
-
gridColor: string
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const defaultOptions: () => ChartOptions<'line'> = () => ({
|
|
24
|
-
plugins: { legend: { position: 'top' as const } },
|
|
25
|
-
responsive: true,
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
export class ForecastLineChartConfigBuilder {
|
|
29
|
-
data: ChartData<'line'> = { datasets: [] }
|
|
30
|
-
|
|
31
|
-
options: ChartOptions<'line'> = defaultOptions()
|
|
32
|
-
themeColors: ThemeColors | undefined
|
|
33
|
-
|
|
34
|
-
private payload?: ForecastPayload
|
|
35
|
-
|
|
36
|
-
constructor(
|
|
37
|
-
theme: Theme,
|
|
38
|
-
payload?: ForecastPayload,
|
|
39
|
-
) {
|
|
40
|
-
this.payload = payload
|
|
41
|
-
this.themeColors = this.parseTheme(theme)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
get forecastPayload() {
|
|
45
|
-
if (this.payload) {
|
|
46
|
-
return this.payload
|
|
47
|
-
} else {
|
|
48
|
-
throw new Error('ForecastPayload was not defined')
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
static async create(theme: Theme, payload?: ForecastPayload, sourcePayloadConfig?: SourcePayloadConfig) {
|
|
53
|
-
const instance = new ForecastLineChartConfigBuilder(theme, payload)
|
|
54
|
-
|
|
55
|
-
await instance.build(sourcePayloadConfig?.fetch)
|
|
56
|
-
|
|
57
|
-
instance.refreshValues()
|
|
58
|
-
|
|
59
|
-
return instance
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async build(includeSources?: boolean) {
|
|
63
|
-
this.buildOptions()
|
|
64
|
-
await this.buildData(includeSources)
|
|
65
|
-
return this
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async buildData(includeSources?: boolean) {
|
|
69
|
-
const forecastData = this.generateDataSetForecastData()
|
|
70
|
-
|
|
71
|
-
const datasets: ChartDataset<'line'>[] = [forecastData]
|
|
72
|
-
|
|
73
|
-
if (includeSources) {
|
|
74
|
-
// build data from sources in forecastPayload
|
|
75
|
-
const sourceData = await this.generateDataSetSourcePayloads()
|
|
76
|
-
datasets.unshift(sourceData)
|
|
77
|
-
|
|
78
|
-
// add last source point as first item in prediction to connect the lines
|
|
79
|
-
const lastSourceDataItem = sourceData.data.at(-1) as Point
|
|
80
|
-
forecastData.data.unshift(lastSourceDataItem)
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
this.data = { datasets }
|
|
84
|
-
|
|
85
|
-
return this
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
buildOptions() {
|
|
89
|
-
if (this.options.plugins) {
|
|
90
|
-
this.options.plugins.title = this.generateTitle()
|
|
91
|
-
this.options.plugins.legend = this.generateLegend()
|
|
92
|
-
}
|
|
93
|
-
this.options.scales = this.generateScales()
|
|
94
|
-
|
|
95
|
-
return this
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
refreshValues() {
|
|
99
|
-
this.data = { ...this.data }
|
|
100
|
-
this.options = { ...this.options }
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
protected generateLegend() {
|
|
104
|
-
return {
|
|
105
|
-
labels: {
|
|
106
|
-
pointStyle: 'circle',
|
|
107
|
-
usePointStyle: true,
|
|
108
|
-
},
|
|
109
|
-
} as LegendOptions<'line'>
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
protected generateScales() {
|
|
113
|
-
return {
|
|
114
|
-
x: {
|
|
115
|
-
grid: { color: this.themeColors?.gridColor },
|
|
116
|
-
time: { unit: 'minute' },
|
|
117
|
-
type: 'time',
|
|
118
|
-
},
|
|
119
|
-
y: { grid: { color: this.themeColors?.gridColor } },
|
|
120
|
-
} as unknown as ScaleChartOptions<'line'>['scales']
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
protected generateTitle() {
|
|
124
|
-
return {
|
|
125
|
-
display: true,
|
|
126
|
-
text: `Gas Price Forecaster (GWEI over time from ${
|
|
127
|
-
this.forecastPayload?.values[0].timestamp ? new Date(this.forecastPayload.values[0].timestamp).toLocaleDateString() : ''
|
|
128
|
-
})`,
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
protected parseTheme(theme: Theme) {
|
|
133
|
-
// eslint-disable-next-line react-x/rules-of-hooks, react-hooks/rules-of-hooks
|
|
134
|
-
const dark = useIsDark()
|
|
135
|
-
return {
|
|
136
|
-
dataSetColorPrimary: theme.vars.palette.primary.light,
|
|
137
|
-
dataSetColorSecondary: theme.vars.palette.secondary.light,
|
|
138
|
-
gridColor: dark ? theme.vars.palette.grey[800] : theme.vars.palette.grey[300],
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private generateDataSetForecastData(): ChartDataset<'line'> {
|
|
143
|
-
return {
|
|
144
|
-
borderDash: [5],
|
|
145
|
-
borderDashOffset: 0.5,
|
|
146
|
-
data: this.forecastPayload.values.map(price => ({ x: price.timestamp ?? 0, y: price.value })),
|
|
147
|
-
label: 'Forecast Price',
|
|
148
|
-
...DataPointStyles(this.themeColors?.dataSetColorPrimary),
|
|
149
|
-
...DataLineStyles(this.themeColors?.dataSetColorPrimary),
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
private async generateDataSetSourcePayloads(): Promise<ChartDataset<'line'>> {
|
|
154
|
-
const { sourcePrices } = await SourcePayloads.build('feePerGas.medium')
|
|
155
|
-
return {
|
|
156
|
-
data: sourcePrices,
|
|
157
|
-
label: 'Source Prices',
|
|
158
|
-
...DataLineStyles(this.themeColors?.dataSetColorSecondary),
|
|
159
|
-
...DataPointStyles(this.themeColors?.dataSetColorSecondary),
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { asSchema } from '@xyo-network/payload-model'
|
|
2
|
-
|
|
3
|
-
export const MockSourcePayloads = () => {
|
|
4
|
-
const tenMin = 600_000
|
|
5
|
-
return [
|
|
6
|
-
{
|
|
7
|
-
baseFee: 38.901_553_878_25,
|
|
8
|
-
feePerGas: {
|
|
9
|
-
high: 47.994_586_439_6, low: 39.006_868_093, medium: 39.306_868_093, veryHigh: 44.453_843_805_25,
|
|
10
|
-
},
|
|
11
|
-
priorityFeePerGas: {
|
|
12
|
-
high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,
|
|
13
|
-
},
|
|
14
|
-
schema: asSchema('network.xyo.blockchain.ethereum.gas', true),
|
|
15
|
-
timestamp: Date.now() - tenMin,
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
baseFee: 38.901_553_878_25,
|
|
19
|
-
feePerGas: {
|
|
20
|
-
high: 47.994_586_439_6, low: 39.006_868_093, medium: 100, veryHigh: 44.453_843_805_25,
|
|
21
|
-
},
|
|
22
|
-
priorityFeePerGas: {
|
|
23
|
-
high: 1.026_666_666_666_666_6, low: -0.410_000_000_000_000_03, medium: 0.38, veryHigh: 1.390_000_000_000_000_1,
|
|
24
|
-
},
|
|
25
|
-
schema: asSchema('network.xyo.blockchain.ethereum.gas', true),
|
|
26
|
-
timestamp: Date.now(),
|
|
27
|
-
},
|
|
28
|
-
]
|
|
29
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { Payload } from '@xyo-network/payload-model'
|
|
2
|
-
import type { Point } from 'chart.js'
|
|
3
|
-
|
|
4
|
-
import { MockSourcePayloads } from './MockSourcePayloads.ts'
|
|
5
|
-
|
|
6
|
-
export class SourcePayloads {
|
|
7
|
-
sourcePayloads: Payload[]
|
|
8
|
-
sourcePrices: Point[] = []
|
|
9
|
-
|
|
10
|
-
constructor(sourcePayloads: Payload[]) {
|
|
11
|
-
this.sourcePayloads = sourcePayloads
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
get payloads() {
|
|
15
|
-
return this.sourcePayloads
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
static async build(jsonPath: string) {
|
|
19
|
-
const sourcePayloads = await this.fetchSourcePayloads()
|
|
20
|
-
const instance = new this(sourcePayloads)
|
|
21
|
-
|
|
22
|
-
const paths = jsonPath.split('.')
|
|
23
|
-
instance.sourcePrices = sourcePayloads.map((payload) => {
|
|
24
|
-
return { x: payload.timestamp, y: instance.jsonPathTraverser(payload, paths) }
|
|
25
|
-
})
|
|
26
|
-
return instance
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// TODO - fetch from archivist
|
|
30
|
-
static async fetchSourcePayloads() {
|
|
31
|
-
const payloads = await Promise.resolve(MockSourcePayloads())
|
|
32
|
-
return payloads
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
jsonPathTraverser(obj: Payload, path: string[]) {
|
|
36
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
-
let result: any = obj
|
|
38
|
-
for (const key of path) {
|
|
39
|
-
if (key in result) {
|
|
40
|
-
const foundKey = key as keyof typeof result
|
|
41
|
-
result = result[foundKey]
|
|
42
|
-
} else {
|
|
43
|
-
result = undefined
|
|
44
|
-
break
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return result
|
|
49
|
-
}
|
|
50
|
-
}
|
package/src/lib/index.ts
DELETED