@n1xyz/nord-ts 0.0.1
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/.eslintignore +1 -0
- package/.eslintrc.js +20 -0
- package/.prettierignore +1 -0
- package/README.md +110 -0
- package/dist/abis/ERC20_ABI.d.ts +39 -0
- package/dist/abis/ERC20_ABI.js +313 -0
- package/dist/abis/NORD_GETTERS_FACET_ABI.d.ts +34 -0
- package/dist/abis/NORD_GETTERS_FACET_ABI.js +195 -0
- package/dist/abis/NORD_RAMP_FACET_ABI.d.ts +35 -0
- package/dist/abis/NORD_RAMP_FACET_ABI.js +144 -0
- package/dist/abis/index.d.ts +3 -0
- package/dist/abis/index.js +9 -0
- package/dist/const.d.ts +11 -0
- package/dist/const.js +34 -0
- package/dist/gen/common.d.ts +63 -0
- package/dist/gen/common.js +205 -0
- package/dist/gen/nord.d.ts +705 -0
- package/dist/gen/nord.js +4784 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +21 -0
- package/dist/nord/Nord.d.ts +76 -0
- package/dist/nord/Nord.js +376 -0
- package/dist/nord/NordImpl.d.ts +7 -0
- package/dist/nord/NordImpl.js +6 -0
- package/dist/nord/NordUser.d.ts +77 -0
- package/dist/nord/NordUser.js +249 -0
- package/dist/nord/actions.d.ts +101 -0
- package/dist/nord/actions.js +254 -0
- package/dist/nord/index.d.ts +2 -0
- package/dist/nord/index.js +9 -0
- package/dist/types.d.ts +343 -0
- package/dist/types.js +92 -0
- package/dist/utils.d.ts +114 -0
- package/dist/utils.js +257 -0
- package/docs/.nojekyll +1 -0
- package/docs/assets/highlight.css +92 -0
- package/docs/assets/icons.js +15 -0
- package/docs/assets/icons.svg +1 -0
- package/docs/assets/main.js +59 -0
- package/docs/assets/navigation.js +1 -0
- package/docs/assets/search.js +1 -0
- package/docs/assets/style.css +1415 -0
- package/docs/classes/Nord.html +44 -0
- package/docs/classes/NordUser.html +35 -0
- package/docs/classes/Subscriber.html +6 -0
- package/docs/enums/FillMode.html +5 -0
- package/docs/enums/KeyType.html +4 -0
- package/docs/enums/PeakTpsPeriodUnit.html +15 -0
- package/docs/enums/Side.html +3 -0
- package/docs/functions/assert.html +1 -0
- package/docs/functions/bigIntToProtoU128.html +4 -0
- package/docs/functions/checkPubKeyLength.html +1 -0
- package/docs/functions/checkedFetch.html +6 -0
- package/docs/functions/createWebSocketSubscription.html +12 -0
- package/docs/functions/decodeLengthDelimited.html +10 -0
- package/docs/functions/encodeLengthDelimited.html +6 -0
- package/docs/functions/fillModeToProtoFillMode.html +5 -0
- package/docs/functions/findMarket.html +1 -0
- package/docs/functions/findToken.html +1 -0
- package/docs/functions/makeWalletSignFn.html +6 -0
- package/docs/functions/optExpect.html +5 -0
- package/docs/functions/optMap.html +5 -0
- package/docs/functions/optUnwrap.html +2 -0
- package/docs/functions/panic.html +1 -0
- package/docs/functions/signAction.html +6 -0
- package/docs/functions/toScaledU128.html +8 -0
- package/docs/functions/toScaledU64.html +8 -0
- package/docs/index.html +21 -0
- package/docs/interfaces/Account.html +8 -0
- package/docs/interfaces/ActionInfo.html +8 -0
- package/docs/interfaces/ActionQuery.html +4 -0
- package/docs/interfaces/ActionResponse.html +8 -0
- package/docs/interfaces/ActionsExtendedInfo.html +10 -0
- package/docs/interfaces/ActionsQuery.html +5 -0
- package/docs/interfaces/ActionsResponse.html +6 -0
- package/docs/interfaces/AggregateMetrics.html +12 -0
- package/docs/interfaces/BlockQuery.html +6 -0
- package/docs/interfaces/BlockResponse.html +6 -0
- package/docs/interfaces/BlockSummary.html +8 -0
- package/docs/interfaces/BlockSummaryResponse.html +6 -0
- package/docs/interfaces/DeltaEvent.html +6 -0
- package/docs/interfaces/ERC20TokenInfo.html +5 -0
- package/docs/interfaces/Info.html +3 -0
- package/docs/interfaces/Market.html +6 -0
- package/docs/interfaces/MarketStats.html +7 -0
- package/docs/interfaces/MarketsStatsResponse.html +2 -0
- package/docs/interfaces/NordConfig.html +5 -0
- package/docs/interfaces/Order.html +6 -0
- package/docs/interfaces/OrderInfo.html +6 -0
- package/docs/interfaces/OrderbookOrder.html +6 -0
- package/docs/interfaces/OrderbookResponse.html +10 -0
- package/docs/interfaces/PerpMarketStats.html +5 -0
- package/docs/interfaces/RollmanActionExtendedInfo.html +4 -0
- package/docs/interfaces/RollmanActionInfo.html +4 -0
- package/docs/interfaces/RollmanActionResponse.html +4 -0
- package/docs/interfaces/RollmanActionsResponse.html +2 -0
- package/docs/interfaces/RollmanBlockResponse.html +3 -0
- package/docs/interfaces/SubscriberConfig.html +3 -0
- package/docs/interfaces/Token.html +5 -0
- package/docs/interfaces/Trade.html +5 -0
- package/docs/interfaces/TradeInfo.html +20 -0
- package/docs/interfaces/Trades.html +5 -0
- package/docs/interfaces/TradesQueryParams.html +10 -0
- package/docs/interfaces/TradesResponse.html +12 -0
- package/docs/modules.html +77 -0
- package/docs/types/BigIntValue.html +2 -0
- package/docs/variables/DEBUG_KEYS.html +1 -0
- package/docs/variables/DEFAULT_FUNDING_AMOUNTS.html +1 -0
- package/docs/variables/DEV_CONTRACT_ADDRESS.html +1 -0
- package/docs/variables/DEV_TOKEN_INFOS.html +1 -0
- package/docs/variables/DEV_URL.html +1 -0
- package/docs/variables/ERC20_ABI.html +1 -0
- package/docs/variables/EVM_DEV_URL.html +1 -0
- package/docs/variables/FAUCET_PRIVATE_ADDRESS.html +1 -0
- package/docs/variables/MAX_BUFFER_LEN.html +1 -0
- package/docs/variables/NORD_GETTERS_FACET_ABI.html +1 -0
- package/docs/variables/NORD_RAMP_FACET_ABI.html +1 -0
- package/docs/variables/SESSION_TTL.html +1 -0
- package/docs/variables/WEBSERVER_DEV_URL.html +1 -0
- package/docs/variables/ZERO_DECIMAL.html +1 -0
- package/jest.config.ts +9 -0
- package/nodemon.json +4 -0
- package/package.json +61 -0
- package/protoc-generate.sh +23 -0
- package/src/abis/ERC20_ABI.ts +310 -0
- package/src/abis/NORD_GETTERS_FACET_ABI.ts +192 -0
- package/src/abis/NORD_RAMP_FACET_ABI.ts +141 -0
- package/src/abis/index.ts +3 -0
- package/src/const.ts +39 -0
- package/src/gen/common.ts +280 -0
- package/src/gen/nord.ts +5666 -0
- package/src/index.ts +5 -0
- package/src/nord/Nord.ts +504 -0
- package/src/nord/NordImpl.ts +8 -0
- package/src/nord/NordUser.ts +469 -0
- package/src/nord/actions.ts +484 -0
- package/src/nord/index.ts +2 -0
- package/src/types.ts +393 -0
- package/src/utils.ts +300 -0
- package/tests/utils.spec.ts +154 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import { BrowserProvider, ethers, SigningKey, MaxUint256 } from "ethers";
|
|
2
|
+
import secp256k1 from "secp256k1";
|
|
3
|
+
import { DEFAULT_FUNDING_AMOUNTS, FAUCET_PRIVATE_ADDRESS } from "../const";
|
|
4
|
+
import {
|
|
5
|
+
assert,
|
|
6
|
+
BigIntValue,
|
|
7
|
+
checkedFetch,
|
|
8
|
+
findMarket,
|
|
9
|
+
findToken,
|
|
10
|
+
optExpect,
|
|
11
|
+
} from "../utils";
|
|
12
|
+
import { ERC20_ABI, NORD_RAMP_FACET_ABI } from "../abis";
|
|
13
|
+
import {
|
|
14
|
+
cancelOrder,
|
|
15
|
+
createSession,
|
|
16
|
+
placeOrder,
|
|
17
|
+
revokeSession,
|
|
18
|
+
transfer,
|
|
19
|
+
withdraw,
|
|
20
|
+
} from "./actions";
|
|
21
|
+
import { FillMode, Order, Side } from "../types";
|
|
22
|
+
import { Nord } from "./Nord";
|
|
23
|
+
import Decimal from "decimal.js";
|
|
24
|
+
|
|
25
|
+
export class NordUser {
|
|
26
|
+
nord: Nord;
|
|
27
|
+
address: string;
|
|
28
|
+
walletSignFn: (message: Uint8Array | string) => Promise<string>;
|
|
29
|
+
sessionSignFn: (message: Uint8Array) => Promise<Uint8Array>;
|
|
30
|
+
balances: {
|
|
31
|
+
[key: string]: { accountId: number; balance: number; symbol: string }[];
|
|
32
|
+
} = {};
|
|
33
|
+
orders: { [key: string]: Order[] } = {};
|
|
34
|
+
accountIds?: number[];
|
|
35
|
+
sessionId?: bigint;
|
|
36
|
+
|
|
37
|
+
publicKey: Uint8Array | undefined;
|
|
38
|
+
lastTs = 0;
|
|
39
|
+
lastNonce = 0;
|
|
40
|
+
|
|
41
|
+
constructor(params: {
|
|
42
|
+
nord: Nord;
|
|
43
|
+
address: string;
|
|
44
|
+
walletSignFn: (message: Uint8Array | string) => Promise<string>;
|
|
45
|
+
sessionSignFn: (message: Uint8Array) => Promise<Uint8Array>;
|
|
46
|
+
}) {
|
|
47
|
+
this.nord = params.nord;
|
|
48
|
+
this.address = params.address;
|
|
49
|
+
this.walletSignFn = params.walletSignFn;
|
|
50
|
+
this.sessionSignFn = params.sessionSignFn;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
clone(): NordUser {
|
|
54
|
+
const newUser = new NordUser({
|
|
55
|
+
nord: this.nord,
|
|
56
|
+
address: this.address,
|
|
57
|
+
walletSignFn: this.walletSignFn,
|
|
58
|
+
sessionSignFn: this.sessionSignFn,
|
|
59
|
+
});
|
|
60
|
+
newUser.publicKey = this.publicKey;
|
|
61
|
+
newUser.lastTs = this.lastTs;
|
|
62
|
+
newUser.lastNonce = this.lastNonce;
|
|
63
|
+
newUser.accountIds = this.accountIds;
|
|
64
|
+
newUser.sessionId = this.sessionId;
|
|
65
|
+
return newUser;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Generates a nonce based on the current timestamp.
|
|
70
|
+
* @returns Generated nonce as a number.
|
|
71
|
+
*/
|
|
72
|
+
getNonce(): number {
|
|
73
|
+
const ts = Date.now() / 1000;
|
|
74
|
+
if (ts === this.lastTs) {
|
|
75
|
+
this.lastNonce += 1;
|
|
76
|
+
} else {
|
|
77
|
+
this.lastTs = ts;
|
|
78
|
+
this.lastNonce = 0;
|
|
79
|
+
}
|
|
80
|
+
return this.lastNonce;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async updateAccountId() {
|
|
84
|
+
const hexPubkey = ethers
|
|
85
|
+
.hexlify(optExpect(this.publicKey, "No user public key"))
|
|
86
|
+
.slice(2);
|
|
87
|
+
const accountIds_ = await (
|
|
88
|
+
await checkedFetch(
|
|
89
|
+
`${this.nord.webServerUrl}/user_account_ids?pubkey=${hexPubkey}`,
|
|
90
|
+
)
|
|
91
|
+
).json();
|
|
92
|
+
assert(Array.isArray(accountIds_), "Unexpected response");
|
|
93
|
+
const accountIds = accountIds_ as Array<number>;
|
|
94
|
+
this.accountIds = accountIds;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async fetchInfo() {
|
|
98
|
+
interface FetchOrder {
|
|
99
|
+
orderId: number;
|
|
100
|
+
size: number;
|
|
101
|
+
price: number;
|
|
102
|
+
marketId: number;
|
|
103
|
+
side: "ask" | "bid";
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
interface Balance {
|
|
107
|
+
tokenId: number;
|
|
108
|
+
token: string;
|
|
109
|
+
amount: number;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
interface Account {
|
|
113
|
+
orders: FetchOrder[];
|
|
114
|
+
balances: Balance[];
|
|
115
|
+
accountId: number;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (this.accountIds !== undefined) {
|
|
119
|
+
// todo:implement class
|
|
120
|
+
const accountsData = await Promise.all(
|
|
121
|
+
this.accountIds.map(async (accountId) => {
|
|
122
|
+
const response = await checkedFetch(
|
|
123
|
+
`${this.nord.webServerUrl}/account?account_id=${accountId}`,
|
|
124
|
+
);
|
|
125
|
+
return {
|
|
126
|
+
accountId,
|
|
127
|
+
...((await response.json()) as Promise<Account>),
|
|
128
|
+
};
|
|
129
|
+
}),
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
for (const accountData of accountsData) {
|
|
133
|
+
this.balances[accountData.accountId] = [];
|
|
134
|
+
for (const balance of accountData.balances) {
|
|
135
|
+
this.balances[accountData.accountId].push({
|
|
136
|
+
accountId: accountData.accountId,
|
|
137
|
+
balance: balance.amount,
|
|
138
|
+
symbol: balance.token,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
this.orders[accountData.accountId] = accountData.orders.map(
|
|
143
|
+
(order: {
|
|
144
|
+
orderId: number;
|
|
145
|
+
side: string;
|
|
146
|
+
size: number;
|
|
147
|
+
price: number;
|
|
148
|
+
marketId: number;
|
|
149
|
+
}) => {
|
|
150
|
+
return {
|
|
151
|
+
orderId: order.orderId,
|
|
152
|
+
isLong: order.side === "bid",
|
|
153
|
+
size: order.size,
|
|
154
|
+
price: order.price,
|
|
155
|
+
marketId: order.marketId,
|
|
156
|
+
};
|
|
157
|
+
},
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
async setPublicKey() {
|
|
164
|
+
const message = "Layer N - Nord";
|
|
165
|
+
const msgHash = ethers.hashMessage(message);
|
|
166
|
+
const msgHashBytes = ethers.getBytes(msgHash);
|
|
167
|
+
const signature = await this.walletSignFn(message);
|
|
168
|
+
const recoveredPubKey = SigningKey.recoverPublicKey(
|
|
169
|
+
msgHashBytes,
|
|
170
|
+
signature,
|
|
171
|
+
);
|
|
172
|
+
const publicKeyBuffer = Buffer.from(recoveredPubKey.slice(2), "hex");
|
|
173
|
+
this.publicKey = secp256k1.publicKeyConvert(publicKeyBuffer, true);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async fundEthWallet() {
|
|
177
|
+
const provider = new ethers.JsonRpcProvider(this.nord.evmUrl);
|
|
178
|
+
const wallet = new ethers.Wallet(FAUCET_PRIVATE_ADDRESS, provider);
|
|
179
|
+
assert(DEFAULT_FUNDING_AMOUNTS["ETH"] != null);
|
|
180
|
+
const ethTx = await wallet.sendTransaction({
|
|
181
|
+
to: this.address,
|
|
182
|
+
value: ethers.parseEther(DEFAULT_FUNDING_AMOUNTS["ETH"][0]),
|
|
183
|
+
});
|
|
184
|
+
await ethTx.wait();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async fundErc20Wallet() {
|
|
188
|
+
const provider = new ethers.JsonRpcProvider(this.nord.evmUrl);
|
|
189
|
+
const wallet = new ethers.Wallet(FAUCET_PRIVATE_ADDRESS, provider);
|
|
190
|
+
assert(DEFAULT_FUNDING_AMOUNTS["ETH"] != null);
|
|
191
|
+
for (const tokenInfo of this.nord.tokenInfos) {
|
|
192
|
+
const erc20Contract = new ethers.Contract(
|
|
193
|
+
tokenInfo.address,
|
|
194
|
+
ERC20_ABI,
|
|
195
|
+
wallet,
|
|
196
|
+
);
|
|
197
|
+
if (DEFAULT_FUNDING_AMOUNTS[tokenInfo.address]) {
|
|
198
|
+
const defaultFundingAmount = DEFAULT_FUNDING_AMOUNTS[tokenInfo.address];
|
|
199
|
+
const tokenTx = await erc20Contract.transfer(
|
|
200
|
+
this.address,
|
|
201
|
+
ethers.parseUnits(defaultFundingAmount[0], defaultFundingAmount[1]),
|
|
202
|
+
{
|
|
203
|
+
maxFeePerGas: ethers.parseUnits("30", "gwei"),
|
|
204
|
+
maxPriorityFeePerGas: ethers.parseUnits("0.001", "gwei"),
|
|
205
|
+
},
|
|
206
|
+
);
|
|
207
|
+
await tokenTx.wait();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
async refreshSession(sessionPk: Uint8Array): Promise<void> {
|
|
213
|
+
this.sessionId = await createSession(
|
|
214
|
+
this.nord.webServerUrl,
|
|
215
|
+
this.walletSignFn,
|
|
216
|
+
await this.nord.impl.getTimestamp(),
|
|
217
|
+
this.getNonce(),
|
|
218
|
+
{
|
|
219
|
+
userPubkey: optExpect(this.publicKey, "No user's public key"),
|
|
220
|
+
sessionPubkey: sessionPk,
|
|
221
|
+
},
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Revokes session previously created by user
|
|
226
|
+
*
|
|
227
|
+
* @param sessionId - session identifier
|
|
228
|
+
*/
|
|
229
|
+
async revokeSession(sessionId: BigIntValue): Promise<void> {
|
|
230
|
+
return revokeSession(
|
|
231
|
+
this.nord.webServerUrl,
|
|
232
|
+
this.walletSignFn,
|
|
233
|
+
await this.nord.impl.getTimestamp(),
|
|
234
|
+
this.getNonce(),
|
|
235
|
+
{
|
|
236
|
+
sessionId,
|
|
237
|
+
},
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async deposit(
|
|
242
|
+
provider: BrowserProvider,
|
|
243
|
+
amount: number,
|
|
244
|
+
tokenId: number,
|
|
245
|
+
): Promise<void> {
|
|
246
|
+
const erc20 = this.nord.tokenInfos[tokenId];
|
|
247
|
+
const erc20Contract = new ethers.Contract(
|
|
248
|
+
erc20.address,
|
|
249
|
+
ERC20_ABI,
|
|
250
|
+
await provider.getSigner(),
|
|
251
|
+
);
|
|
252
|
+
|
|
253
|
+
const approveTx = await erc20Contract.approve(
|
|
254
|
+
this.nord.contractAddress,
|
|
255
|
+
MaxUint256,
|
|
256
|
+
{
|
|
257
|
+
maxFeePerGas: ethers.parseUnits("30", "gwei"),
|
|
258
|
+
maxPriorityFeePerGas: ethers.parseUnits("0.001", "gwei"),
|
|
259
|
+
},
|
|
260
|
+
);
|
|
261
|
+
await approveTx.wait();
|
|
262
|
+
const nordContract = new ethers.Contract(
|
|
263
|
+
this.nord.contractAddress,
|
|
264
|
+
NORD_RAMP_FACET_ABI,
|
|
265
|
+
await provider.getSigner(),
|
|
266
|
+
);
|
|
267
|
+
const depositTx = await nordContract.depositUnchecked(
|
|
268
|
+
this.publicKey,
|
|
269
|
+
BigInt(0),
|
|
270
|
+
ethers.parseUnits(amount.toString(), erc20.precision),
|
|
271
|
+
{
|
|
272
|
+
maxFeePerGas: ethers.parseUnits("30", "gwei"),
|
|
273
|
+
maxPriorityFeePerGas: ethers.parseUnits("0.001", "gwei"),
|
|
274
|
+
},
|
|
275
|
+
);
|
|
276
|
+
await depositTx.wait();
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
async depositApproveTx(
|
|
280
|
+
provider: BrowserProvider,
|
|
281
|
+
amount: number,
|
|
282
|
+
tokenId: number,
|
|
283
|
+
): Promise<void> {
|
|
284
|
+
const erc20 = this.nord.tokenInfos[tokenId];
|
|
285
|
+
const erc20Contract = new ethers.Contract(
|
|
286
|
+
erc20.address,
|
|
287
|
+
ERC20_ABI,
|
|
288
|
+
await provider.getSigner(),
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
const approveTx = await erc20Contract.approve(
|
|
292
|
+
this.nord.contractAddress,
|
|
293
|
+
MaxUint256,
|
|
294
|
+
{
|
|
295
|
+
maxFeePerGas: ethers.parseUnits("30", "gwei"),
|
|
296
|
+
maxPriorityFeePerGas: ethers.parseUnits("0.001", "gwei"),
|
|
297
|
+
},
|
|
298
|
+
);
|
|
299
|
+
return approveTx.hash;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
async depositOnlyTx(
|
|
303
|
+
provider: BrowserProvider,
|
|
304
|
+
amount: number,
|
|
305
|
+
tokenId: number,
|
|
306
|
+
): Promise<void> {
|
|
307
|
+
const erc20 = this.nord.tokenInfos[tokenId];
|
|
308
|
+
const nordContract = new ethers.Contract(
|
|
309
|
+
this.nord.contractAddress,
|
|
310
|
+
NORD_RAMP_FACET_ABI,
|
|
311
|
+
await provider.getSigner(),
|
|
312
|
+
);
|
|
313
|
+
const depositTx = await nordContract.depositUnchecked(
|
|
314
|
+
this.publicKey,
|
|
315
|
+
BigInt(0),
|
|
316
|
+
ethers.parseUnits(amount.toString(), erc20.precision),
|
|
317
|
+
{
|
|
318
|
+
maxFeePerGas: ethers.parseUnits("30", "gwei"),
|
|
319
|
+
maxPriorityFeePerGas: ethers.parseUnits("0.001", "gwei"),
|
|
320
|
+
},
|
|
321
|
+
);
|
|
322
|
+
return depositTx.hash;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
async depositEth(
|
|
326
|
+
provider: BrowserProvider,
|
|
327
|
+
amount: number,
|
|
328
|
+
tokenId: number,
|
|
329
|
+
): Promise<void> {
|
|
330
|
+
if (tokenId || tokenId == 0) {
|
|
331
|
+
const nordContract = new ethers.Contract(
|
|
332
|
+
this.nord.contractAddress,
|
|
333
|
+
NORD_RAMP_FACET_ABI,
|
|
334
|
+
await provider.getSigner(),
|
|
335
|
+
);
|
|
336
|
+
const depositTx = await nordContract.depositUnchecked(
|
|
337
|
+
this.publicKey,
|
|
338
|
+
BigInt(1),
|
|
339
|
+
ethers.parseUnits(amount.toString(), 18),
|
|
340
|
+
{
|
|
341
|
+
maxFeePerGas: ethers.parseUnits("30", "gwei"),
|
|
342
|
+
maxPriorityFeePerGas: ethers.parseUnits("0.001", "gwei"),
|
|
343
|
+
},
|
|
344
|
+
);
|
|
345
|
+
await depositTx.wait();
|
|
346
|
+
} else {
|
|
347
|
+
// todo:implement eth deposits
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async withdraw(tokenId: number, amount: number): Promise<void> {
|
|
352
|
+
withdraw(
|
|
353
|
+
this.nord.webServerUrl,
|
|
354
|
+
this.sessionSignFn,
|
|
355
|
+
await this.nord.impl.getTimestamp(),
|
|
356
|
+
this.getNonce(),
|
|
357
|
+
{
|
|
358
|
+
sizeDecimals: findToken(this.nord.tokens, tokenId).decimals,
|
|
359
|
+
sessionId: optExpect(this.sessionId, "No session"),
|
|
360
|
+
tokenId: tokenId,
|
|
361
|
+
amount,
|
|
362
|
+
},
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
async placeOrder(params: {
|
|
367
|
+
marketId: number;
|
|
368
|
+
side: Side;
|
|
369
|
+
fillMode: FillMode;
|
|
370
|
+
isReduceOnly: boolean;
|
|
371
|
+
size?: Decimal.Value;
|
|
372
|
+
price?: Decimal.Value;
|
|
373
|
+
quoteSize?: Decimal.Value;
|
|
374
|
+
accountId?: number;
|
|
375
|
+
}): Promise<bigint | undefined> {
|
|
376
|
+
const market = findMarket(this.nord.markets, params.marketId);
|
|
377
|
+
|
|
378
|
+
return placeOrder(
|
|
379
|
+
this.nord.webServerUrl,
|
|
380
|
+
this.sessionSignFn,
|
|
381
|
+
await this.nord.impl.getTimestamp(),
|
|
382
|
+
this.getNonce(),
|
|
383
|
+
{
|
|
384
|
+
sessionId: optExpect(this.sessionId, "No session"),
|
|
385
|
+
senderId: params.accountId,
|
|
386
|
+
sizeDecimals: market.sizeDecimals,
|
|
387
|
+
priceDecimals: market.priceDecimals,
|
|
388
|
+
marketId: params.marketId,
|
|
389
|
+
side: params.side,
|
|
390
|
+
fillMode: params.fillMode,
|
|
391
|
+
isReduceOnly: params.isReduceOnly,
|
|
392
|
+
size: params.size,
|
|
393
|
+
price: params.price,
|
|
394
|
+
quoteSize: params.quoteSize,
|
|
395
|
+
},
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
async cancelOrder(orderId: BigIntValue, accountId: number): Promise<bigint> {
|
|
400
|
+
return cancelOrder(
|
|
401
|
+
this.nord.webServerUrl,
|
|
402
|
+
this.sessionSignFn,
|
|
403
|
+
await this.nord.impl.getTimestamp(),
|
|
404
|
+
this.getNonce(),
|
|
405
|
+
{
|
|
406
|
+
sessionId: optExpect(this.sessionId, "No session"),
|
|
407
|
+
senderId: accountId,
|
|
408
|
+
orderId,
|
|
409
|
+
},
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
async transferToAccount(params: {
|
|
414
|
+
to: NordUser;
|
|
415
|
+
tokenId: number;
|
|
416
|
+
amount: Decimal.Value;
|
|
417
|
+
fromAccountId: number;
|
|
418
|
+
toAccountId: number;
|
|
419
|
+
}): Promise<void> {
|
|
420
|
+
const token = findToken(this.nord.tokens, params.tokenId);
|
|
421
|
+
|
|
422
|
+
await transfer(
|
|
423
|
+
this.nord.webServerUrl,
|
|
424
|
+
this.sessionSignFn,
|
|
425
|
+
await this.nord.impl.getTimestamp(),
|
|
426
|
+
this.getNonce(),
|
|
427
|
+
{
|
|
428
|
+
sessionId: optExpect(this.sessionId, "No session"),
|
|
429
|
+
fromAccountId: optExpect(params.fromAccountId, "No source account"),
|
|
430
|
+
toAccountId: optExpect(params.toAccountId, "No target account"),
|
|
431
|
+
tokenId: params.tokenId,
|
|
432
|
+
tokenDecimals: token.decimals,
|
|
433
|
+
amount: params.amount,
|
|
434
|
+
},
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
async createAccount(params: {
|
|
439
|
+
tokenId: number;
|
|
440
|
+
amount: Decimal.Value;
|
|
441
|
+
}): Promise<NordUser> {
|
|
442
|
+
const token = findToken(this.nord.tokens, params.tokenId);
|
|
443
|
+
|
|
444
|
+
const maybeToAccountId = await transfer(
|
|
445
|
+
this.nord.webServerUrl,
|
|
446
|
+
this.sessionSignFn,
|
|
447
|
+
await this.nord.impl.getTimestamp(),
|
|
448
|
+
this.getNonce(),
|
|
449
|
+
{
|
|
450
|
+
sessionId: optExpect(this.sessionId, "No session"),
|
|
451
|
+
fromAccountId: optExpect(this.accountIds?.[0], "No source account"),
|
|
452
|
+
toAccountId: undefined,
|
|
453
|
+
tokenId: params.tokenId,
|
|
454
|
+
tokenDecimals: token.decimals,
|
|
455
|
+
amount: params.amount,
|
|
456
|
+
},
|
|
457
|
+
);
|
|
458
|
+
|
|
459
|
+
const toAccountId = optExpect(
|
|
460
|
+
maybeToAccountId,
|
|
461
|
+
"New account should have been created",
|
|
462
|
+
);
|
|
463
|
+
const newUser = this.clone();
|
|
464
|
+
newUser.accountIds?.push(toAccountId);
|
|
465
|
+
await newUser.fetchInfo();
|
|
466
|
+
|
|
467
|
+
return newUser;
|
|
468
|
+
}
|
|
469
|
+
}
|