@n1xyz/nord-ts 0.0.1 → 0.0.4
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/.eslintrc.js +11 -0
- package/README.md +148 -65
- package/dist/bridge/NordUser.d.ts +78 -0
- package/dist/bridge/NordUser.js +196 -0
- package/dist/bridge/client.d.ts +150 -0
- package/dist/bridge/client.js +394 -0
- package/dist/bridge/const.d.ts +23 -0
- package/dist/bridge/const.js +47 -0
- package/dist/bridge/index.d.ts +5 -0
- package/dist/bridge/index.js +23 -0
- package/dist/bridge/types.d.ts +118 -0
- package/dist/bridge/types.js +16 -0
- package/dist/bridge/utils.d.ts +64 -0
- package/dist/bridge/utils.js +131 -0
- package/dist/client.d.ts +70 -0
- package/dist/client.js +129 -0
- package/dist/const.d.ts +2 -5
- package/dist/const.js +18 -22
- package/dist/constants/endpoints.d.ts +65 -0
- package/dist/constants/endpoints.js +68 -0
- package/dist/gen/common.d.ts +6 -1
- package/dist/gen/common.js +19 -9
- package/dist/gen/nord.d.ts +75 -17
- package/dist/gen/nord.js +987 -423
- package/dist/idl/bridge.d.ts +2 -0
- package/dist/idl/bridge.js +703 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.js +18 -2
- package/dist/models/account.d.ts +58 -0
- package/dist/models/account.js +6 -0
- package/dist/models/index.d.ts +8 -0
- package/dist/models/index.js +28 -0
- package/dist/models/market.d.ts +137 -0
- package/dist/models/market.js +6 -0
- package/dist/models/order.d.ts +211 -0
- package/dist/models/order.js +6 -0
- package/dist/models/token.d.ts +50 -0
- package/dist/models/token.js +6 -0
- package/dist/nord/Nord.d.ts +222 -49
- package/dist/nord/Nord.js +290 -278
- package/dist/nord/NordError.d.ts +23 -0
- package/dist/nord/NordError.js +48 -0
- package/dist/nord/NordImpl.d.ts +6 -2
- package/dist/nord/NordImpl.js +21 -1
- package/dist/nord/NordUser.d.ts +208 -42
- package/dist/nord/NordUser.js +389 -157
- package/dist/nord/Subscriber.d.ts +37 -0
- package/dist/nord/Subscriber.js +29 -0
- package/dist/nord/api/actions.d.ts +101 -0
- package/dist/nord/api/actions.js +250 -0
- package/dist/nord/api/core.d.ts +49 -0
- package/dist/nord/api/core.js +121 -0
- package/dist/nord/api/index.d.ts +1 -0
- package/dist/nord/api/index.js +17 -0
- package/dist/nord/api/market.d.ts +36 -0
- package/dist/nord/api/market.js +98 -0
- package/dist/nord/api/metrics.d.ts +67 -0
- package/dist/nord/api/metrics.js +132 -0
- package/dist/nord/api/orderFunctions.d.ts +168 -0
- package/dist/nord/api/orderFunctions.js +133 -0
- package/dist/nord/api/queries.d.ts +81 -0
- package/dist/nord/api/queries.js +187 -0
- package/dist/nord/client/Nord.d.ts +335 -0
- package/dist/nord/client/Nord.js +532 -0
- package/dist/nord/client/NordUser.d.ts +320 -0
- package/dist/nord/client/NordUser.js +701 -0
- package/dist/nord/core.d.ts +48 -0
- package/dist/nord/core.js +97 -0
- package/dist/nord/index.d.ts +9 -2
- package/dist/nord/index.js +30 -6
- package/dist/nord/market.d.ts +36 -0
- package/dist/nord/market.js +90 -0
- package/dist/nord/metrics.d.ts +67 -0
- package/dist/nord/metrics.js +124 -0
- package/dist/nord/models/Subscriber.d.ts +37 -0
- package/dist/nord/models/Subscriber.js +29 -0
- package/dist/nord/queries.d.ts +81 -0
- package/dist/nord/queries.js +181 -0
- package/dist/nord/types.d.ts +88 -0
- package/dist/nord/types.js +2 -0
- package/dist/nord/utils/NordError.d.ts +35 -0
- package/dist/nord/utils/NordError.js +46 -0
- package/dist/nord/websocket.d.ts +49 -0
- package/dist/nord/websocket.js +107 -0
- package/dist/operations/account.d.ts +58 -0
- package/dist/operations/account.js +112 -0
- package/dist/operations/market.d.ts +65 -0
- package/dist/operations/market.js +131 -0
- package/dist/operations/orders.d.ts +57 -0
- package/dist/operations/orders.js +129 -0
- package/dist/solana/NordUser.d.ts +78 -0
- package/dist/solana/NordUser.js +196 -0
- package/dist/solana/client.d.ts +139 -0
- package/dist/solana/client.js +360 -0
- package/dist/solana/const.d.ts +23 -0
- package/dist/solana/const.js +47 -0
- package/dist/solana/index.d.ts +5 -0
- package/dist/solana/index.js +23 -0
- package/dist/solana/types.d.ts +118 -0
- package/dist/solana/types.js +16 -0
- package/dist/solana/utils.d.ts +64 -0
- package/dist/solana/utils.js +131 -0
- package/dist/types/api.d.ts +152 -0
- package/dist/types/api.js +6 -0
- package/dist/types/config.d.ts +34 -0
- package/dist/types/config.js +6 -0
- package/dist/types.d.ts +144 -87
- package/dist/types.js +13 -2
- package/dist/utils/errors.d.ts +96 -0
- package/dist/utils/errors.js +132 -0
- package/dist/utils/http.d.ts +35 -0
- package/dist/utils/http.js +105 -0
- package/dist/utils.d.ts +14 -5
- package/dist/utils.js +26 -7
- package/dist/websocket/NordWebSocketClient.d.ts +71 -0
- package/dist/websocket/NordWebSocketClient.js +343 -0
- package/dist/websocket/client.d.ts +93 -0
- package/dist/websocket/client.js +222 -0
- package/dist/websocket/events.d.ts +19 -0
- package/dist/websocket/events.js +2 -0
- package/dist/websocket/index.d.ts +2 -0
- package/dist/websocket/index.js +5 -0
- package/dist/websocket.d.ts +55 -0
- package/dist/websocket.js +211 -0
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/Nord.html +2 -15
- package/docs/classes/NordUser.html +4 -4
- package/docs/enums/FillMode.html +2 -2
- package/docs/enums/KeyType.html +2 -2
- package/docs/enums/PeakTpsPeriodUnit.html +2 -2
- package/docs/enums/Side.html +2 -2
- package/docs/functions/assert.html +1 -1
- package/docs/functions/bigIntToProtoU128.html +1 -1
- package/docs/functions/checkPubKeyLength.html +1 -1
- package/docs/functions/checkedFetch.html +1 -1
- package/docs/functions/decodeLengthDelimited.html +1 -1
- package/docs/functions/encodeLengthDelimited.html +1 -1
- package/docs/functions/fillModeToProtoFillMode.html +1 -1
- package/docs/functions/findMarket.html +1 -1
- package/docs/functions/findToken.html +1 -1
- package/docs/functions/makeWalletSignFn.html +1 -1
- package/docs/functions/optExpect.html +1 -1
- package/docs/functions/optMap.html +1 -1
- package/docs/functions/optUnwrap.html +1 -1
- package/docs/functions/panic.html +1 -1
- package/docs/functions/signAction.html +1 -1
- package/docs/functions/toScaledU128.html +1 -1
- package/docs/functions/toScaledU64.html +1 -1
- package/docs/interfaces/Account.html +2 -2
- package/docs/interfaces/ActionInfo.html +2 -2
- package/docs/interfaces/ActionQuery.html +2 -2
- package/docs/interfaces/ActionResponse.html +2 -2
- package/docs/interfaces/ActionsExtendedInfo.html +2 -2
- package/docs/interfaces/ActionsQuery.html +2 -2
- package/docs/interfaces/ActionsResponse.html +2 -2
- package/docs/interfaces/AggregateMetrics.html +2 -2
- package/docs/interfaces/BlockQuery.html +2 -2
- package/docs/interfaces/BlockResponse.html +2 -2
- package/docs/interfaces/BlockSummary.html +2 -2
- package/docs/interfaces/BlockSummaryResponse.html +2 -2
- package/docs/interfaces/DeltaEvent.html +2 -2
- package/docs/interfaces/ERC20TokenInfo.html +2 -2
- package/docs/interfaces/Info.html +2 -2
- package/docs/interfaces/Market.html +2 -2
- package/docs/interfaces/MarketStats.html +2 -2
- package/docs/interfaces/MarketsStatsResponse.html +2 -2
- package/docs/interfaces/NordConfig.html +2 -2
- package/docs/interfaces/Order.html +2 -2
- package/docs/interfaces/OrderInfo.html +2 -2
- package/docs/interfaces/PerpMarketStats.html +2 -2
- package/docs/interfaces/RollmanActionExtendedInfo.html +2 -2
- package/docs/interfaces/RollmanActionInfo.html +2 -2
- package/docs/interfaces/RollmanActionResponse.html +2 -2
- package/docs/interfaces/RollmanActionsResponse.html +2 -2
- package/docs/interfaces/RollmanBlockResponse.html +2 -2
- package/docs/interfaces/SubscriberConfig.html +2 -2
- package/docs/interfaces/Token.html +2 -2
- package/docs/interfaces/Trade.html +2 -2
- package/docs/interfaces/Trades.html +2 -2
- package/docs/modules.html +0 -7
- package/docs/types/BigIntValue.html +1 -1
- package/docs/variables/DEBUG_KEYS.html +1 -1
- package/docs/variables/DEFAULT_FUNDING_AMOUNTS.html +1 -1
- package/docs/variables/DEV_CONTRACT_ADDRESS.html +1 -1
- package/docs/variables/DEV_TOKEN_INFOS.html +1 -1
- package/docs/variables/DEV_URL.html +1 -1
- package/docs/variables/ERC20_ABI.html +1 -1
- package/docs/variables/EVM_DEV_URL.html +1 -1
- package/docs/variables/FAUCET_PRIVATE_ADDRESS.html +1 -1
- package/docs/variables/MAX_BUFFER_LEN.html +1 -1
- package/docs/variables/NORD_GETTERS_FACET_ABI.html +1 -1
- package/docs/variables/NORD_RAMP_FACET_ABI.html +1 -1
- package/docs/variables/SESSION_TTL.html +1 -1
- package/docs/variables/WEBSERVER_DEV_URL.html +1 -1
- package/docs/variables/ZERO_DECIMAL.html +1 -1
- package/package.json +10 -12
- package/src/bridge/client.ts +487 -0
- package/src/bridge/const.ts +53 -0
- package/src/bridge/index.ts +7 -0
- package/src/bridge/types.ts +127 -0
- package/src/bridge/utils.ts +140 -0
- package/src/const.ts +20 -25
- package/src/gen/common.ts +27 -10
- package/src/gen/nord.ts +1044 -483
- package/src/idl/bridge.ts +702 -0
- package/src/index.ts +24 -5
- package/src/nord/{actions.ts → api/actions.ts} +33 -37
- package/src/nord/api/core.ts +130 -0
- package/src/nord/api/market.ts +125 -0
- package/src/nord/api/metrics.ts +154 -0
- package/src/nord/api/queries.ts +236 -0
- package/src/nord/client/Nord.ts +652 -0
- package/src/nord/client/NordUser.ts +1105 -0
- package/src/nord/index.ts +16 -2
- package/src/nord/models/Subscriber.ts +57 -0
- package/src/nord/utils/NordError.ts +72 -0
- package/src/types.ts +170 -99
- package/src/utils.ts +40 -19
- package/src/websocket/NordWebSocketClient.ts +432 -0
- package/src/websocket/events.ts +31 -0
- package/src/websocket/index.ts +2 -0
- package/tests/utils.spec.ts +24 -24
- package/docs/classes/Subscriber.html +0 -6
- package/docs/functions/createWebSocketSubscription.html +0 -12
- package/docs/interfaces/OrderbookOrder.html +0 -6
- package/docs/interfaces/OrderbookResponse.html +0 -10
- package/docs/interfaces/TradeInfo.html +0 -20
- package/docs/interfaces/TradesQueryParams.html +0 -10
- package/docs/interfaces/TradesResponse.html +0 -12
- package/src/abis/ERC20_ABI.ts +0 -310
- package/src/abis/NORD_GETTERS_FACET_ABI.ts +0 -192
- package/src/abis/NORD_RAMP_FACET_ABI.ts +0 -141
- package/src/abis/index.ts +0 -3
- package/src/nord/Nord.ts +0 -504
- package/src/nord/NordImpl.ts +0 -8
- package/src/nord/NordUser.ts +0 -469
package/src/nord/Nord.ts
DELETED
|
@@ -1,504 +0,0 @@
|
|
|
1
|
-
import { ethers } from "ethers";
|
|
2
|
-
import WebSocket from "ws";
|
|
3
|
-
import {
|
|
4
|
-
ActionInfo,
|
|
5
|
-
ActionsExtendedInfo,
|
|
6
|
-
ActionQuery,
|
|
7
|
-
ActionResponse,
|
|
8
|
-
ActionsResponse,
|
|
9
|
-
AggregateMetrics,
|
|
10
|
-
BlockQuery,
|
|
11
|
-
BlockResponse,
|
|
12
|
-
BlockSummaryResponse,
|
|
13
|
-
type DeltaEvent,
|
|
14
|
-
ERC20TokenInfo,
|
|
15
|
-
type Info,
|
|
16
|
-
type Market,
|
|
17
|
-
NordConfig,
|
|
18
|
-
PeakTpsPeriodUnit,
|
|
19
|
-
RollmanActionResponse,
|
|
20
|
-
RollmanActionsResponse,
|
|
21
|
-
RollmanBlockResponse,
|
|
22
|
-
MarketsStatsResponse,
|
|
23
|
-
type SubscriberConfig,
|
|
24
|
-
type Token,
|
|
25
|
-
type Trades,
|
|
26
|
-
type Account,
|
|
27
|
-
type OrderbookResponse,
|
|
28
|
-
type TradesResponse,
|
|
29
|
-
type TradesQueryParams,
|
|
30
|
-
} from "../types";
|
|
31
|
-
import { checkedFetch, decodeLengthDelimited, MAX_BUFFER_LEN } from "../utils";
|
|
32
|
-
import {
|
|
33
|
-
DEV_TOKEN_INFOS,
|
|
34
|
-
EVM_DEV_URL,
|
|
35
|
-
WEBSERVER_DEV_URL,
|
|
36
|
-
DEV_CONTRACT_ADDRESS,
|
|
37
|
-
} from "../const";
|
|
38
|
-
import { ERC20_ABI, NORD_RAMP_FACET_ABI } from "../abis";
|
|
39
|
-
import * as proto from "../gen/nord";
|
|
40
|
-
import { NordImpl } from "./NordImpl";
|
|
41
|
-
|
|
42
|
-
export async function depositOnlyTx(
|
|
43
|
-
privateAddress: string,
|
|
44
|
-
publicKey: Uint8Array,
|
|
45
|
-
amount: number,
|
|
46
|
-
precision: number,
|
|
47
|
-
contractAddress: string,
|
|
48
|
-
): Promise<string> {
|
|
49
|
-
const provider = new ethers.JsonRpcProvider(process.env.SECRET_FAUCET_RPC);
|
|
50
|
-
const wallet = new ethers.Wallet(privateAddress, provider);
|
|
51
|
-
const nordContract = new ethers.Contract(
|
|
52
|
-
contractAddress,
|
|
53
|
-
NORD_RAMP_FACET_ABI,
|
|
54
|
-
wallet,
|
|
55
|
-
);
|
|
56
|
-
const depositTx = await nordContract.depositUnchecked(
|
|
57
|
-
publicKey,
|
|
58
|
-
BigInt(0),
|
|
59
|
-
ethers.parseUnits(amount.toString(), precision),
|
|
60
|
-
{
|
|
61
|
-
gasLimit: 1_000_000,
|
|
62
|
-
maxFeePerGas: ethers.parseUnits("100", "gwei"),
|
|
63
|
-
maxPriorityFeePerGas: ethers.parseUnits("0.01", "gwei"),
|
|
64
|
-
},
|
|
65
|
-
);
|
|
66
|
-
return depositTx.hash;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export async function depositOnlyTxRaw(
|
|
70
|
-
privateAddress: string,
|
|
71
|
-
publicKey: Uint8Array,
|
|
72
|
-
amount: number,
|
|
73
|
-
precision: number,
|
|
74
|
-
contractAddress: string,
|
|
75
|
-
): Promise<string> {
|
|
76
|
-
const provider = new ethers.JsonRpcProvider(process.env.SECRET_FAUCET_RPC);
|
|
77
|
-
const wallet = new ethers.Wallet(privateAddress, provider);
|
|
78
|
-
const nordContract = new ethers.Contract(
|
|
79
|
-
contractAddress,
|
|
80
|
-
NORD_RAMP_FACET_ABI,
|
|
81
|
-
wallet,
|
|
82
|
-
);
|
|
83
|
-
const depositTx = await nordContract.depositUnchecked.populateTransaction(
|
|
84
|
-
publicKey,
|
|
85
|
-
BigInt(0),
|
|
86
|
-
ethers.parseUnits(amount.toString(), precision),
|
|
87
|
-
{
|
|
88
|
-
maxFeePerGas: ethers.parseUnits("0.0003", "gwei"),
|
|
89
|
-
maxPriorityFeePerGas: ethers.parseUnits("0.0003", "gwei"),
|
|
90
|
-
},
|
|
91
|
-
);
|
|
92
|
-
return JSON.stringify(depositTx);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function makeNordImpl(nord: Nord): NordImpl {
|
|
96
|
-
return {
|
|
97
|
-
getTimestamp: (): Promise<bigint> =>
|
|
98
|
-
nord.getTimestamp().then((x) => x + 1n),
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export class Nord {
|
|
103
|
-
impl: NordImpl;
|
|
104
|
-
evmUrl: string;
|
|
105
|
-
webServerUrl: string;
|
|
106
|
-
contractAddress: string;
|
|
107
|
-
tokenInfos: ERC20TokenInfo[];
|
|
108
|
-
markets: Market[];
|
|
109
|
-
tokens: Token[];
|
|
110
|
-
|
|
111
|
-
constructor({
|
|
112
|
-
evmUrl,
|
|
113
|
-
webServerUrl,
|
|
114
|
-
tokenInfos,
|
|
115
|
-
contractAddress,
|
|
116
|
-
}: NordConfig) {
|
|
117
|
-
this.impl = makeNordImpl(this);
|
|
118
|
-
this.evmUrl = evmUrl;
|
|
119
|
-
this.webServerUrl = webServerUrl;
|
|
120
|
-
this.tokenInfos = tokenInfos;
|
|
121
|
-
this.contractAddress = contractAddress;
|
|
122
|
-
this.markets = [];
|
|
123
|
-
this.tokens = [];
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
async getTimestamp(): Promise<bigint> {
|
|
127
|
-
const resp = await (
|
|
128
|
-
await checkedFetch(`${this.webServerUrl}/timestamp`, { method: "GET" })
|
|
129
|
-
).json();
|
|
130
|
-
return BigInt(resp);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
async getActionNonce(): Promise<number> {
|
|
134
|
-
const resp = await (
|
|
135
|
-
await checkedFetch(`${this.webServerUrl}/action_nonce`, { method: "GET" })
|
|
136
|
-
).json();
|
|
137
|
-
return resp as number;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async fetchNordInfo() {
|
|
141
|
-
const response = await checkedFetch(`${this.webServerUrl}/info`, {
|
|
142
|
-
method: "GET",
|
|
143
|
-
});
|
|
144
|
-
const info: Info = await response.json();
|
|
145
|
-
this.markets = info.markets;
|
|
146
|
-
this.tokens = info.tokens;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
public static async initNord(nordConfig: NordConfig): Promise<Nord> {
|
|
150
|
-
const nord = new Nord(nordConfig);
|
|
151
|
-
await nord.fetchNordInfo();
|
|
152
|
-
return nord;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
public static async initDevNord(): Promise<Nord> {
|
|
156
|
-
const nord = new Nord({
|
|
157
|
-
evmUrl: EVM_DEV_URL,
|
|
158
|
-
webServerUrl: WEBSERVER_DEV_URL,
|
|
159
|
-
tokenInfos: DEV_TOKEN_INFOS,
|
|
160
|
-
contractAddress: DEV_CONTRACT_ADDRESS,
|
|
161
|
-
});
|
|
162
|
-
await nord.fetchNordInfo();
|
|
163
|
-
return nord;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
public async marketsStats(): Promise<MarketsStatsResponse> {
|
|
167
|
-
const response = await checkedFetch(`${this.webServerUrl}/stats`, {
|
|
168
|
-
method: "GET",
|
|
169
|
-
});
|
|
170
|
-
const stats: MarketsStatsResponse = await response.json();
|
|
171
|
-
return stats;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Query the block info from rollman.
|
|
175
|
-
async queryBlock(query: BlockQuery): Promise<BlockResponse> {
|
|
176
|
-
const rollmanResponse: RollmanBlockResponse =
|
|
177
|
-
await this.blockQueryRollman(query);
|
|
178
|
-
const queryResponse: BlockResponse = {
|
|
179
|
-
block_number: rollmanResponse.block_number,
|
|
180
|
-
actions: [],
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
for (const rollmanAction of rollmanResponse.actions) {
|
|
184
|
-
const blockAction: ActionInfo = {
|
|
185
|
-
action_id: rollmanAction.action_id,
|
|
186
|
-
action: decodeLengthDelimited(
|
|
187
|
-
new Uint8Array(rollmanAction.action_pb),
|
|
188
|
-
proto.Action,
|
|
189
|
-
),
|
|
190
|
-
exec_timestamp: rollmanAction.exec_timestamp,
|
|
191
|
-
};
|
|
192
|
-
queryResponse.actions.push(blockAction);
|
|
193
|
-
}
|
|
194
|
-
return queryResponse;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
// Query the block info from rollman.
|
|
198
|
-
async queryLastNBlocks(): Promise<BlockResponse> {
|
|
199
|
-
const rollmanResponse: RollmanBlockResponse = await this.blockQueryRollman(
|
|
200
|
-
{},
|
|
201
|
-
);
|
|
202
|
-
const queryResponse: BlockResponse = {
|
|
203
|
-
block_number: rollmanResponse.block_number,
|
|
204
|
-
actions: [],
|
|
205
|
-
};
|
|
206
|
-
for (const rollmanAction of rollmanResponse.actions) {
|
|
207
|
-
const blockAction: ActionInfo = {
|
|
208
|
-
action_id: rollmanAction.action_id,
|
|
209
|
-
action: decodeLengthDelimited(rollmanAction.action_pb, proto.Action),
|
|
210
|
-
exec_timestamp: rollmanAction.exec_timestamp,
|
|
211
|
-
};
|
|
212
|
-
queryResponse.actions.push(blockAction);
|
|
213
|
-
}
|
|
214
|
-
return queryResponse;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
// Query the block summary of recent blocks from rollman.
|
|
218
|
-
async queryRecentBlocks(last_n: number): Promise<BlockSummaryResponse> {
|
|
219
|
-
const response: BlockSummaryResponse =
|
|
220
|
-
await this.blockSummaryQueryRollman(last_n);
|
|
221
|
-
return response;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Query the action info from rollman.
|
|
225
|
-
async queryAction(query: ActionQuery): Promise<ActionResponse> {
|
|
226
|
-
const rollmanResponse: RollmanActionResponse =
|
|
227
|
-
await this.actionQueryRollman(query);
|
|
228
|
-
return {
|
|
229
|
-
block_number: rollmanResponse.block_number,
|
|
230
|
-
action: decodeLengthDelimited(rollmanResponse.action_pb, proto.Action),
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Query the recent transactions from rollman.
|
|
235
|
-
async queryRecentActions(last_n: number): Promise<ActionsResponse> {
|
|
236
|
-
const rollmanResponse: RollmanActionsResponse =
|
|
237
|
-
await this.actionsQueryRollman(last_n);
|
|
238
|
-
|
|
239
|
-
const queryResponse: ActionsResponse = {
|
|
240
|
-
actions: [],
|
|
241
|
-
};
|
|
242
|
-
for (const rollmanExtendedAction of rollmanResponse.actions) {
|
|
243
|
-
const extendedActionInfo: ActionsExtendedInfo = {
|
|
244
|
-
block_number: rollmanExtendedAction.block_number,
|
|
245
|
-
action_id: rollmanExtendedAction.action_id,
|
|
246
|
-
action: decodeLengthDelimited(
|
|
247
|
-
rollmanExtendedAction.action_pb,
|
|
248
|
-
proto.Action,
|
|
249
|
-
),
|
|
250
|
-
};
|
|
251
|
-
queryResponse.actions.push(extendedActionInfo);
|
|
252
|
-
}
|
|
253
|
-
return queryResponse;
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Query the aggregate metrics across nord and rollman.
|
|
257
|
-
async aggregateMetrics(
|
|
258
|
-
txPeakTpsPeriod = 1,
|
|
259
|
-
txPeakTpsPeriodUnit: PeakTpsPeriodUnit = PeakTpsPeriodUnit.Day,
|
|
260
|
-
): Promise<AggregateMetrics> {
|
|
261
|
-
// Get the latest block number for L2 blocks.
|
|
262
|
-
const blockQuery: BlockQuery = {};
|
|
263
|
-
const rollmanResponse: RollmanBlockResponse =
|
|
264
|
-
await this.blockQueryRollman(blockQuery);
|
|
265
|
-
|
|
266
|
-
const period = txPeakTpsPeriod.toString() + txPeakTpsPeriodUnit;
|
|
267
|
-
const query = `max_over_time(rate(nord_requests_ok_count[1m])[${period}:1m])`;
|
|
268
|
-
|
|
269
|
-
return {
|
|
270
|
-
blocks_total: rollmanResponse.block_number,
|
|
271
|
-
tx_total: await this.queryPrometheus("nord_requests_ok_count"),
|
|
272
|
-
tx_tps: await this.getCurrentTps(),
|
|
273
|
-
tx_tps_peak: await this.queryPrometheus(query),
|
|
274
|
-
request_latency_average: await this.queryPrometheus(
|
|
275
|
-
'nord_requests_ok_latency{quantile="0.5"}',
|
|
276
|
-
),
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
async getCurrentTps(period: string = "1m") {
|
|
281
|
-
return await this.queryPrometheus(
|
|
282
|
-
"rate(nord_requests_ok_count[" + period + "])",
|
|
283
|
-
);
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
async getPeakTps(period: string = "24h") {
|
|
287
|
-
return await this.queryPrometheus(
|
|
288
|
-
"max_over_time(rate(nord_requests_ok_count[30s])[" + period + ":])",
|
|
289
|
-
);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
async getMedianLatency(period: string = "1m") {
|
|
293
|
-
return await this.queryPrometheus(
|
|
294
|
-
`avg_over_time(nord_requests_ok_latency{quantile="0.5"}[${period}])`,
|
|
295
|
-
);
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
async getTotalTransactions() {
|
|
299
|
-
return await (
|
|
300
|
-
await checkedFetch(this.webServerUrl + "/last_actionid")
|
|
301
|
-
).text();
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Helper to query rollman for block info.
|
|
305
|
-
async blockQueryRollman(query: BlockQuery): Promise<RollmanBlockResponse> {
|
|
306
|
-
let url = this.webServerUrl + "/block_query";
|
|
307
|
-
if (query.block_number != null) {
|
|
308
|
-
url = url + "?block_number=" + query.block_number;
|
|
309
|
-
}
|
|
310
|
-
const response = await checkedFetch(url);
|
|
311
|
-
if (!response.ok) {
|
|
312
|
-
throw new Error("Rollman query failed " + url);
|
|
313
|
-
}
|
|
314
|
-
return await response.json();
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
// Helper to query rollman for recent block summary.
|
|
318
|
-
async blockSummaryQueryRollman(
|
|
319
|
-
last_n: number,
|
|
320
|
-
): Promise<BlockSummaryResponse> {
|
|
321
|
-
const url = this.webServerUrl + "/last_n_blocks?last_n=" + last_n;
|
|
322
|
-
const response = await checkedFetch(url);
|
|
323
|
-
if (!response.ok) {
|
|
324
|
-
throw new Error("Rollman query failed " + url);
|
|
325
|
-
}
|
|
326
|
-
return await response.json();
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Helper to query rollman for action info.
|
|
330
|
-
async actionQueryRollman(query: ActionQuery): Promise<RollmanActionResponse> {
|
|
331
|
-
const url = this.webServerUrl + "/tx_query?action_id=" + query.action_id;
|
|
332
|
-
const response = await checkedFetch(url);
|
|
333
|
-
if (!response.ok) {
|
|
334
|
-
throw new Error("Rollman query failed " + url);
|
|
335
|
-
}
|
|
336
|
-
return await response.json();
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Helper to query rollman for recent actions.
|
|
340
|
-
async actionsQueryRollman(last_n: number): Promise<RollmanActionsResponse> {
|
|
341
|
-
const url = this.webServerUrl + "/last_n_actions?last_n=" + last_n;
|
|
342
|
-
const response = await checkedFetch(url);
|
|
343
|
-
if (!response.ok) {
|
|
344
|
-
throw new Error("Rollman query failed " + url);
|
|
345
|
-
}
|
|
346
|
-
return await response.json();
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
// Helper to query prometheus.
|
|
350
|
-
async queryPrometheus(params: string): Promise<number> {
|
|
351
|
-
const url = this.webServerUrl + "/prometheus_query?query=" + params;
|
|
352
|
-
const response = await checkedFetch(url);
|
|
353
|
-
if (!response.ok) {
|
|
354
|
-
throw new Error("Prometheus query failed " + url);
|
|
355
|
-
}
|
|
356
|
-
const json = await response.json();
|
|
357
|
-
// Prometheus HTTP API: https://prometheus.io/docs/prometheus/latest/querying/api/
|
|
358
|
-
return Number(json.data.result[0].value[1]);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
static async approveTx(
|
|
362
|
-
privateAddress: string,
|
|
363
|
-
erc20address: string,
|
|
364
|
-
contractAddress: string,
|
|
365
|
-
): Promise<void> {
|
|
366
|
-
const provider = new ethers.JsonRpcProvider(process.env.SECRET_FAUCET_RPC);
|
|
367
|
-
const wallet = new ethers.Wallet(privateAddress, provider);
|
|
368
|
-
const erc20Contract = new ethers.Contract(erc20address, ERC20_ABI, wallet);
|
|
369
|
-
|
|
370
|
-
const maxUint256 = ethers.MaxUint256;
|
|
371
|
-
const approveTx = await erc20Contract.approve(
|
|
372
|
-
contractAddress,
|
|
373
|
-
maxUint256.toString(),
|
|
374
|
-
{
|
|
375
|
-
maxFeePerGas: ethers.parseUnits("30", "gwei"),
|
|
376
|
-
maxPriorityFeePerGas: ethers.parseUnits("0.001", "gwei"),
|
|
377
|
-
},
|
|
378
|
-
);
|
|
379
|
-
return approveTx.hash;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
/**
|
|
383
|
-
* Fetches a sequence of actions between specified action IDs
|
|
384
|
-
* @param fromActionId - Starting action ID
|
|
385
|
-
* @param toActionId - Ending action ID
|
|
386
|
-
* @returns A promise that resolves to an ActionsResponse
|
|
387
|
-
*/
|
|
388
|
-
async getActions(fromActionId: number, toActionId: number): Promise<ActionsResponse> {
|
|
389
|
-
const response = await checkedFetch(
|
|
390
|
-
`${this.webServerUrl}/actions?from=${fromActionId}&to=${toActionId}`,
|
|
391
|
-
{ method: "GET" }
|
|
392
|
-
);
|
|
393
|
-
|
|
394
|
-
const rawResponse = await response.json();
|
|
395
|
-
const queryResponse: ActionsResponse = {
|
|
396
|
-
actions: [],
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
if (Array.isArray(rawResponse.actions)) {
|
|
400
|
-
for (const action of rawResponse.actions) {
|
|
401
|
-
const extendedActionInfo: ActionsExtendedInfo = {
|
|
402
|
-
block_number: action.block_number,
|
|
403
|
-
action_id: action.action_id,
|
|
404
|
-
action: decodeLengthDelimited(action.action_pb, proto.Action),
|
|
405
|
-
};
|
|
406
|
-
queryResponse.actions.push(extendedActionInfo);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
return queryResponse;
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Fetches trades for a specified account
|
|
415
|
-
* @param params - Query parameters for fetching trades
|
|
416
|
-
* @returns A promise that resolves to a TradesResponse
|
|
417
|
-
*/
|
|
418
|
-
async getTrades(params: TradesQueryParams): Promise<TradesResponse> {
|
|
419
|
-
const { accountId, since, until, pageId } = params;
|
|
420
|
-
|
|
421
|
-
let url = `${this.webServerUrl}/trades?accountId=${accountId}`;
|
|
422
|
-
if (since) {
|
|
423
|
-
url += `&since=${encodeURIComponent(since)}`;
|
|
424
|
-
}
|
|
425
|
-
if (until) {
|
|
426
|
-
url += `&until=${encodeURIComponent(until)}`;
|
|
427
|
-
}
|
|
428
|
-
if (pageId) {
|
|
429
|
-
url += `&pageId=${encodeURIComponent(pageId)}`;
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
const response = await checkedFetch(url, { method: "GET" });
|
|
433
|
-
const tradesResponse: TradesResponse = await response.json();
|
|
434
|
-
|
|
435
|
-
return tradesResponse;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* Fetches the orderbook for a specified market
|
|
440
|
-
* @param symbol - Market symbol
|
|
441
|
-
* @returns A promise that resolves to an OrderbookResponse
|
|
442
|
-
*/
|
|
443
|
-
async getOrderbook(symbol: string): Promise<OrderbookResponse> {
|
|
444
|
-
const response = await checkedFetch(
|
|
445
|
-
`${this.webServerUrl}/orderbook?symbol=${encodeURIComponent(symbol)}`,
|
|
446
|
-
{ method: "GET" }
|
|
447
|
-
);
|
|
448
|
-
|
|
449
|
-
const orderbook: OrderbookResponse = await response.json();
|
|
450
|
-
return orderbook;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
export class Subscriber {
|
|
455
|
-
streamURL: string;
|
|
456
|
-
buffer: (DeltaEvent | Trades | Account)[];
|
|
457
|
-
maxBufferLen: number;
|
|
458
|
-
|
|
459
|
-
constructor(config: SubscriberConfig) {
|
|
460
|
-
this.streamURL = config.streamURL;
|
|
461
|
-
this.buffer = [];
|
|
462
|
-
this.maxBufferLen = config.maxBufferLen || MAX_BUFFER_LEN;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
subscribe(): void {
|
|
466
|
-
const ws = new WebSocket(this.streamURL);
|
|
467
|
-
ws.on("message", (data) => {
|
|
468
|
-
try {
|
|
469
|
-
const parsed = JSON.parse(data.toString());
|
|
470
|
-
this.buffer.push(parsed);
|
|
471
|
-
if (this.buffer.length > this.maxBufferLen) {
|
|
472
|
-
this.buffer.shift();
|
|
473
|
-
}
|
|
474
|
-
} catch (e) {
|
|
475
|
-
console.error("Failed to parse websocket message", e);
|
|
476
|
-
}
|
|
477
|
-
});
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* Creates a WebSocket subscription to specified streams
|
|
483
|
-
* @param baseUrl - Base URL of the API
|
|
484
|
-
* @param streams - Array of streams to subscribe to
|
|
485
|
-
* @returns A Subscriber instance
|
|
486
|
-
*
|
|
487
|
-
* Syntax for streams:
|
|
488
|
-
* - trades@<symbol>: Subscribe to trades for a market
|
|
489
|
-
* - deltas@<symbol>: Subscribe to orderbook deltas for a market
|
|
490
|
-
* - user@<user id>: Subscribe to user account updates
|
|
491
|
-
*
|
|
492
|
-
* Example: createWebSocketSubscription('https://alpha-api.layern.network', ['trades@BTCUSDC', 'deltas@BTCUSDC', 'user@0'])
|
|
493
|
-
*/
|
|
494
|
-
export function createWebSocketSubscription(baseUrl: string, streams: string[]): Subscriber {
|
|
495
|
-
const streamPath = streams.join('&');
|
|
496
|
-
const wsUrl = baseUrl.replace(/^http/, 'ws') + `/ws/${streamPath}`;
|
|
497
|
-
|
|
498
|
-
const subscriber = new Subscriber({
|
|
499
|
-
streamURL: wsUrl,
|
|
500
|
-
});
|
|
501
|
-
|
|
502
|
-
subscriber.subscribe();
|
|
503
|
-
return subscriber;
|
|
504
|
-
}
|