@n1xyz/wallet-widget 0.0.22 → 0.0.25
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/Modal/NordFlow/context/DepositContext.js +7 -3
- package/dist/Modal/NordFlow/context/DepositContext.js.map +1 -1
- package/dist/Modal/NordFlow/context/WalletConnectContext.js +4 -3
- package/dist/Modal/NordFlow/context/WalletConnectContext.js.map +1 -1
- package/dist/Modal/NordFlow/screens/04-AmountInputScreen.js +19 -14
- package/dist/Modal/NordFlow/screens/04-AmountInputScreen.js.map +1 -1
- package/dist/Modal/Sidebar/N1Sidebar.js +6 -2
- package/dist/Modal/Sidebar/N1Sidebar.js.map +1 -1
- package/dist/Modal/Sidebar/NordTradingView/MarketOverview/MarketOverview.d.ts +7 -2
- package/dist/Modal/Sidebar/NordTradingView/MarketOverview/MarketOverview.js +11 -8
- package/dist/Modal/Sidebar/NordTradingView/MarketOverview/MarketOverview.js.map +1 -1
- package/dist/Modal/Sidebar/NordTradingView/MarketOverview/MarketSelector.d.ts +2 -2
- package/dist/Modal/Sidebar/NordTradingView/MarketOverview/MarketSelector.js +3 -3
- package/dist/Modal/Sidebar/NordTradingView/MarketOverview/MarketSelector.js.map +1 -1
- package/dist/Modal/Sidebar/NordTradingView/MarketOverview/MarketStats.d.ts +4 -0
- package/dist/Modal/Sidebar/NordTradingView/MarketOverview/MarketStats.js +4 -0
- package/dist/Modal/Sidebar/NordTradingView/MarketOverview/MarketStats.js.map +1 -1
- package/dist/Modal/Sidebar/NordTradingView/NordTradingView.d.ts +1 -1
- package/dist/Modal/Sidebar/NordTradingView/NordTradingView.js +129 -41
- package/dist/Modal/Sidebar/NordTradingView/NordTradingView.js.map +1 -1
- package/dist/Modal/Sidebar/NordTradingView/OrderBook/OrderBook.d.ts +0 -5
- package/dist/Modal/Sidebar/NordTradingView/OrderBook/OrderBook.js +234 -195
- package/dist/Modal/Sidebar/NordTradingView/OrderBook/OrderBook.js.map +1 -1
- package/dist/Modal/Sidebar/NordTradingView/TradeForm/TradeForm.d.ts +6 -1
- package/dist/Modal/Sidebar/NordTradingView/TradeForm/TradeForm.js +11 -7
- package/dist/Modal/Sidebar/NordTradingView/TradeForm/TradeForm.js.map +1 -1
- package/dist/Modal/Sidebar/NordTradingView/UserBalances/UserBalances.d.ts +4 -0
- package/dist/Modal/Sidebar/NordTradingView/UserBalances/UserBalances.js +4 -0
- package/dist/Modal/Sidebar/NordTradingView/UserBalances/UserBalances.js.map +1 -1
- package/dist/Modal/Sidebar/NordTradingView/UserPositions/UserPositions.d.ts +0 -1
- package/dist/Modal/Sidebar/NordTradingView/UserPositions/UserPositions.js +271 -189
- package/dist/Modal/Sidebar/NordTradingView/UserPositions/UserPositions.js.map +1 -1
- package/dist/Provider/hooks/useNordUserInitialization.js +7 -4
- package/dist/Provider/hooks/useNordUserInitialization.js.map +1 -1
- package/dist/embedded-main-css.d.ts +1 -1
- package/dist/embedded-main-css.js +1 -1
- package/dist/embedded-main-css.js.map +1 -1
- package/dist/main.css +1 -1
- package/package.json +2 -3
|
@@ -1,209 +1,248 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
-
function step(op) {
|
|
15
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
-
switch (op[0]) {
|
|
20
|
-
case 0: case 1: t = op; break;
|
|
21
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
-
default:
|
|
25
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
-
if (t[2]) _.ops.pop();
|
|
30
|
-
_.trys.pop(); continue;
|
|
31
|
-
}
|
|
32
|
-
op = body.call(thisArg, _);
|
|
33
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
38
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
39
|
-
if (ar || !(i in from)) {
|
|
40
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
41
|
-
ar[i] = from[i];
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
45
|
-
};
|
|
46
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
"use strict";
|
|
2
|
+
// DEPRECATED: This entire component has been deprecated due to errors
|
|
3
|
+
// All code below has been commented out to prevent issues
|
|
4
|
+
/*
|
|
47
5
|
import { useEffect, useState } from 'react';
|
|
48
6
|
import { useN1WalletContext } from '../../../../Provider/hooks';
|
|
49
7
|
import OrderBookHeader from './OrderBookHeader';
|
|
50
8
|
import OrderBookTable from './OrderBookTable';
|
|
51
9
|
// Create a simple implementation for the missing OrderBookDepthVisualizer component
|
|
52
10
|
import { RefreshCw } from 'lucide-react';
|
|
11
|
+
|
|
53
12
|
// Simple implementation of OrderBookDepthVisualizer
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
13
|
+
const OrderBookDepthVisualizer = ({
|
|
14
|
+
data,
|
|
15
|
+
maxSize,
|
|
16
|
+
}: {
|
|
17
|
+
data: {
|
|
18
|
+
bids: Array<[number, number]>;
|
|
19
|
+
asks: Array<[number, number]>;
|
|
20
|
+
timestamp: number;
|
|
21
|
+
} | null;
|
|
22
|
+
maxSize: number;
|
|
23
|
+
}) => {
|
|
24
|
+
if (!data || data.bids.length === 0 || data.asks.length === 0) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className="mt-3">
|
|
30
|
+
<h3 className="text-xs font-medium text-n1-ww-gray-900 dark:text-n1-ww-gray-100 mb-2">
|
|
31
|
+
Depth Chart
|
|
32
|
+
</h3>
|
|
33
|
+
<div className="w-full h-24 border border-n1-ww-gray-200 dark:border-n1-ww-gray-800 rounded-sm overflow-hidden flex items-center justify-center">
|
|
34
|
+
<div className="relative w-full h-full">
|
|
35
|
+
<div className="absolute inset-0 flex">
|
|
36
|
+
<div className="w-1/2 bg-gradient-to-r from-green-500/10 to-green-500/5"></div>
|
|
37
|
+
<div className="w-1/2 bg-gradient-to-l from-red-500/10 to-red-500/5"></div>
|
|
38
|
+
</div>
|
|
39
|
+
<div className="absolute inset-0 flex items-center justify-center">
|
|
40
|
+
<div className="h-full w-px bg-n1-ww-gray-300 dark:bg-n1-ww-gray-600"></div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
60
46
|
};
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
: prev.asks;
|
|
123
|
-
return {
|
|
124
|
-
bids: updatedBids,
|
|
125
|
-
asks: updatedAsks,
|
|
126
|
-
timestamp: Date.now(),
|
|
127
|
-
};
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
return [3 /*break*/, 5];
|
|
131
|
-
case 3:
|
|
132
|
-
err_1 = _a.sent();
|
|
133
|
-
console.error('Error fetching orderbook:', err_1);
|
|
134
|
-
setError('Failed to load orderbook data');
|
|
135
|
-
return [3 /*break*/, 5];
|
|
136
|
-
case 4:
|
|
137
|
-
setLoading(false);
|
|
138
|
-
return [7 /*endfinally*/];
|
|
139
|
-
case 5: return [2 /*return*/];
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
}); };
|
|
143
|
-
fetchOrderBook();
|
|
144
|
-
// Cleanup subscription on unmount or market change
|
|
145
|
-
return function () {
|
|
146
|
-
if (subscription) {
|
|
147
|
-
subscription.close();
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
}, [marketSymbol, nord]);
|
|
151
|
-
// Aggregate orderbook data based on aggregation level
|
|
152
|
-
var aggregateOrderBook = function (data, level) {
|
|
153
|
-
if (!data)
|
|
154
|
-
return null;
|
|
155
|
-
var aggregatedBids = {};
|
|
156
|
-
var aggregatedAsks = {};
|
|
157
|
-
// Aggregate bids
|
|
158
|
-
data.bids.forEach(function (_a) {
|
|
159
|
-
var price = _a[0], size = _a[1];
|
|
160
|
-
var aggregatedPrice = Math.floor(price / level) * level;
|
|
161
|
-
aggregatedBids[aggregatedPrice] =
|
|
162
|
-
(aggregatedBids[aggregatedPrice] || 0) + size;
|
|
47
|
+
|
|
48
|
+
interface OrderBookProps {
|
|
49
|
+
marketSymbol: string | null;
|
|
50
|
+
marketId?: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface OrderBookData {
|
|
54
|
+
bids: Array<[number, number]>; // [price, size]
|
|
55
|
+
asks: Array<[number, number]>; // [price, size]
|
|
56
|
+
timestamp: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Define the OrderbookEntry interface to match the API response
|
|
60
|
+
interface OrderbookEntry {
|
|
61
|
+
price: number;
|
|
62
|
+
size: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export default function OrderBook({ marketSymbol, marketId }: OrderBookProps) {
|
|
66
|
+
const { nord } = useN1WalletContext();
|
|
67
|
+
const [orderBookData, setOrderBookData] = useState<OrderBookData | null>(
|
|
68
|
+
null
|
|
69
|
+
);
|
|
70
|
+
const [loading, setLoading] = useState(false);
|
|
71
|
+
const [error, setError] = useState<string | null>(null);
|
|
72
|
+
const [aggregationLevel, setAggregationLevel] = useState<number>(0.01);
|
|
73
|
+
|
|
74
|
+
// Fetch orderbook data when market changes
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (!marketSymbol || !nord) return;
|
|
77
|
+
|
|
78
|
+
let subscription: any = null;
|
|
79
|
+
|
|
80
|
+
const fetchOrderBook = async () => {
|
|
81
|
+
setLoading(true);
|
|
82
|
+
setError(null);
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
// Initial fetch
|
|
86
|
+
const orderbook = await nord.getOrderbook({ symbol: marketSymbol });
|
|
87
|
+
|
|
88
|
+
// The API now returns bids and asks directly as arrays of [price, size] pairs
|
|
89
|
+
// instead of OrderbookEntry objects
|
|
90
|
+
const bids: Array<[number, number]> = Array.isArray(orderbook.bids[0])
|
|
91
|
+
? (orderbook.bids as unknown as Array<[number, number]>)
|
|
92
|
+
: orderbook.bids.map((entry: OrderbookEntry) => [
|
|
93
|
+
entry.price,
|
|
94
|
+
entry.size,
|
|
95
|
+
]);
|
|
96
|
+
|
|
97
|
+
const asks: Array<[number, number]> = Array.isArray(orderbook.asks[0])
|
|
98
|
+
? (orderbook.asks as unknown as Array<[number, number]>)
|
|
99
|
+
: orderbook.asks.map((entry: OrderbookEntry) => [
|
|
100
|
+
entry.price,
|
|
101
|
+
entry.size,
|
|
102
|
+
]);
|
|
103
|
+
|
|
104
|
+
setOrderBookData({
|
|
105
|
+
bids,
|
|
106
|
+
asks,
|
|
107
|
+
timestamp: Date.now(),
|
|
163
108
|
});
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
109
|
+
|
|
110
|
+
// Subscribe to real-time updates
|
|
111
|
+
subscription = nord.subscribeOrderbook(marketSymbol);
|
|
112
|
+
subscription.on('update', (update: any) => {
|
|
113
|
+
setOrderBookData((prev) => {
|
|
114
|
+
if (!prev) return update;
|
|
115
|
+
|
|
116
|
+
// Convert OrderbookEntry[] to [number, number][] if needed
|
|
117
|
+
const updatedBids = update.bids
|
|
118
|
+
? update.bids.map((entry: OrderbookEntry) => [
|
|
119
|
+
entry.price,
|
|
120
|
+
entry.size,
|
|
121
|
+
])
|
|
122
|
+
: prev.bids;
|
|
123
|
+
|
|
124
|
+
const updatedAsks = update.asks
|
|
125
|
+
? update.asks.map((entry: OrderbookEntry) => [
|
|
126
|
+
entry.price,
|
|
127
|
+
entry.size,
|
|
128
|
+
])
|
|
129
|
+
: prev.asks;
|
|
130
|
+
|
|
131
|
+
return {
|
|
132
|
+
bids: updatedBids,
|
|
133
|
+
asks: updatedAsks,
|
|
134
|
+
timestamp: Date.now(),
|
|
135
|
+
};
|
|
136
|
+
});
|
|
170
137
|
});
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
.sort(function (a, b) { return b[0] - a[0]; });
|
|
178
|
-
var asks = Object.entries(aggregatedAsks)
|
|
179
|
-
.map(function (_a) {
|
|
180
|
-
var price = _a[0], size = _a[1];
|
|
181
|
-
return [parseFloat(price), size];
|
|
182
|
-
})
|
|
183
|
-
.sort(function (a, b) { return a[0] - b[0]; });
|
|
184
|
-
return {
|
|
185
|
-
bids: bids,
|
|
186
|
-
asks: asks,
|
|
187
|
-
timestamp: data.timestamp,
|
|
188
|
-
};
|
|
138
|
+
} catch (err) {
|
|
139
|
+
console.error('Error fetching orderbook:', err);
|
|
140
|
+
setError('Failed to load orderbook data');
|
|
141
|
+
} finally {
|
|
142
|
+
setLoading(false);
|
|
143
|
+
}
|
|
189
144
|
};
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
145
|
+
|
|
146
|
+
fetchOrderBook();
|
|
147
|
+
|
|
148
|
+
// Cleanup subscription on unmount or market change
|
|
149
|
+
return () => {
|
|
150
|
+
if (subscription) {
|
|
151
|
+
subscription.close();
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}, [marketSymbol, nord]);
|
|
155
|
+
|
|
156
|
+
// Aggregate orderbook data based on aggregation level
|
|
157
|
+
const aggregateOrderBook = (
|
|
158
|
+
data: OrderBookData | null,
|
|
159
|
+
level: number
|
|
160
|
+
): OrderBookData | null => {
|
|
161
|
+
if (!data) return null;
|
|
162
|
+
|
|
163
|
+
const aggregatedBids: { [key: number]: number } = {};
|
|
164
|
+
const aggregatedAsks: { [key: number]: number } = {};
|
|
165
|
+
|
|
166
|
+
// Aggregate bids
|
|
167
|
+
data.bids.forEach(([price, size]) => {
|
|
168
|
+
const aggregatedPrice = Math.floor(price / level) * level;
|
|
169
|
+
aggregatedBids[aggregatedPrice] =
|
|
170
|
+
(aggregatedBids[aggregatedPrice] || 0) + size;
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Aggregate asks
|
|
174
|
+
data.asks.forEach(([price, size]) => {
|
|
175
|
+
const aggregatedPrice = Math.ceil(price / level) * level;
|
|
176
|
+
aggregatedAsks[aggregatedPrice] =
|
|
177
|
+
(aggregatedAsks[aggregatedPrice] || 0) + size;
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Convert back to arrays and sort
|
|
181
|
+
const bids = Object.entries(aggregatedBids)
|
|
182
|
+
.map(([price, size]) => [parseFloat(price), size])
|
|
183
|
+
.sort((a, b) => b[0] - a[0]) as Array<[number, number]>;
|
|
184
|
+
|
|
185
|
+
const asks = Object.entries(aggregatedAsks)
|
|
186
|
+
.map(([price, size]) => [parseFloat(price), size])
|
|
187
|
+
.sort((a, b) => a[0] - b[0]) as Array<[number, number]>;
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
bids,
|
|
191
|
+
asks,
|
|
192
|
+
timestamp: data.timestamp,
|
|
205
193
|
};
|
|
206
|
-
|
|
207
|
-
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
const aggregatedData = aggregateOrderBook(orderBookData, aggregationLevel);
|
|
197
|
+
|
|
198
|
+
// Calculate max size for depth visualization
|
|
199
|
+
const calculateMaxSize = (data: OrderBookData | null): number => {
|
|
200
|
+
if (!data) return 0;
|
|
201
|
+
|
|
202
|
+
const bidSizes = data.bids.map(([_, size]) => size);
|
|
203
|
+
const askSizes = data.asks.map(([_, size]) => size);
|
|
204
|
+
const allSizes = [...bidSizes, ...askSizes];
|
|
205
|
+
|
|
206
|
+
return Math.max(...allSizes, 0);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
const maxSize = calculateMaxSize(aggregatedData);
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<div className="p-4">
|
|
213
|
+
<OrderBookHeader
|
|
214
|
+
marketSymbol={marketSymbol}
|
|
215
|
+
aggregationLevel={aggregationLevel}
|
|
216
|
+
onAggregationChange={setAggregationLevel}
|
|
217
|
+
/>
|
|
218
|
+
|
|
219
|
+
{error ? (
|
|
220
|
+
<div className="p-3 mt-3 border border-red-200 dark:border-red-900/30 rounded-sm text-red-600 dark:text-red-400 text-xs">
|
|
221
|
+
{error}
|
|
222
|
+
</div>
|
|
223
|
+
) : loading && !orderBookData ? (
|
|
224
|
+
<div className="flex items-center justify-center h-40 mt-3">
|
|
225
|
+
<RefreshCw size={24} className="text-n1-ww-main n1-animate-spin" />
|
|
226
|
+
</div>
|
|
227
|
+
) : !marketSymbol ? (
|
|
228
|
+
<div className="p-3 mt-3 border border-n1-ww-gray-200 dark:border-n1-ww-gray-800 rounded-sm text-n1-ww-gray-500 dark:text-n1-ww-gray-400 text-xs">
|
|
229
|
+
Select a market to view orderbook
|
|
230
|
+
</div>
|
|
231
|
+
) : (
|
|
232
|
+
<div className="mt-3">
|
|
233
|
+
<div className="flex flex-col">
|
|
234
|
+
<OrderBookTable
|
|
235
|
+
data={aggregatedData}
|
|
236
|
+
loading={loading}
|
|
237
|
+
maxSize={maxSize}
|
|
238
|
+
/>
|
|
239
|
+
|
|
240
|
+
<OrderBookDepthVisualizer data={aggregatedData} maxSize={maxSize} />
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
)}
|
|
244
|
+
</div>
|
|
245
|
+
);
|
|
208
246
|
}
|
|
247
|
+
*/
|
|
209
248
|
//# sourceMappingURL=OrderBook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OrderBook.js","sourceRoot":"","sources":["../../../../../src/Modal/Sidebar/NordTradingView/OrderBook/OrderBook.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useState } from 'react';\nimport { useN1WalletContext } from '../../../../Provider/hooks';\nimport OrderBookHeader from './OrderBookHeader';\nimport OrderBookTable from './OrderBookTable';\n// Create a simple implementation for the missing OrderBookDepthVisualizer component\nimport { RefreshCw } from 'lucide-react';\n\n// Simple implementation of OrderBookDepthVisualizer\nconst OrderBookDepthVisualizer = ({\n data,\n maxSize,\n}: {\n data: {\n bids: Array<[number, number]>;\n asks: Array<[number, number]>;\n timestamp: number;\n } | null;\n maxSize: number;\n}) => {\n if (!data || data.bids.length === 0 || data.asks.length === 0) {\n return null;\n }\n\n return (\n <div className=\"mt-3\">\n <h3 className=\"text-xs font-medium text-n1-ww-gray-900 dark:text-n1-ww-gray-100 mb-2\">\n Depth Chart\n </h3>\n <div className=\"w-full h-24 border border-n1-ww-gray-200 dark:border-n1-ww-gray-800 rounded-sm overflow-hidden flex items-center justify-center\">\n <div className=\"relative w-full h-full\">\n {/* Simple visualization with gradient backgrounds */}\n <div className=\"absolute inset-0 flex\">\n <div className=\"w-1/2 bg-gradient-to-r from-green-500/10 to-green-500/5\"></div>\n <div className=\"w-1/2 bg-gradient-to-l from-red-500/10 to-red-500/5\"></div>\n </div>\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"h-full w-px bg-n1-ww-gray-300 dark:bg-n1-ww-gray-600\"></div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\ninterface OrderBookProps {\n marketSymbol: string | null;\n}\n\ninterface OrderBookData {\n bids: Array<[number, number]>; // [price, size]\n asks: Array<[number, number]>; // [price, size]\n timestamp: number;\n}\n\n// Define the OrderbookEntry interface to match the API response\ninterface OrderbookEntry {\n price: number;\n size: number;\n}\n\nexport default function OrderBook({ marketSymbol }: OrderBookProps) {\n const { nord } = useN1WalletContext();\n const [orderBookData, setOrderBookData] = useState<OrderBookData | null>(\n null\n );\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [aggregationLevel, setAggregationLevel] = useState<number>(0.01);\n\n // Fetch orderbook data when market changes\n useEffect(() => {\n if (!marketSymbol || !nord) return;\n\n let subscription: any = null;\n\n const fetchOrderBook = async () => {\n setLoading(true);\n setError(null);\n\n try {\n // Initial fetch\n const orderbook = await nord.getOrderbook({ symbol: marketSymbol });\n\n // The API now returns bids and asks directly as arrays of [price, size] pairs\n // instead of OrderbookEntry objects\n const bids: Array<[number, number]> = Array.isArray(orderbook.bids[0])\n ? (orderbook.bids as unknown as Array<[number, number]>)\n : orderbook.bids.map((entry: OrderbookEntry) => [\n entry.price,\n entry.size,\n ]);\n\n const asks: Array<[number, number]> = Array.isArray(orderbook.asks[0])\n ? (orderbook.asks as unknown as Array<[number, number]>)\n : orderbook.asks.map((entry: OrderbookEntry) => [\n entry.price,\n entry.size,\n ]);\n\n setOrderBookData({\n bids,\n asks,\n timestamp: Date.now(),\n });\n\n // Subscribe to real-time updates\n subscription = nord.subscribeOrderbook(marketSymbol);\n subscription.on('update', (update: any) => {\n setOrderBookData((prev) => {\n if (!prev) return update;\n\n // Convert OrderbookEntry[] to [number, number][] if needed\n const updatedBids = update.bids\n ? update.bids.map((entry: OrderbookEntry) => [\n entry.price,\n entry.size,\n ])\n : prev.bids;\n\n const updatedAsks = update.asks\n ? update.asks.map((entry: OrderbookEntry) => [\n entry.price,\n entry.size,\n ])\n : prev.asks;\n\n return {\n bids: updatedBids,\n asks: updatedAsks,\n timestamp: Date.now(),\n };\n });\n });\n } catch (err) {\n console.error('Error fetching orderbook:', err);\n setError('Failed to load orderbook data');\n } finally {\n setLoading(false);\n }\n };\n\n fetchOrderBook();\n\n // Cleanup subscription on unmount or market change\n return () => {\n if (subscription) {\n subscription.close();\n }\n };\n }, [marketSymbol, nord]);\n\n // Aggregate orderbook data based on aggregation level\n const aggregateOrderBook = (\n data: OrderBookData | null,\n level: number\n ): OrderBookData | null => {\n if (!data) return null;\n\n const aggregatedBids: { [key: number]: number } = {};\n const aggregatedAsks: { [key: number]: number } = {};\n\n // Aggregate bids\n data.bids.forEach(([price, size]) => {\n const aggregatedPrice = Math.floor(price / level) * level;\n aggregatedBids[aggregatedPrice] =\n (aggregatedBids[aggregatedPrice] || 0) + size;\n });\n\n // Aggregate asks\n data.asks.forEach(([price, size]) => {\n const aggregatedPrice = Math.ceil(price / level) * level;\n aggregatedAsks[aggregatedPrice] =\n (aggregatedAsks[aggregatedPrice] || 0) + size;\n });\n\n // Convert back to arrays and sort\n const bids = Object.entries(aggregatedBids)\n .map(([price, size]) => [parseFloat(price), size])\n .sort((a, b) => b[0] - a[0]) as Array<[number, number]>;\n\n const asks = Object.entries(aggregatedAsks)\n .map(([price, size]) => [parseFloat(price), size])\n .sort((a, b) => a[0] - b[0]) as Array<[number, number]>;\n\n return {\n bids,\n asks,\n timestamp: data.timestamp,\n };\n };\n\n const aggregatedData = aggregateOrderBook(orderBookData, aggregationLevel);\n\n // Calculate max size for depth visualization\n const calculateMaxSize = (data: OrderBookData | null): number => {\n if (!data) return 0;\n\n const bidSizes = data.bids.map(([_, size]) => size);\n const askSizes = data.asks.map(([_, size]) => size);\n const allSizes = [...bidSizes, ...askSizes];\n\n return Math.max(...allSizes, 0);\n };\n\n const maxSize = calculateMaxSize(aggregatedData);\n\n return (\n <div className=\"p-4\">\n <OrderBookHeader\n marketSymbol={marketSymbol}\n aggregationLevel={aggregationLevel}\n onAggregationChange={setAggregationLevel}\n />\n\n {error ? (\n <div className=\"p-3 mt-3 border border-red-200 dark:border-red-900/30 rounded-sm text-red-600 dark:text-red-400 text-xs\">\n {error}\n </div>\n ) : loading && !orderBookData ? (\n <div className=\"flex items-center justify-center h-40 mt-3\">\n <RefreshCw size={24} className=\"text-n1-ww-main n1-animate-spin\" />\n </div>\n ) : !marketSymbol ? (\n <div className=\"p-3 mt-3 border border-n1-ww-gray-200 dark:border-n1-ww-gray-800 rounded-sm text-n1-ww-gray-500 dark:text-n1-ww-gray-400 text-xs\">\n Select a market to view orderbook\n </div>\n ) : (\n <div className=\"mt-3\">\n <div className=\"flex flex-col\">\n <OrderBookTable\n data={aggregatedData}\n loading={loading}\n maxSize={maxSize}\n />\n\n <OrderBookDepthVisualizer data={aggregatedData} maxSize={maxSize} />\n </div>\n </div>\n )}\n </div>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"OrderBook.js","sourceRoot":"","sources":["../../../../../src/Modal/Sidebar/NordTradingView/OrderBook/OrderBook.tsx"],"names":[],"mappings":";AAAA,sEAAsE;AACtE,0DAA0D;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmPE","sourcesContent":["// DEPRECATED: This entire component has been deprecated due to errors\n// All code below has been commented out to prevent issues\n\n/*\nimport { useEffect, useState } from 'react';\nimport { useN1WalletContext } from '../../../../Provider/hooks';\nimport OrderBookHeader from './OrderBookHeader';\nimport OrderBookTable from './OrderBookTable';\n// Create a simple implementation for the missing OrderBookDepthVisualizer component\nimport { RefreshCw } from 'lucide-react';\n\n// Simple implementation of OrderBookDepthVisualizer\nconst OrderBookDepthVisualizer = ({\n data,\n maxSize,\n}: {\n data: {\n bids: Array<[number, number]>;\n asks: Array<[number, number]>;\n timestamp: number;\n } | null;\n maxSize: number;\n}) => {\n if (!data || data.bids.length === 0 || data.asks.length === 0) {\n return null;\n }\n\n return (\n <div className=\"mt-3\">\n <h3 className=\"text-xs font-medium text-n1-ww-gray-900 dark:text-n1-ww-gray-100 mb-2\">\n Depth Chart\n </h3>\n <div className=\"w-full h-24 border border-n1-ww-gray-200 dark:border-n1-ww-gray-800 rounded-sm overflow-hidden flex items-center justify-center\">\n <div className=\"relative w-full h-full\">\n <div className=\"absolute inset-0 flex\">\n <div className=\"w-1/2 bg-gradient-to-r from-green-500/10 to-green-500/5\"></div>\n <div className=\"w-1/2 bg-gradient-to-l from-red-500/10 to-red-500/5\"></div>\n </div>\n <div className=\"absolute inset-0 flex items-center justify-center\">\n <div className=\"h-full w-px bg-n1-ww-gray-300 dark:bg-n1-ww-gray-600\"></div>\n </div>\n </div>\n </div>\n </div>\n );\n};\n\ninterface OrderBookProps {\n marketSymbol: string | null;\n marketId?: number;\n}\n\ninterface OrderBookData {\n bids: Array<[number, number]>; // [price, size]\n asks: Array<[number, number]>; // [price, size]\n timestamp: number;\n}\n\n// Define the OrderbookEntry interface to match the API response\ninterface OrderbookEntry {\n price: number;\n size: number;\n}\n\nexport default function OrderBook({ marketSymbol, marketId }: OrderBookProps) {\n const { nord } = useN1WalletContext();\n const [orderBookData, setOrderBookData] = useState<OrderBookData | null>(\n null\n );\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [aggregationLevel, setAggregationLevel] = useState<number>(0.01);\n\n // Fetch orderbook data when market changes\n useEffect(() => {\n if (!marketSymbol || !nord) return;\n\n let subscription: any = null;\n\n const fetchOrderBook = async () => {\n setLoading(true);\n setError(null);\n\n try {\n // Initial fetch\n const orderbook = await nord.getOrderbook({ symbol: marketSymbol });\n\n // The API now returns bids and asks directly as arrays of [price, size] pairs\n // instead of OrderbookEntry objects\n const bids: Array<[number, number]> = Array.isArray(orderbook.bids[0])\n ? (orderbook.bids as unknown as Array<[number, number]>)\n : orderbook.bids.map((entry: OrderbookEntry) => [\n entry.price,\n entry.size,\n ]);\n\n const asks: Array<[number, number]> = Array.isArray(orderbook.asks[0])\n ? (orderbook.asks as unknown as Array<[number, number]>)\n : orderbook.asks.map((entry: OrderbookEntry) => [\n entry.price,\n entry.size,\n ]);\n\n setOrderBookData({\n bids,\n asks,\n timestamp: Date.now(),\n });\n\n // Subscribe to real-time updates\n subscription = nord.subscribeOrderbook(marketSymbol);\n subscription.on('update', (update: any) => {\n setOrderBookData((prev) => {\n if (!prev) return update;\n\n // Convert OrderbookEntry[] to [number, number][] if needed\n const updatedBids = update.bids\n ? update.bids.map((entry: OrderbookEntry) => [\n entry.price,\n entry.size,\n ])\n : prev.bids;\n\n const updatedAsks = update.asks\n ? update.asks.map((entry: OrderbookEntry) => [\n entry.price,\n entry.size,\n ])\n : prev.asks;\n\n return {\n bids: updatedBids,\n asks: updatedAsks,\n timestamp: Date.now(),\n };\n });\n });\n } catch (err) {\n console.error('Error fetching orderbook:', err);\n setError('Failed to load orderbook data');\n } finally {\n setLoading(false);\n }\n };\n\n fetchOrderBook();\n\n // Cleanup subscription on unmount or market change\n return () => {\n if (subscription) {\n subscription.close();\n }\n };\n }, [marketSymbol, nord]);\n\n // Aggregate orderbook data based on aggregation level\n const aggregateOrderBook = (\n data: OrderBookData | null,\n level: number\n ): OrderBookData | null => {\n if (!data) return null;\n\n const aggregatedBids: { [key: number]: number } = {};\n const aggregatedAsks: { [key: number]: number } = {};\n\n // Aggregate bids\n data.bids.forEach(([price, size]) => {\n const aggregatedPrice = Math.floor(price / level) * level;\n aggregatedBids[aggregatedPrice] =\n (aggregatedBids[aggregatedPrice] || 0) + size;\n });\n\n // Aggregate asks\n data.asks.forEach(([price, size]) => {\n const aggregatedPrice = Math.ceil(price / level) * level;\n aggregatedAsks[aggregatedPrice] =\n (aggregatedAsks[aggregatedPrice] || 0) + size;\n });\n\n // Convert back to arrays and sort\n const bids = Object.entries(aggregatedBids)\n .map(([price, size]) => [parseFloat(price), size])\n .sort((a, b) => b[0] - a[0]) as Array<[number, number]>;\n\n const asks = Object.entries(aggregatedAsks)\n .map(([price, size]) => [parseFloat(price), size])\n .sort((a, b) => a[0] - b[0]) as Array<[number, number]>;\n\n return {\n bids,\n asks,\n timestamp: data.timestamp,\n };\n };\n\n const aggregatedData = aggregateOrderBook(orderBookData, aggregationLevel);\n\n // Calculate max size for depth visualization\n const calculateMaxSize = (data: OrderBookData | null): number => {\n if (!data) return 0;\n\n const bidSizes = data.bids.map(([_, size]) => size);\n const askSizes = data.asks.map(([_, size]) => size);\n const allSizes = [...bidSizes, ...askSizes];\n\n return Math.max(...allSizes, 0);\n };\n\n const maxSize = calculateMaxSize(aggregatedData);\n\n return (\n <div className=\"p-4\">\n <OrderBookHeader\n marketSymbol={marketSymbol}\n aggregationLevel={aggregationLevel}\n onAggregationChange={setAggregationLevel}\n />\n\n {error ? (\n <div className=\"p-3 mt-3 border border-red-200 dark:border-red-900/30 rounded-sm text-red-600 dark:text-red-400 text-xs\">\n {error}\n </div>\n ) : loading && !orderBookData ? (\n <div className=\"flex items-center justify-center h-40 mt-3\">\n <RefreshCw size={24} className=\"text-n1-ww-main n1-animate-spin\" />\n </div>\n ) : !marketSymbol ? (\n <div className=\"p-3 mt-3 border border-n1-ww-gray-200 dark:border-n1-ww-gray-800 rounded-sm text-n1-ww-gray-500 dark:text-n1-ww-gray-400 text-xs\">\n Select a market to view orderbook\n </div>\n ) : (\n <div className=\"mt-3\">\n <div className=\"flex flex-col\">\n <OrderBookTable\n data={aggregatedData}\n loading={loading}\n maxSize={maxSize}\n />\n\n <OrderBookDepthVisualizer data={aggregatedData} maxSize={maxSize} />\n </div>\n </div>\n )}\n </div>\n );\n}\n*/"]}
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated This component is deprecated due to technical issues.
|
|
3
|
+
* Please refer to DEPRECATED.md for more information.
|
|
4
|
+
*/
|
|
1
5
|
interface TradeFormProps {
|
|
2
6
|
marketSymbol: string | null;
|
|
7
|
+
marketId?: number;
|
|
3
8
|
}
|
|
4
9
|
export type OrderSide = 'BUY' | 'SELL';
|
|
5
10
|
export type OrderType = 'LIMIT' | 'MARKET';
|
|
6
11
|
export type FillMode = 'GTC' | 'POST_ONLY' | 'IOC' | 'FOK';
|
|
7
|
-
export default function TradeForm({ marketSymbol }: TradeFormProps): JSX.Element;
|
|
12
|
+
export default function TradeForm({ marketSymbol, marketId }: TradeFormProps): JSX.Element;
|
|
8
13
|
export {};
|
|
@@ -35,6 +35,10 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
37
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
38
|
+
/**
|
|
39
|
+
* @deprecated This component is deprecated due to technical issues.
|
|
40
|
+
* Please refer to DEPRECATED.md for more information.
|
|
41
|
+
*/
|
|
38
42
|
import { useState, useEffect } from 'react';
|
|
39
43
|
import { useN1WalletContext } from '../../../../Provider/hooks';
|
|
40
44
|
import BuySellTabs from './BuySellTabs';
|
|
@@ -70,7 +74,7 @@ var isMarketOrder = function (mode) {
|
|
|
70
74
|
};
|
|
71
75
|
export default function TradeForm(_a) {
|
|
72
76
|
var _this = this;
|
|
73
|
-
var marketSymbol = _a.marketSymbol;
|
|
77
|
+
var marketSymbol = _a.marketSymbol, marketId = _a.marketId;
|
|
74
78
|
var _b = useN1WalletContext(), nord = _b.nord, nordUser = _b.nordUser;
|
|
75
79
|
// Form state
|
|
76
80
|
var _c = useState('BUY'), side = _c[0], setSide = _c[1];
|
|
@@ -96,7 +100,7 @@ export default function TradeForm(_a) {
|
|
|
96
100
|
}, []);
|
|
97
101
|
// Fetch market info and user account ID when market changes
|
|
98
102
|
useEffect(function () {
|
|
99
|
-
if (!marketSymbol || !nord)
|
|
103
|
+
if (!marketSymbol || !nord || marketId === undefined)
|
|
100
104
|
return;
|
|
101
105
|
var fetchMarketInfo = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
102
106
|
var stats, selectedMarket, err_1;
|
|
@@ -104,10 +108,10 @@ export default function TradeForm(_a) {
|
|
|
104
108
|
switch (_a.label) {
|
|
105
109
|
case 0:
|
|
106
110
|
_a.trys.push([0, 2, , 3]);
|
|
107
|
-
return [4 /*yield*/, nord.getMarketStats()];
|
|
111
|
+
return [4 /*yield*/, nord.getMarketStats({ marketId: marketId })];
|
|
108
112
|
case 1:
|
|
109
113
|
stats = _a.sent();
|
|
110
|
-
selectedMarket = stats
|
|
114
|
+
selectedMarket = stats;
|
|
111
115
|
setMarketInfo(selectedMarket || null);
|
|
112
116
|
// Set default price to current market price
|
|
113
117
|
if (selectedMarket === null || selectedMarket === void 0 ? void 0 : selectedMarket.lastPrice) {
|
|
@@ -167,7 +171,7 @@ export default function TradeForm(_a) {
|
|
|
167
171
|
}, [price, amount, fillMode]);
|
|
168
172
|
// Handle order submission
|
|
169
173
|
var handleSubmit = function (e) { return __awaiter(_this, void 0, void 0, function () {
|
|
170
|
-
var market,
|
|
174
|
+
var market, marketId_1, orderParams, orderId, err_3;
|
|
171
175
|
var _a;
|
|
172
176
|
return __generator(this, function (_b) {
|
|
173
177
|
switch (_b.label) {
|
|
@@ -192,11 +196,11 @@ export default function TradeForm(_a) {
|
|
|
192
196
|
case 1:
|
|
193
197
|
_b.trys.push([1, 3, 4, 5]);
|
|
194
198
|
market = (_a = nord === null || nord === void 0 ? void 0 : nord.markets) === null || _a === void 0 ? void 0 : _a.find(function (m) { return m.symbol === marketSymbol; });
|
|
195
|
-
|
|
199
|
+
marketId_1 = market
|
|
196
200
|
? market.id || market.marketId || 0
|
|
197
201
|
: 0;
|
|
198
202
|
orderParams = {
|
|
199
|
-
marketId:
|
|
203
|
+
marketId: marketId_1,
|
|
200
204
|
side: mapSide(side),
|
|
201
205
|
fillMode: mapFillMode(fillMode),
|
|
202
206
|
isReduceOnly: isReduceOnly,
|