@signals-protocol/v1-sdk 1.1.0 → 1.2.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/dist/index.d.ts +2 -1
- package/dist/index.js +6 -1
- package/dist/share/assets.d.ts +3 -0
- package/dist/share/assets.js +22 -0
- package/dist/share/brand-image.d.ts +2 -0
- package/dist/share/brand-image.js +107 -0
- package/dist/share/distribution-image.d.ts +2 -0
- package/dist/share/distribution-image.js +294 -0
- package/dist/share/distribution-share-utils.d.ts +8 -0
- package/dist/share/distribution-share-utils.js +63 -0
- package/dist/share/format.d.ts +6 -0
- package/dist/share/format.js +56 -0
- package/dist/share/h.d.ts +2 -0
- package/dist/share/h.js +10 -0
- package/dist/share/index.d.ts +8 -0
- package/dist/share/index.js +30 -0
- package/dist/share/position-image.d.ts +2 -0
- package/dist/share/position-image.js +337 -0
- package/dist/share/types.d.ts +39 -0
- package/dist/share/types.js +2 -0
- package/package.json +4 -1
package/dist/index.d.ts
CHANGED
|
@@ -9,4 +9,5 @@ export { WADAmount, USDCAmount, Quantity, Tick, MarketDistributionRaw, MarketRaw
|
|
|
9
9
|
export * as MathUtils from "./utils/math";
|
|
10
10
|
export { toWAD, toMicroUSDC } from "./clmsr-sdk";
|
|
11
11
|
export { createCLMSRSDK, createSignalsSDK } from "./clmsr-sdk";
|
|
12
|
-
export
|
|
12
|
+
export * from "./share";
|
|
13
|
+
export declare const VERSION = "1.2.0";
|
package/dist/index.js
CHANGED
|
@@ -37,6 +37,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
return result;
|
|
38
38
|
};
|
|
39
39
|
})();
|
|
40
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
41
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
42
|
+
};
|
|
40
43
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
44
|
exports.VERSION = exports.createSignalsSDK = exports.createCLMSRSDK = exports.toMicroUSDC = exports.toWAD = exports.MathUtils = exports.CalculationError = exports.ValidationError = exports.mapDistribution = exports.mapMarket = exports.SignalsSDK = exports.CLMSRSDK = void 0;
|
|
42
45
|
// Export main SDK class
|
|
@@ -61,5 +64,7 @@ Object.defineProperty(exports, "toMicroUSDC", { enumerable: true, get: function
|
|
|
61
64
|
var clmsr_sdk_4 = require("./clmsr-sdk");
|
|
62
65
|
Object.defineProperty(exports, "createCLMSRSDK", { enumerable: true, get: function () { return clmsr_sdk_4.createCLMSRSDK; } });
|
|
63
66
|
Object.defineProperty(exports, "createSignalsSDK", { enumerable: true, get: function () { return clmsr_sdk_4.createSignalsSDK; } });
|
|
67
|
+
// Share image VNode templates
|
|
68
|
+
__exportStar(require("./share"), exports);
|
|
64
69
|
// Version (keep in sync with package.json)
|
|
65
|
-
exports.VERSION = "1.
|
|
70
|
+
exports.VERSION = "1.2.0";
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { SatoriNode } from "./types";
|
|
2
|
+
export declare const SIGNALS_LOGO_URI = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTciIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNyAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSI4LjUwMDI0IiB5PSIwIiB3aWR0aD0iNCIgaGVpZ2h0PSI0IiBmaWxsPSIjMTQ0NGMyIi8+PHJlY3QgeD0iOC41MDAyNCIgeT0iNC4wMDAwNiIgd2lkdGg9IjQiIGhlaWdodD0iNCIgZmlsbD0iIzE0NDRjMiIvPjxyZWN0IHg9IjAuNSIgeT0iMTIiIHdpZHRoPSI0IiBoZWlnaHQ9IjQiIGZpbGw9IiMxNDQ0YzIiLz48cmVjdCB4PSIxMi41IiB5PSI4LjAwMDA2IiB3aWR0aD0iNCIgaGVpZ2h0PSI0IiBmaWxsPSIjMTQ0NGMyIi8+PHJlY3QgeD0iMTIuNSIgeT0iMCIgd2lkdGg9IjQiIGhlaWdodD0iNCIgZmlsbD0iIzE0NDRjMiIvPjxyZWN0IHg9IjQuNTAwMjQiIHk9IjAiIHdpZHRoPSI0IiBoZWlnaHQ9IjQiIGZpbGw9IiMxNDQ0YzIiLz48cmVjdCB4PSIxMi41IiB5PSI0LjAwMDA2IiB3aWR0aD0iNCIgaGVpZ2h0PSI0IiBmaWxsPSIjMTQ0NGMyIi8+PHJlY3QgeD0iNC41MDAyNCIgeT0iOC4wMDAwNiIgd2lkdGg9IjQiIGhlaWdodD0iNCIgZmlsbD0iIzE0NDRjMiIvPjwvc3ZnPg==";
|
|
3
|
+
export declare function buildLogoStrokeSVG(size: number, theme: "light" | "dark"): SatoriNode;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SIGNALS_LOGO_URI = void 0;
|
|
4
|
+
exports.buildLogoStrokeSVG = buildLogoStrokeSVG;
|
|
5
|
+
const h_1 = require("./h");
|
|
6
|
+
// Signals logo SVG (pixel block pattern) as base64 data URI
|
|
7
|
+
exports.SIGNALS_LOGO_URI = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTciIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNyAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cmVjdCB4PSI4LjUwMDI0IiB5PSIwIiB3aWR0aD0iNCIgaGVpZ2h0PSI0IiBmaWxsPSIjMTQ0NGMyIi8+PHJlY3QgeD0iOC41MDAyNCIgeT0iNC4wMDAwNiIgd2lkdGg9IjQiIGhlaWdodD0iNCIgZmlsbD0iIzE0NDRjMiIvPjxyZWN0IHg9IjAuNSIgeT0iMTIiIHdpZHRoPSI0IiBoZWlnaHQ9IjQiIGZpbGw9IiMxNDQ0YzIiLz48cmVjdCB4PSIxMi41IiB5PSI4LjAwMDA2IiB3aWR0aD0iNCIgaGVpZ2h0PSI0IiBmaWxsPSIjMTQ0NGMyIi8+PHJlY3QgeD0iMTIuNSIgeT0iMCIgd2lkdGg9IjQiIGhlaWdodD0iNCIgZmlsbD0iIzE0NDRjMiIvPjxyZWN0IHg9IjQuNTAwMjQiIHk9IjAiIHdpZHRoPSI0IiBoZWlnaHQ9IjQiIGZpbGw9IiMxNDQ0YzIiLz48cmVjdCB4PSIxMi41IiB5PSI0LjAwMDA2IiB3aWR0aD0iNCIgaGVpZ2h0PSI0IiBmaWxsPSIjMTQ0NGMyIi8+PHJlY3QgeD0iNC41MDAyNCIgeT0iOC4wMDAwNiIgd2lkdGg9IjQiIGhlaWdodD0iNCIgZmlsbD0iIzE0NDRjMiIvPjwvc3ZnPg==";
|
|
8
|
+
function buildLogoStrokeSVG(size, theme) {
|
|
9
|
+
const stroke = theme === "dark" ? "white" : "#1444c2";
|
|
10
|
+
return (0, h_1.h)("svg", {
|
|
11
|
+
width: size,
|
|
12
|
+
height: size,
|
|
13
|
+
viewBox: "0 0 1362 1362",
|
|
14
|
+
style: { display: "flex" },
|
|
15
|
+
}, (0, h_1.h)("path", {
|
|
16
|
+
d: "M341 1021H1V1361H341V1021ZM341 1021H681V681.006M341 1021V681.006H681M681 681.006L1021 680.994V1021H1361V1H341V340.997H681V681.006Z",
|
|
17
|
+
stroke,
|
|
18
|
+
strokeOpacity: "0.4",
|
|
19
|
+
strokeWidth: "2",
|
|
20
|
+
fill: "none",
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildBrandVNode = buildBrandVNode;
|
|
4
|
+
const h_1 = require("./h");
|
|
5
|
+
const assets_1 = require("./assets");
|
|
6
|
+
function buildLogoStrokeSVG(size) {
|
|
7
|
+
return (0, h_1.h)("svg", {
|
|
8
|
+
width: size,
|
|
9
|
+
height: size,
|
|
10
|
+
viewBox: "0 0 1362 1362",
|
|
11
|
+
style: { display: "flex" },
|
|
12
|
+
}, (0, h_1.h)("path", {
|
|
13
|
+
d: "M341 1021H1V1361H341V1021ZM341 1021H681V681.006M341 1021V681.006H681M681 681.006L1021 680.994V1021H1361V1H341V340.997H681V681.006Z",
|
|
14
|
+
stroke: "white",
|
|
15
|
+
strokeOpacity: "0.4",
|
|
16
|
+
strokeWidth: "2",
|
|
17
|
+
fill: "none",
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
function buildBrandVNode() {
|
|
21
|
+
return (0, h_1.h)("div", {
|
|
22
|
+
style: {
|
|
23
|
+
width: 1200,
|
|
24
|
+
height: 630,
|
|
25
|
+
display: "flex",
|
|
26
|
+
fontFamily: "Inter",
|
|
27
|
+
position: "relative",
|
|
28
|
+
overflow: "hidden",
|
|
29
|
+
background: "linear-gradient(135deg, #0d1528, #0e1633)",
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
// Blue radial glow
|
|
33
|
+
(0, h_1.h)("div", {
|
|
34
|
+
style: {
|
|
35
|
+
position: "absolute",
|
|
36
|
+
top: 0,
|
|
37
|
+
left: 0,
|
|
38
|
+
right: 0,
|
|
39
|
+
bottom: 0,
|
|
40
|
+
background: "radial-gradient(circle at 30% 30%, rgba(20,68,194,0.25), transparent 60%)",
|
|
41
|
+
display: "flex",
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
// LogoStrokeSVG watermark
|
|
45
|
+
(0, h_1.h)("div", {
|
|
46
|
+
style: {
|
|
47
|
+
position: "absolute",
|
|
48
|
+
right: 8,
|
|
49
|
+
top: 8,
|
|
50
|
+
bottom: 8,
|
|
51
|
+
display: "flex",
|
|
52
|
+
},
|
|
53
|
+
}, buildLogoStrokeSVG(614)),
|
|
54
|
+
// Content
|
|
55
|
+
(0, h_1.h)("div", {
|
|
56
|
+
style: {
|
|
57
|
+
display: "flex",
|
|
58
|
+
flexDirection: "column",
|
|
59
|
+
justifyContent: "center",
|
|
60
|
+
position: "relative",
|
|
61
|
+
width: "100%",
|
|
62
|
+
height: "100%",
|
|
63
|
+
padding: "60px 64px",
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
// Logo + "Signals"
|
|
67
|
+
(0, h_1.h)("div", {
|
|
68
|
+
style: {
|
|
69
|
+
display: "flex",
|
|
70
|
+
alignItems: "center",
|
|
71
|
+
gap: 16,
|
|
72
|
+
marginBottom: 32,
|
|
73
|
+
},
|
|
74
|
+
}, (0, h_1.h)("img", {
|
|
75
|
+
src: assets_1.SIGNALS_LOGO_URI,
|
|
76
|
+
width: 68,
|
|
77
|
+
height: 64,
|
|
78
|
+
style: { display: "flex" },
|
|
79
|
+
}), (0, h_1.h)("span", {
|
|
80
|
+
style: {
|
|
81
|
+
fontSize: 56,
|
|
82
|
+
fontWeight: 700,
|
|
83
|
+
color: "#1444c2",
|
|
84
|
+
display: "flex",
|
|
85
|
+
},
|
|
86
|
+
}, "Signals")),
|
|
87
|
+
// Subtitle
|
|
88
|
+
(0, h_1.h)("div", {
|
|
89
|
+
style: {
|
|
90
|
+
fontSize: 28,
|
|
91
|
+
fontWeight: 500,
|
|
92
|
+
color: "rgba(255,255,255,0.70)",
|
|
93
|
+
lineHeight: 1.4,
|
|
94
|
+
display: "flex",
|
|
95
|
+
},
|
|
96
|
+
}, "Range-Based Bitcoin Price Prediction Market"),
|
|
97
|
+
// Spacer
|
|
98
|
+
(0, h_1.h)("div", { style: { flex: 1, display: "flex" } }),
|
|
99
|
+
// Footer handle
|
|
100
|
+
(0, h_1.h)("div", { style: { display: "flex" } }, (0, h_1.h)("span", {
|
|
101
|
+
style: {
|
|
102
|
+
fontSize: 20,
|
|
103
|
+
color: "rgba(255,255,255,0.50)",
|
|
104
|
+
display: "flex",
|
|
105
|
+
},
|
|
106
|
+
}, "@signalswtf"))));
|
|
107
|
+
}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildDistributionVNode = buildDistributionVNode;
|
|
4
|
+
const h_1 = require("./h");
|
|
5
|
+
const assets_1 = require("./assets");
|
|
6
|
+
const distribution_share_utils_1 = require("./distribution-share-utils");
|
|
7
|
+
const BAR_COLORS = {
|
|
8
|
+
peak: { bg: "#F7931A", opacity: 0.9 },
|
|
9
|
+
high: { bg: "#2d88ff", opacity: 0.5 },
|
|
10
|
+
mid: { bg: "#5a6a7a", opacity: 0.3 },
|
|
11
|
+
low: { bg: "#3a4555", opacity: 0.15 },
|
|
12
|
+
};
|
|
13
|
+
function formatPrice(price) {
|
|
14
|
+
return "$" + Math.round(price).toLocaleString("en-US");
|
|
15
|
+
}
|
|
16
|
+
function buildDistributionVNode(input) {
|
|
17
|
+
const { distribution, minTick, maxTick, tickSpacing, closingPriceDate, currentPrice, } = input;
|
|
18
|
+
const maxProb = Math.max(...distribution.map((d) => d.probability));
|
|
19
|
+
const [peakLo, peakHi] = (0, distribution_share_utils_1.getPeakRange)(distribution, tickSpacing);
|
|
20
|
+
const xTicks = (0, distribution_share_utils_1.generateXAxisTicks)(minTick, maxTick);
|
|
21
|
+
const range = maxTick - minTick;
|
|
22
|
+
// Build histogram bars
|
|
23
|
+
const bars = distribution.map((tick) => {
|
|
24
|
+
const category = (0, distribution_share_utils_1.getBarCategory)(tick.probability, maxProb);
|
|
25
|
+
const height = (0, distribution_share_utils_1.getSqrtHeight)(tick.probability, maxProb);
|
|
26
|
+
const { bg, opacity } = BAR_COLORS[category];
|
|
27
|
+
const isPeak = category === "peak";
|
|
28
|
+
if (isPeak) {
|
|
29
|
+
return (0, h_1.h)("div", {
|
|
30
|
+
style: {
|
|
31
|
+
display: "flex",
|
|
32
|
+
flexDirection: "column",
|
|
33
|
+
flex: 1,
|
|
34
|
+
minWidth: 0,
|
|
35
|
+
height: `${height}%`,
|
|
36
|
+
alignItems: "center",
|
|
37
|
+
justifyContent: "flex-end",
|
|
38
|
+
},
|
|
39
|
+
}, (0, h_1.h)("span", {
|
|
40
|
+
style: {
|
|
41
|
+
fontSize: 14,
|
|
42
|
+
fontWeight: 700,
|
|
43
|
+
color: "#F7931A",
|
|
44
|
+
marginBottom: 4,
|
|
45
|
+
},
|
|
46
|
+
}, `${(tick.probability * 100).toFixed(1)}%`), (0, h_1.h)("div", {
|
|
47
|
+
style: {
|
|
48
|
+
width: "100%",
|
|
49
|
+
flex: 1,
|
|
50
|
+
background: bg,
|
|
51
|
+
opacity,
|
|
52
|
+
borderRadius: "3px 3px 0 0",
|
|
53
|
+
},
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
return (0, h_1.h)("div", {
|
|
57
|
+
style: {
|
|
58
|
+
flex: 1,
|
|
59
|
+
minWidth: 0,
|
|
60
|
+
height: `${height}%`,
|
|
61
|
+
display: "flex",
|
|
62
|
+
},
|
|
63
|
+
}, (0, h_1.h)("div", {
|
|
64
|
+
style: {
|
|
65
|
+
width: "100%",
|
|
66
|
+
height: "100%",
|
|
67
|
+
background: bg,
|
|
68
|
+
opacity,
|
|
69
|
+
borderRadius: "3px 3px 0 0",
|
|
70
|
+
},
|
|
71
|
+
}));
|
|
72
|
+
});
|
|
73
|
+
// X-axis labels
|
|
74
|
+
const xLabels = xTicks.map((price) => {
|
|
75
|
+
const pos = ((price - minTick) / range) * 100;
|
|
76
|
+
return (0, h_1.h)("div", {
|
|
77
|
+
style: {
|
|
78
|
+
position: "absolute",
|
|
79
|
+
left: `${pos}%`,
|
|
80
|
+
fontSize: 15,
|
|
81
|
+
fontWeight: 500,
|
|
82
|
+
color: "rgba(255,255,255,0.5)",
|
|
83
|
+
display: "flex",
|
|
84
|
+
},
|
|
85
|
+
}, (0, distribution_share_utils_1.formatXTick)(price));
|
|
86
|
+
});
|
|
87
|
+
return (0, h_1.h)("div", {
|
|
88
|
+
style: {
|
|
89
|
+
width: 1200,
|
|
90
|
+
height: 630,
|
|
91
|
+
display: "flex",
|
|
92
|
+
flexDirection: "column",
|
|
93
|
+
fontFamily: "Inter",
|
|
94
|
+
background: "linear-gradient(140deg, #0a1120, #0d1730)",
|
|
95
|
+
padding: "40px 48px 28px",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
// Main row
|
|
99
|
+
(0, h_1.h)("div", {
|
|
100
|
+
style: { display: "flex", flex: 1, gap: 40, minHeight: 0 },
|
|
101
|
+
},
|
|
102
|
+
// Left panel
|
|
103
|
+
(0, h_1.h)("div", {
|
|
104
|
+
style: {
|
|
105
|
+
display: "flex",
|
|
106
|
+
flexDirection: "column",
|
|
107
|
+
width: 340,
|
|
108
|
+
flexShrink: 0,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
// Logo
|
|
112
|
+
(0, h_1.h)("div", {
|
|
113
|
+
style: {
|
|
114
|
+
display: "flex",
|
|
115
|
+
alignItems: "center",
|
|
116
|
+
gap: 12,
|
|
117
|
+
marginBottom: 28,
|
|
118
|
+
},
|
|
119
|
+
}, (0, h_1.h)("img", {
|
|
120
|
+
src: assets_1.SIGNALS_LOGO_URI,
|
|
121
|
+
width: 34,
|
|
122
|
+
height: 32,
|
|
123
|
+
style: { display: "flex" },
|
|
124
|
+
}), (0, h_1.h)("span", {
|
|
125
|
+
style: { fontSize: 30, fontWeight: 700, color: "#1444c2" },
|
|
126
|
+
}, "Signals")),
|
|
127
|
+
// Market question
|
|
128
|
+
(0, h_1.h)("div", {
|
|
129
|
+
style: {
|
|
130
|
+
fontSize: 28,
|
|
131
|
+
color: "#fff",
|
|
132
|
+
lineHeight: 1.3,
|
|
133
|
+
marginBottom: 16,
|
|
134
|
+
fontWeight: 700,
|
|
135
|
+
display: "flex",
|
|
136
|
+
},
|
|
137
|
+
}, `BTC Price on ${closingPriceDate}?`),
|
|
138
|
+
// Stats
|
|
139
|
+
(0, h_1.h)("div", {
|
|
140
|
+
style: {
|
|
141
|
+
display: "flex",
|
|
142
|
+
flexDirection: "column",
|
|
143
|
+
gap: 20,
|
|
144
|
+
marginTop: 20,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
// Most Likely Price
|
|
148
|
+
(0, h_1.h)("div", {
|
|
149
|
+
style: {
|
|
150
|
+
display: "flex",
|
|
151
|
+
flexDirection: "column",
|
|
152
|
+
},
|
|
153
|
+
}, (0, h_1.h)("div", {
|
|
154
|
+
style: {
|
|
155
|
+
fontSize: 14,
|
|
156
|
+
letterSpacing: "0.05em",
|
|
157
|
+
textTransform: "uppercase",
|
|
158
|
+
color: "rgba(255,255,255,0.5)",
|
|
159
|
+
marginBottom: 4,
|
|
160
|
+
display: "flex",
|
|
161
|
+
},
|
|
162
|
+
}, "Most Likely Price"), (0, h_1.h)("div", {
|
|
163
|
+
style: {
|
|
164
|
+
fontSize: 40,
|
|
165
|
+
lineHeight: 1.1,
|
|
166
|
+
color: "#F7931A",
|
|
167
|
+
fontWeight: 700,
|
|
168
|
+
display: "flex",
|
|
169
|
+
},
|
|
170
|
+
}, (0, distribution_share_utils_1.formatDistributionPriceRange)(peakLo, peakHi))),
|
|
171
|
+
// Current Price
|
|
172
|
+
...(currentPrice != null
|
|
173
|
+
? [
|
|
174
|
+
(0, h_1.h)("div", {
|
|
175
|
+
style: {
|
|
176
|
+
display: "flex",
|
|
177
|
+
flexDirection: "column",
|
|
178
|
+
},
|
|
179
|
+
}, (0, h_1.h)("div", {
|
|
180
|
+
style: {
|
|
181
|
+
fontSize: 14,
|
|
182
|
+
letterSpacing: "0.05em",
|
|
183
|
+
textTransform: "uppercase",
|
|
184
|
+
color: "rgba(255,255,255,0.5)",
|
|
185
|
+
marginBottom: 4,
|
|
186
|
+
display: "flex",
|
|
187
|
+
},
|
|
188
|
+
}, "Current Price"), (0, h_1.h)("div", {
|
|
189
|
+
style: {
|
|
190
|
+
fontSize: 28,
|
|
191
|
+
lineHeight: 1.1,
|
|
192
|
+
color: "#fff",
|
|
193
|
+
fontWeight: 700,
|
|
194
|
+
display: "flex",
|
|
195
|
+
},
|
|
196
|
+
}, formatPrice(currentPrice))),
|
|
197
|
+
]
|
|
198
|
+
: [])),
|
|
199
|
+
// Spacer
|
|
200
|
+
(0, h_1.h)("div", { style: { flex: 1, display: "flex" } })),
|
|
201
|
+
// Right panel — histogram
|
|
202
|
+
(0, h_1.h)("div", {
|
|
203
|
+
style: {
|
|
204
|
+
flex: 1,
|
|
205
|
+
display: "flex",
|
|
206
|
+
flexDirection: "column",
|
|
207
|
+
},
|
|
208
|
+
},
|
|
209
|
+
// Chart subtitle
|
|
210
|
+
(0, h_1.h)("div", {
|
|
211
|
+
style: {
|
|
212
|
+
textAlign: "right",
|
|
213
|
+
fontSize: 14,
|
|
214
|
+
color: "rgba(255,255,255,0.5)",
|
|
215
|
+
marginBottom: 6,
|
|
216
|
+
flexShrink: 0,
|
|
217
|
+
display: "flex",
|
|
218
|
+
justifyContent: "flex-end",
|
|
219
|
+
},
|
|
220
|
+
}, `$${tickSpacing} ranges`),
|
|
221
|
+
// Histogram area
|
|
222
|
+
(0, h_1.h)("div", {
|
|
223
|
+
style: {
|
|
224
|
+
flex: 1,
|
|
225
|
+
display: "flex",
|
|
226
|
+
flexDirection: "column",
|
|
227
|
+
position: "relative",
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
// Bars
|
|
231
|
+
(0, h_1.h)("div", {
|
|
232
|
+
style: {
|
|
233
|
+
flex: 1,
|
|
234
|
+
display: "flex",
|
|
235
|
+
alignItems: "flex-end",
|
|
236
|
+
gap: 1,
|
|
237
|
+
paddingTop: 22,
|
|
238
|
+
},
|
|
239
|
+
}, ...bars),
|
|
240
|
+
// Current price vertical marker
|
|
241
|
+
...(currentPrice != null &&
|
|
242
|
+
currentPrice >= minTick &&
|
|
243
|
+
currentPrice <= maxTick
|
|
244
|
+
? [
|
|
245
|
+
(0, h_1.h)("div", {
|
|
246
|
+
style: {
|
|
247
|
+
position: "absolute",
|
|
248
|
+
left: `${((currentPrice - minTick) / range) * 100}%`,
|
|
249
|
+
top: 0,
|
|
250
|
+
bottom: 28,
|
|
251
|
+
width: 2,
|
|
252
|
+
background: "rgba(255,255,255,0.6)",
|
|
253
|
+
display: "flex",
|
|
254
|
+
},
|
|
255
|
+
}),
|
|
256
|
+
(0, h_1.h)("div", {
|
|
257
|
+
style: {
|
|
258
|
+
position: "absolute",
|
|
259
|
+
left: `${((currentPrice - minTick) / range) * 100}%`,
|
|
260
|
+
top: 2,
|
|
261
|
+
fontSize: 11,
|
|
262
|
+
fontWeight: 700,
|
|
263
|
+
color: "rgba(255,255,255,0.7)",
|
|
264
|
+
display: "flex",
|
|
265
|
+
marginLeft: 6,
|
|
266
|
+
},
|
|
267
|
+
}, "Current"),
|
|
268
|
+
]
|
|
269
|
+
: []),
|
|
270
|
+
// X-axis
|
|
271
|
+
(0, h_1.h)("div", {
|
|
272
|
+
style: {
|
|
273
|
+
display: "flex",
|
|
274
|
+
position: "relative",
|
|
275
|
+
borderTop: "1px solid rgba(255,255,255,0.1)",
|
|
276
|
+
height: 28,
|
|
277
|
+
paddingTop: 8,
|
|
278
|
+
},
|
|
279
|
+
}, ...xLabels)))),
|
|
280
|
+
// Footer
|
|
281
|
+
(0, h_1.h)("div", {
|
|
282
|
+
style: {
|
|
283
|
+
display: "flex",
|
|
284
|
+
justifyContent: "space-between",
|
|
285
|
+
alignItems: "center",
|
|
286
|
+
paddingTop: 10,
|
|
287
|
+
flexShrink: 0,
|
|
288
|
+
},
|
|
289
|
+
}, (0, h_1.h)("span", {
|
|
290
|
+
style: { fontSize: 14, color: "rgba(255,255,255,0.5)" },
|
|
291
|
+
}, "@signalswtf"), (0, h_1.h)("span", {
|
|
292
|
+
style: { fontSize: 14, color: "rgba(255,255,255,0.5)" },
|
|
293
|
+
}, "signals.wtf")));
|
|
294
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { BarCategory, PriceTick } from "./types";
|
|
2
|
+
export declare function getBarCategory(prob: number, maxProb: number): BarCategory;
|
|
3
|
+
export declare function getSqrtHeight(prob: number, maxProb: number): number;
|
|
4
|
+
export declare function generateXAxisTicks(minTick: number, maxTick: number, targetCount?: number): number[];
|
|
5
|
+
export declare function formatXTick(price: number): string;
|
|
6
|
+
export declare function getPeakRange(distribution: PriceTick[], tickSpacing: number): [number, number];
|
|
7
|
+
/** Distribution-specific price range format (em-dash, no decimals) */
|
|
8
|
+
export declare function formatDistributionPriceRange(lo: number, hi: number): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getBarCategory = getBarCategory;
|
|
4
|
+
exports.getSqrtHeight = getSqrtHeight;
|
|
5
|
+
exports.generateXAxisTicks = generateXAxisTicks;
|
|
6
|
+
exports.formatXTick = formatXTick;
|
|
7
|
+
exports.getPeakRange = getPeakRange;
|
|
8
|
+
exports.formatDistributionPriceRange = formatDistributionPriceRange;
|
|
9
|
+
function getBarCategory(prob, maxProb) {
|
|
10
|
+
if (prob === maxProb)
|
|
11
|
+
return "peak";
|
|
12
|
+
if (prob > maxProb * 0.4)
|
|
13
|
+
return "high";
|
|
14
|
+
if (prob > 0.001)
|
|
15
|
+
return "mid";
|
|
16
|
+
return "low";
|
|
17
|
+
}
|
|
18
|
+
function getSqrtHeight(prob, maxProb) {
|
|
19
|
+
if (prob <= 0.001)
|
|
20
|
+
return 0.8;
|
|
21
|
+
return Math.max(Math.sqrt(prob / maxProb) * 100, 1.5);
|
|
22
|
+
}
|
|
23
|
+
const TICK_STEPS = [500, 1000, 2000, 5000, 10000, 20000];
|
|
24
|
+
function generateXAxisTicks(minTick, maxTick, targetCount = 6) {
|
|
25
|
+
const range = maxTick - minTick;
|
|
26
|
+
let bestStep = 2000;
|
|
27
|
+
let bestDiff = Infinity;
|
|
28
|
+
for (const step of TICK_STEPS) {
|
|
29
|
+
const count = Math.floor(range / step);
|
|
30
|
+
const diff = Math.abs(count - targetCount);
|
|
31
|
+
if (diff < bestDiff) {
|
|
32
|
+
bestDiff = diff;
|
|
33
|
+
bestStep = step;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const ticks = [];
|
|
37
|
+
const firstTick = Math.ceil(minTick / bestStep) * bestStep;
|
|
38
|
+
for (let t = firstTick; t <= maxTick; t += bestStep) {
|
|
39
|
+
ticks.push(t);
|
|
40
|
+
}
|
|
41
|
+
return ticks;
|
|
42
|
+
}
|
|
43
|
+
function formatXTick(price) {
|
|
44
|
+
return `$${Math.round(price / 1000)}K`;
|
|
45
|
+
}
|
|
46
|
+
function getPeakRange(distribution, tickSpacing) {
|
|
47
|
+
let peakIdx = 0;
|
|
48
|
+
let maxProb = -1;
|
|
49
|
+
for (let i = 0; i < distribution.length; i++) {
|
|
50
|
+
if (distribution[i].probability > maxProb) {
|
|
51
|
+
maxProb = distribution[i].probability;
|
|
52
|
+
peakIdx = i;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const halfSpacing = tickSpacing / 2;
|
|
56
|
+
const peakPrice = distribution[peakIdx].price;
|
|
57
|
+
return [peakPrice - halfSpacing, peakPrice + halfSpacing];
|
|
58
|
+
}
|
|
59
|
+
/** Distribution-specific price range format (em-dash, no decimals) */
|
|
60
|
+
function formatDistributionPriceRange(lo, hi) {
|
|
61
|
+
const fmt = (v) => "$" + v.toLocaleString("en-US");
|
|
62
|
+
return `${fmt(lo)}\u2013${fmt(hi)}`;
|
|
63
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function formatUSDC(raw: string): string;
|
|
2
|
+
export declare function formatPrice(tick: number): string;
|
|
3
|
+
export declare function formatPriceRange(lower: number, upper: number): string;
|
|
4
|
+
export declare function percForm(value: number): string;
|
|
5
|
+
export declare function formatUsdPnl(value: number): string;
|
|
6
|
+
export declare function getPnlColor(pnl: number, neutral: string): string;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatUSDC = formatUSDC;
|
|
4
|
+
exports.formatPrice = formatPrice;
|
|
5
|
+
exports.formatPriceRange = formatPriceRange;
|
|
6
|
+
exports.percForm = percForm;
|
|
7
|
+
exports.formatUsdPnl = formatUsdPnl;
|
|
8
|
+
exports.getPnlColor = getPnlColor;
|
|
9
|
+
const USDC_DECIMALS = 6;
|
|
10
|
+
function formatUSDC(raw) {
|
|
11
|
+
const num = Number(raw) / 10 ** USDC_DECIMALS;
|
|
12
|
+
if (num >= 1000)
|
|
13
|
+
return ("$" +
|
|
14
|
+
num.toLocaleString("en-US", {
|
|
15
|
+
minimumFractionDigits: 0,
|
|
16
|
+
maximumFractionDigits: 0,
|
|
17
|
+
}));
|
|
18
|
+
return ("$" +
|
|
19
|
+
num.toLocaleString("en-US", {
|
|
20
|
+
minimumFractionDigits: 2,
|
|
21
|
+
maximumFractionDigits: 2,
|
|
22
|
+
}));
|
|
23
|
+
}
|
|
24
|
+
function formatPrice(tick) {
|
|
25
|
+
return "$" + tick.toLocaleString("en-US");
|
|
26
|
+
}
|
|
27
|
+
function formatPriceRange(lower, upper) {
|
|
28
|
+
const formatToK = (value) => {
|
|
29
|
+
if (value >= 1000)
|
|
30
|
+
return `$${(value / 1000).toFixed(1)}K`;
|
|
31
|
+
return `$${value}`;
|
|
32
|
+
};
|
|
33
|
+
return `${formatToK(lower)} - ${formatToK(upper)}`;
|
|
34
|
+
}
|
|
35
|
+
function percForm(value) {
|
|
36
|
+
const perc = Math.round(value * 10000) / 100;
|
|
37
|
+
return (perc.toLocaleString(undefined, {
|
|
38
|
+
minimumFractionDigits: 0,
|
|
39
|
+
maximumFractionDigits: 2,
|
|
40
|
+
}) + "%");
|
|
41
|
+
}
|
|
42
|
+
function formatUsdPnl(value) {
|
|
43
|
+
const abs = Math.abs(value);
|
|
44
|
+
const formatted = abs.toLocaleString("en-US", {
|
|
45
|
+
minimumFractionDigits: 2,
|
|
46
|
+
maximumFractionDigits: 2,
|
|
47
|
+
});
|
|
48
|
+
if (value === 0)
|
|
49
|
+
return `$${formatted}`;
|
|
50
|
+
return value > 0 ? `+$${formatted}` : `-$${formatted}`;
|
|
51
|
+
}
|
|
52
|
+
function getPnlColor(pnl, neutral) {
|
|
53
|
+
if (pnl === 0)
|
|
54
|
+
return neutral;
|
|
55
|
+
return pnl > 0 ? "#22c55e" : "#ef4444";
|
|
56
|
+
}
|
package/dist/share/h.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.h = h;
|
|
4
|
+
function h(type, props, ...children) {
|
|
5
|
+
if (children.length === 0)
|
|
6
|
+
return { type, props: { ...props } };
|
|
7
|
+
if (children.length === 1)
|
|
8
|
+
return { type, props: { ...props, children: children[0] } };
|
|
9
|
+
return { type, props: { ...props, children } };
|
|
10
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { SatoriNode, PositionImageInput, DistributionImageInput, PriceTick, BarCategory, } from "./types";
|
|
2
|
+
export { buildPositionVNode } from "./position-image";
|
|
3
|
+
export { buildDistributionVNode } from "./distribution-image";
|
|
4
|
+
export { buildBrandVNode } from "./brand-image";
|
|
5
|
+
export { h } from "./h";
|
|
6
|
+
export { SIGNALS_LOGO_URI, buildLogoStrokeSVG } from "./assets";
|
|
7
|
+
export { formatUSDC, formatPrice, formatPriceRange, percForm, formatUsdPnl, getPnlColor, } from "./format";
|
|
8
|
+
export { getBarCategory, getSqrtHeight, generateXAxisTicks, formatXTick, getPeakRange, formatDistributionPriceRange, } from "./distribution-share-utils";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.formatDistributionPriceRange = exports.getPeakRange = exports.formatXTick = exports.generateXAxisTicks = exports.getSqrtHeight = exports.getBarCategory = exports.getPnlColor = exports.formatUsdPnl = exports.percForm = exports.formatPriceRange = exports.formatPrice = exports.formatUSDC = exports.buildLogoStrokeSVG = exports.SIGNALS_LOGO_URI = exports.h = exports.buildBrandVNode = exports.buildDistributionVNode = exports.buildPositionVNode = void 0;
|
|
4
|
+
// VNode builders
|
|
5
|
+
var position_image_1 = require("./position-image");
|
|
6
|
+
Object.defineProperty(exports, "buildPositionVNode", { enumerable: true, get: function () { return position_image_1.buildPositionVNode; } });
|
|
7
|
+
var distribution_image_1 = require("./distribution-image");
|
|
8
|
+
Object.defineProperty(exports, "buildDistributionVNode", { enumerable: true, get: function () { return distribution_image_1.buildDistributionVNode; } });
|
|
9
|
+
var brand_image_1 = require("./brand-image");
|
|
10
|
+
Object.defineProperty(exports, "buildBrandVNode", { enumerable: true, get: function () { return brand_image_1.buildBrandVNode; } });
|
|
11
|
+
// Helpers (used by v1-server for its own distribution rendering)
|
|
12
|
+
var h_1 = require("./h");
|
|
13
|
+
Object.defineProperty(exports, "h", { enumerable: true, get: function () { return h_1.h; } });
|
|
14
|
+
var assets_1 = require("./assets");
|
|
15
|
+
Object.defineProperty(exports, "SIGNALS_LOGO_URI", { enumerable: true, get: function () { return assets_1.SIGNALS_LOGO_URI; } });
|
|
16
|
+
Object.defineProperty(exports, "buildLogoStrokeSVG", { enumerable: true, get: function () { return assets_1.buildLogoStrokeSVG; } });
|
|
17
|
+
var format_1 = require("./format");
|
|
18
|
+
Object.defineProperty(exports, "formatUSDC", { enumerable: true, get: function () { return format_1.formatUSDC; } });
|
|
19
|
+
Object.defineProperty(exports, "formatPrice", { enumerable: true, get: function () { return format_1.formatPrice; } });
|
|
20
|
+
Object.defineProperty(exports, "formatPriceRange", { enumerable: true, get: function () { return format_1.formatPriceRange; } });
|
|
21
|
+
Object.defineProperty(exports, "percForm", { enumerable: true, get: function () { return format_1.percForm; } });
|
|
22
|
+
Object.defineProperty(exports, "formatUsdPnl", { enumerable: true, get: function () { return format_1.formatUsdPnl; } });
|
|
23
|
+
Object.defineProperty(exports, "getPnlColor", { enumerable: true, get: function () { return format_1.getPnlColor; } });
|
|
24
|
+
var distribution_share_utils_1 = require("./distribution-share-utils");
|
|
25
|
+
Object.defineProperty(exports, "getBarCategory", { enumerable: true, get: function () { return distribution_share_utils_1.getBarCategory; } });
|
|
26
|
+
Object.defineProperty(exports, "getSqrtHeight", { enumerable: true, get: function () { return distribution_share_utils_1.getSqrtHeight; } });
|
|
27
|
+
Object.defineProperty(exports, "generateXAxisTicks", { enumerable: true, get: function () { return distribution_share_utils_1.generateXAxisTicks; } });
|
|
28
|
+
Object.defineProperty(exports, "formatXTick", { enumerable: true, get: function () { return distribution_share_utils_1.formatXTick; } });
|
|
29
|
+
Object.defineProperty(exports, "getPeakRange", { enumerable: true, get: function () { return distribution_share_utils_1.getPeakRange; } });
|
|
30
|
+
Object.defineProperty(exports, "formatDistributionPriceRange", { enumerable: true, get: function () { return distribution_share_utils_1.formatDistributionPriceRange; } });
|
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildPositionVNode = buildPositionVNode;
|
|
4
|
+
const h_1 = require("./h");
|
|
5
|
+
const assets_1 = require("./assets");
|
|
6
|
+
const format_1 = require("./format");
|
|
7
|
+
function buildPositionVNode(input) {
|
|
8
|
+
const { positionId, lowerTick, upperTick, currentQuantity, currentCost, totalQuantityBought, totalCosts, totalProceeds, outcome, closingPriceDate, isSettled, settlementTick, owner, theme, hideWallet, hideAmounts, currentValue, } = input;
|
|
9
|
+
const isDark = theme === "dark";
|
|
10
|
+
const isOpen = outcome === "OPEN";
|
|
11
|
+
// Entry: OPEN uses currentCost, settled uses totalCosts (currentCost is zeroed after claim)
|
|
12
|
+
const entry = isOpen ? Number(currentCost) / 1e6 : Number(totalCosts) / 1e6;
|
|
13
|
+
// PnL calculation:
|
|
14
|
+
// - LOSS: payout = 0
|
|
15
|
+
// - OPEN with currentValue: use SDK close proceeds
|
|
16
|
+
// - OPEN without currentValue: max payout fallback (currentQuantity)
|
|
17
|
+
// - WIN (settled): totalQuantityBought (full range payout)
|
|
18
|
+
// - CLOSED (early exit settled): totalProceeds
|
|
19
|
+
let value;
|
|
20
|
+
if (outcome === "LOSS") {
|
|
21
|
+
value = 0;
|
|
22
|
+
}
|
|
23
|
+
else if (isOpen && currentValue != null) {
|
|
24
|
+
value = currentValue;
|
|
25
|
+
}
|
|
26
|
+
else if (isOpen) {
|
|
27
|
+
value = Number(currentQuantity) / 1e6;
|
|
28
|
+
}
|
|
29
|
+
else if (outcome === "WIN") {
|
|
30
|
+
value = Number(totalQuantityBought) / 1e6;
|
|
31
|
+
}
|
|
32
|
+
else if (outcome === "CLOSED") {
|
|
33
|
+
value = Number(totalProceeds) / 1e6;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
value = 0;
|
|
37
|
+
}
|
|
38
|
+
// Snap sub-cent PnL to zero (floating-point noise from SDK calculations)
|
|
39
|
+
const rawPnl = value - entry;
|
|
40
|
+
const pnl = Math.abs(rawPnl) < 0.005 ? 0 : rawPnl;
|
|
41
|
+
const pnlPercent = entry > 0 ? pnl / entry : 0;
|
|
42
|
+
const payoutLabel = isOpen ? "Current Value" : "Payout";
|
|
43
|
+
const textPrimary = isDark ? "#ffffff" : "#000000";
|
|
44
|
+
const textSecondary = isDark
|
|
45
|
+
? "rgba(255,255,255,0.70)"
|
|
46
|
+
: "rgba(0,0,0,0.60)";
|
|
47
|
+
const textMuted = isDark ? "rgba(255,255,255,0.65)" : "rgba(0,0,0,0.55)";
|
|
48
|
+
const pnlColor = (0, format_1.getPnlColor)(pnl, textMuted);
|
|
49
|
+
const payoutDisplayValue = outcome === "LOSS"
|
|
50
|
+
? "$0.00"
|
|
51
|
+
: isOpen && currentValue != null
|
|
52
|
+
? "$" +
|
|
53
|
+
currentValue.toLocaleString("en-US", {
|
|
54
|
+
minimumFractionDigits: 2,
|
|
55
|
+
maximumFractionDigits: 2,
|
|
56
|
+
})
|
|
57
|
+
: isOpen
|
|
58
|
+
? (0, format_1.formatUSDC)(currentQuantity)
|
|
59
|
+
: outcome === "WIN"
|
|
60
|
+
? (0, format_1.formatUSDC)(totalQuantityBought)
|
|
61
|
+
: (0, format_1.formatUSDC)(totalProceeds);
|
|
62
|
+
const children = [];
|
|
63
|
+
// Background gradient
|
|
64
|
+
children.push((0, h_1.h)("div", {
|
|
65
|
+
style: {
|
|
66
|
+
position: "absolute",
|
|
67
|
+
top: 0,
|
|
68
|
+
left: 0,
|
|
69
|
+
right: 0,
|
|
70
|
+
bottom: 0,
|
|
71
|
+
background: isDark
|
|
72
|
+
? "linear-gradient(135deg, #0d1528, #0e1633)"
|
|
73
|
+
: "linear-gradient(135deg, #fbfdff, #f0f6ff)",
|
|
74
|
+
display: "flex",
|
|
75
|
+
},
|
|
76
|
+
}));
|
|
77
|
+
// Blue radial glow
|
|
78
|
+
children.push((0, h_1.h)("div", {
|
|
79
|
+
style: {
|
|
80
|
+
position: "absolute",
|
|
81
|
+
top: 0,
|
|
82
|
+
left: 0,
|
|
83
|
+
right: 0,
|
|
84
|
+
bottom: 0,
|
|
85
|
+
background: isDark
|
|
86
|
+
? "radial-gradient(circle at 25% 20%, rgba(45,136,255,0.15), transparent 65%)"
|
|
87
|
+
: "radial-gradient(circle at 22% 18%, rgba(185,221,255,0.30), transparent 40%)",
|
|
88
|
+
display: "flex",
|
|
89
|
+
},
|
|
90
|
+
}));
|
|
91
|
+
// PnL glow
|
|
92
|
+
children.push((0, h_1.h)("div", {
|
|
93
|
+
style: {
|
|
94
|
+
position: "absolute",
|
|
95
|
+
top: 0,
|
|
96
|
+
left: 0,
|
|
97
|
+
right: 0,
|
|
98
|
+
bottom: 0,
|
|
99
|
+
background: pnl >= 0
|
|
100
|
+
? isDark
|
|
101
|
+
? "radial-gradient(circle at 85% 75%, rgba(0,191,64,0.25), transparent 45%)"
|
|
102
|
+
: "radial-gradient(circle at 85% 75%, rgba(88,230,131,0.30), transparent 45%)"
|
|
103
|
+
: isDark
|
|
104
|
+
? "radial-gradient(circle at 85% 75%, rgba(239,68,68,0.25), transparent 45%)"
|
|
105
|
+
: "radial-gradient(circle at 85% 75%, rgba(252,165,165,0.30), transparent 45%)",
|
|
106
|
+
display: "flex",
|
|
107
|
+
},
|
|
108
|
+
}));
|
|
109
|
+
// LogoStrokeSVG watermark
|
|
110
|
+
children.push((0, h_1.h)("div", {
|
|
111
|
+
style: {
|
|
112
|
+
position: "absolute",
|
|
113
|
+
right: 8,
|
|
114
|
+
top: 8,
|
|
115
|
+
bottom: 8,
|
|
116
|
+
display: "flex",
|
|
117
|
+
},
|
|
118
|
+
}, (0, assets_1.buildLogoStrokeSVG)(614, theme)));
|
|
119
|
+
// Content
|
|
120
|
+
const contentChildren = [];
|
|
121
|
+
// Logo + "Signals"
|
|
122
|
+
contentChildren.push((0, h_1.h)("div", {
|
|
123
|
+
style: {
|
|
124
|
+
display: "flex",
|
|
125
|
+
alignItems: "center",
|
|
126
|
+
gap: 8,
|
|
127
|
+
marginBottom: 24,
|
|
128
|
+
},
|
|
129
|
+
}, (0, h_1.h)("img", {
|
|
130
|
+
src: assets_1.SIGNALS_LOGO_URI,
|
|
131
|
+
width: 34,
|
|
132
|
+
height: 32,
|
|
133
|
+
style: { display: "flex" },
|
|
134
|
+
}), (0, h_1.h)("span", {
|
|
135
|
+
style: {
|
|
136
|
+
fontSize: 28,
|
|
137
|
+
fontWeight: 700,
|
|
138
|
+
color: "#1444c2",
|
|
139
|
+
display: "flex",
|
|
140
|
+
},
|
|
141
|
+
}, "Signals")));
|
|
142
|
+
// Range section
|
|
143
|
+
const rangeItems = [
|
|
144
|
+
(0, h_1.h)("div", { style: { display: "flex", flexDirection: "column" } }, (0, h_1.h)("div", {
|
|
145
|
+
style: {
|
|
146
|
+
fontSize: 17,
|
|
147
|
+
color: textSecondary,
|
|
148
|
+
marginBottom: 4,
|
|
149
|
+
display: "flex",
|
|
150
|
+
},
|
|
151
|
+
}, "Range"), (0, h_1.h)("div", {
|
|
152
|
+
style: {
|
|
153
|
+
fontSize: 34,
|
|
154
|
+
fontWeight: 700,
|
|
155
|
+
color: textPrimary,
|
|
156
|
+
display: "flex",
|
|
157
|
+
},
|
|
158
|
+
}, (0, format_1.formatPriceRange)(lowerTick, upperTick))),
|
|
159
|
+
];
|
|
160
|
+
if (isSettled && settlementTick != null) {
|
|
161
|
+
rangeItems.push((0, h_1.h)("div", { style: { display: "flex", flexDirection: "column" } }, (0, h_1.h)("div", {
|
|
162
|
+
style: {
|
|
163
|
+
fontSize: 17,
|
|
164
|
+
color: textSecondary,
|
|
165
|
+
marginBottom: 4,
|
|
166
|
+
display: "flex",
|
|
167
|
+
},
|
|
168
|
+
}, "Actual Price"), (0, h_1.h)("div", {
|
|
169
|
+
style: {
|
|
170
|
+
fontSize: 34,
|
|
171
|
+
fontWeight: 700,
|
|
172
|
+
color: textPrimary,
|
|
173
|
+
display: "flex",
|
|
174
|
+
},
|
|
175
|
+
}, (0, format_1.formatPrice)(settlementTick))));
|
|
176
|
+
}
|
|
177
|
+
contentChildren.push((0, h_1.h)("div", { style: { display: "flex", gap: 48, marginBottom: 20 } }, ...rangeItems));
|
|
178
|
+
// PnL (dominant)
|
|
179
|
+
const pnlChildren = [
|
|
180
|
+
(0, h_1.h)("div", {
|
|
181
|
+
style: {
|
|
182
|
+
fontSize: 17,
|
|
183
|
+
color: textSecondary,
|
|
184
|
+
marginBottom: 2,
|
|
185
|
+
display: "flex",
|
|
186
|
+
},
|
|
187
|
+
}, "PnL"),
|
|
188
|
+
];
|
|
189
|
+
if (hideAmounts) {
|
|
190
|
+
pnlChildren.push((0, h_1.h)("div", {
|
|
191
|
+
style: {
|
|
192
|
+
fontSize: 90,
|
|
193
|
+
fontWeight: 700,
|
|
194
|
+
color: pnlColor,
|
|
195
|
+
lineHeight: 1,
|
|
196
|
+
display: "flex",
|
|
197
|
+
},
|
|
198
|
+
}, `${pnl > 0 ? "+" : pnl < 0 ? "-" : ""}${(0, format_1.percForm)(Math.abs(pnlPercent))}`));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
pnlChildren.push((0, h_1.h)("div", { style: { display: "flex", alignItems: "flex-end", gap: 8 } }, (0, h_1.h)("div", {
|
|
202
|
+
style: {
|
|
203
|
+
fontSize: 90,
|
|
204
|
+
fontWeight: 700,
|
|
205
|
+
color: pnlColor,
|
|
206
|
+
lineHeight: 1,
|
|
207
|
+
display: "flex",
|
|
208
|
+
},
|
|
209
|
+
}, (0, format_1.formatUsdPnl)(pnl)), (0, h_1.h)("div", {
|
|
210
|
+
style: {
|
|
211
|
+
fontSize: 34,
|
|
212
|
+
fontWeight: 700,
|
|
213
|
+
color: pnlColor,
|
|
214
|
+
marginBottom: 8,
|
|
215
|
+
display: "flex",
|
|
216
|
+
},
|
|
217
|
+
}, `(${(0, format_1.percForm)(pnlPercent)})`)));
|
|
218
|
+
}
|
|
219
|
+
contentChildren.push((0, h_1.h)("div", {
|
|
220
|
+
style: {
|
|
221
|
+
display: "flex",
|
|
222
|
+
flexDirection: "column",
|
|
223
|
+
marginBottom: 16,
|
|
224
|
+
},
|
|
225
|
+
}, ...pnlChildren));
|
|
226
|
+
// Date / Entry / Payout row
|
|
227
|
+
const infoItems = [
|
|
228
|
+
(0, h_1.h)("div", { style: { display: "flex", flexDirection: "column" } }, (0, h_1.h)("div", {
|
|
229
|
+
style: {
|
|
230
|
+
fontSize: 17,
|
|
231
|
+
color: textSecondary,
|
|
232
|
+
marginBottom: 4,
|
|
233
|
+
display: "flex",
|
|
234
|
+
},
|
|
235
|
+
}, "Date"), (0, h_1.h)("div", {
|
|
236
|
+
style: {
|
|
237
|
+
fontSize: 28,
|
|
238
|
+
fontWeight: 700,
|
|
239
|
+
color: textPrimary,
|
|
240
|
+
display: "flex",
|
|
241
|
+
},
|
|
242
|
+
}, closingPriceDate)),
|
|
243
|
+
];
|
|
244
|
+
if (!hideAmounts) {
|
|
245
|
+
infoItems.push((0, h_1.h)("div", { style: { display: "flex", flexDirection: "column" } }, (0, h_1.h)("div", {
|
|
246
|
+
style: {
|
|
247
|
+
fontSize: 17,
|
|
248
|
+
color: textSecondary,
|
|
249
|
+
marginBottom: 4,
|
|
250
|
+
display: "flex",
|
|
251
|
+
},
|
|
252
|
+
}, "Entry"), (0, h_1.h)("div", {
|
|
253
|
+
style: {
|
|
254
|
+
fontSize: 28,
|
|
255
|
+
fontWeight: 700,
|
|
256
|
+
color: textPrimary,
|
|
257
|
+
display: "flex",
|
|
258
|
+
},
|
|
259
|
+
}, isOpen ? (0, format_1.formatUSDC)(currentCost) : (0, format_1.formatUSDC)(totalCosts))));
|
|
260
|
+
infoItems.push((0, h_1.h)("div", { style: { display: "flex", flexDirection: "column" } }, (0, h_1.h)("div", {
|
|
261
|
+
style: {
|
|
262
|
+
fontSize: 17,
|
|
263
|
+
color: textSecondary,
|
|
264
|
+
marginBottom: 4,
|
|
265
|
+
display: "flex",
|
|
266
|
+
},
|
|
267
|
+
}, payoutLabel), (0, h_1.h)("div", {
|
|
268
|
+
style: {
|
|
269
|
+
fontSize: 28,
|
|
270
|
+
fontWeight: 700,
|
|
271
|
+
color: textPrimary,
|
|
272
|
+
display: "flex",
|
|
273
|
+
},
|
|
274
|
+
}, payoutDisplayValue)));
|
|
275
|
+
}
|
|
276
|
+
contentChildren.push((0, h_1.h)("div", { style: { display: "flex", gap: 48, marginBottom: 12 } }, ...infoItems));
|
|
277
|
+
// Owner
|
|
278
|
+
if (!hideWallet && owner) {
|
|
279
|
+
contentChildren.push((0, h_1.h)("div", {
|
|
280
|
+
style: {
|
|
281
|
+
display: "flex",
|
|
282
|
+
flexDirection: "column",
|
|
283
|
+
marginBottom: 8,
|
|
284
|
+
},
|
|
285
|
+
}, (0, h_1.h)("div", {
|
|
286
|
+
style: {
|
|
287
|
+
fontSize: 17,
|
|
288
|
+
color: textSecondary,
|
|
289
|
+
marginBottom: 4,
|
|
290
|
+
display: "flex",
|
|
291
|
+
},
|
|
292
|
+
}, "Owner"), (0, h_1.h)("div", {
|
|
293
|
+
style: {
|
|
294
|
+
fontSize: 22,
|
|
295
|
+
fontWeight: 700,
|
|
296
|
+
color: textPrimary,
|
|
297
|
+
display: "flex",
|
|
298
|
+
},
|
|
299
|
+
}, owner.slice(0, 7))));
|
|
300
|
+
}
|
|
301
|
+
// Spacer
|
|
302
|
+
contentChildren.push((0, h_1.h)("div", { style: { flex: 1, display: "flex" } }));
|
|
303
|
+
// Footer
|
|
304
|
+
contentChildren.push((0, h_1.h)("div", {
|
|
305
|
+
style: {
|
|
306
|
+
display: "flex",
|
|
307
|
+
justifyContent: "space-between",
|
|
308
|
+
alignItems: "flex-end",
|
|
309
|
+
},
|
|
310
|
+
}, (0, h_1.h)("div", { style: { display: "flex", flexDirection: "column" } }, (0, h_1.h)("span", {
|
|
311
|
+
style: { fontSize: 17, color: textMuted, display: "flex" },
|
|
312
|
+
}, "@signalswtf"), (0, h_1.h)("span", {
|
|
313
|
+
style: { fontSize: 17, color: textMuted, display: "flex" },
|
|
314
|
+
}, "Range-Based Bitcoin Price Prediction Market")), (0, h_1.h)("span", {
|
|
315
|
+
style: { fontSize: 17, color: textMuted, display: "flex" },
|
|
316
|
+
}, `#${positionId}`)));
|
|
317
|
+
children.push((0, h_1.h)("div", {
|
|
318
|
+
style: {
|
|
319
|
+
display: "flex",
|
|
320
|
+
flexDirection: "column",
|
|
321
|
+
position: "relative",
|
|
322
|
+
width: "100%",
|
|
323
|
+
height: "100%",
|
|
324
|
+
padding: "32px 40px 28px",
|
|
325
|
+
},
|
|
326
|
+
}, ...contentChildren));
|
|
327
|
+
return (0, h_1.h)("div", {
|
|
328
|
+
style: {
|
|
329
|
+
width: 1200,
|
|
330
|
+
height: 630,
|
|
331
|
+
display: "flex",
|
|
332
|
+
fontFamily: "Inter",
|
|
333
|
+
position: "relative",
|
|
334
|
+
overflow: "hidden",
|
|
335
|
+
},
|
|
336
|
+
}, ...children);
|
|
337
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface SatoriNode {
|
|
2
|
+
type: string;
|
|
3
|
+
props: Record<string, unknown>;
|
|
4
|
+
}
|
|
5
|
+
export interface PositionImageInput {
|
|
6
|
+
positionId: number;
|
|
7
|
+
lowerTick: number;
|
|
8
|
+
upperTick: number;
|
|
9
|
+
currentQuantity: string;
|
|
10
|
+
currentCost: string;
|
|
11
|
+
totalQuantityBought: string;
|
|
12
|
+
totalCosts: string;
|
|
13
|
+
totalProceeds: string;
|
|
14
|
+
outcome: string;
|
|
15
|
+
closingPriceDate: string;
|
|
16
|
+
isSettled: boolean;
|
|
17
|
+
settlementTick: number | null;
|
|
18
|
+
owner: string;
|
|
19
|
+
theme: "light" | "dark";
|
|
20
|
+
hideWallet: boolean;
|
|
21
|
+
hideAmounts: boolean;
|
|
22
|
+
/** Current position value in USDC (NOT raw). null = use max payout fallback. */
|
|
23
|
+
currentValue: number | null;
|
|
24
|
+
}
|
|
25
|
+
export type BarCategory = "peak" | "high" | "mid" | "low";
|
|
26
|
+
export interface PriceTick {
|
|
27
|
+
tick: number;
|
|
28
|
+
factor: bigint;
|
|
29
|
+
price: number;
|
|
30
|
+
probability: number;
|
|
31
|
+
}
|
|
32
|
+
export interface DistributionImageInput {
|
|
33
|
+
distribution: PriceTick[];
|
|
34
|
+
minTick: number;
|
|
35
|
+
maxTick: number;
|
|
36
|
+
tickSpacing: number;
|
|
37
|
+
closingPriceDate: string;
|
|
38
|
+
currentPrice?: number;
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signals-protocol/v1-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Signals v1 SDK for CLMSR market calculations and utilities",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
"build": "tsc",
|
|
10
10
|
"dev": "tsc --watch",
|
|
11
11
|
"test": "jest",
|
|
12
|
+
"test:cov": "jest --coverage",
|
|
12
13
|
"test:watch": "jest --watch",
|
|
14
|
+
"npm:auth": "node scripts/write-npmrc.js",
|
|
15
|
+
"publish:package": "NPM_CONFIG_USERCONFIG=.npmrc.auth npm publish",
|
|
13
16
|
"lint": "eslint src/**/*.ts",
|
|
14
17
|
"format": "prettier --write src/**/*.ts",
|
|
15
18
|
"clean": "rm -rf dist",
|