lighter-ts-sdk 1.0.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.
Files changed (110) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +440 -0
  3. package/dist/api/account-api.d.ts +89 -0
  4. package/dist/api/account-api.d.ts.map +1 -0
  5. package/dist/api/account-api.js +61 -0
  6. package/dist/api/account-api.js.map +1 -0
  7. package/dist/api/api-client.d.ts +23 -0
  8. package/dist/api/api-client.d.ts.map +1 -0
  9. package/dist/api/api-client.js +129 -0
  10. package/dist/api/api-client.js.map +1 -0
  11. package/dist/api/block-api.d.ts +24 -0
  12. package/dist/api/block-api.d.ts.map +1 -0
  13. package/dist/api/block-api.js +22 -0
  14. package/dist/api/block-api.js.map +1 -0
  15. package/dist/api/candlestick-api.d.ts +27 -0
  16. package/dist/api/candlestick-api.d.ts.map +1 -0
  17. package/dist/api/candlestick-api.js +18 -0
  18. package/dist/api/candlestick-api.js.map +1 -0
  19. package/dist/api/order-api.d.ts +76 -0
  20. package/dist/api/order-api.d.ts.map +1 -0
  21. package/dist/api/order-api.js +102 -0
  22. package/dist/api/order-api.js.map +1 -0
  23. package/dist/api/root-api.d.ts +8 -0
  24. package/dist/api/root-api.d.ts.map +1 -0
  25. package/dist/api/root-api.js +14 -0
  26. package/dist/api/root-api.js.map +1 -0
  27. package/dist/api/transaction-api.d.ts +58 -0
  28. package/dist/api/transaction-api.d.ts.map +1 -0
  29. package/dist/api/transaction-api.js +141 -0
  30. package/dist/api/transaction-api.js.map +1 -0
  31. package/dist/api/ws-client.d.ts +21 -0
  32. package/dist/api/ws-client.d.ts.map +1 -0
  33. package/dist/api/ws-client.js +139 -0
  34. package/dist/api/ws-client.js.map +1 -0
  35. package/dist/index.d.ts +62 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +99 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/signer/signer-client.d.ts +79 -0
  40. package/dist/signer/signer-client.d.ts.map +1 -0
  41. package/dist/signer/signer-client.js +213 -0
  42. package/dist/signer/signer-client.js.map +1 -0
  43. package/dist/signer/wasm-signer-client.d.ts +129 -0
  44. package/dist/signer/wasm-signer-client.d.ts.map +1 -0
  45. package/dist/signer/wasm-signer-client.js +607 -0
  46. package/dist/signer/wasm-signer-client.js.map +1 -0
  47. package/dist/types/index.d.ts +130 -0
  48. package/dist/types/index.d.ts.map +1 -0
  49. package/dist/types/index.js +3 -0
  50. package/dist/types/index.js.map +1 -0
  51. package/dist/utils/api-key-utils.d.ts +7 -0
  52. package/dist/utils/api-key-utils.d.ts.map +1 -0
  53. package/dist/utils/api-key-utils.js +31 -0
  54. package/dist/utils/api-key-utils.js.map +1 -0
  55. package/dist/utils/configuration.d.ts +19 -0
  56. package/dist/utils/configuration.d.ts.map +1 -0
  57. package/dist/utils/configuration.js +55 -0
  58. package/dist/utils/configuration.js.map +1 -0
  59. package/dist/utils/exceptions.d.ts +33 -0
  60. package/dist/utils/exceptions.d.ts.map +1 -0
  61. package/dist/utils/exceptions.js +76 -0
  62. package/dist/utils/exceptions.js.map +1 -0
  63. package/dist/utils/node-wasm-signer.d.ts +126 -0
  64. package/dist/utils/node-wasm-signer.d.ts.map +1 -0
  65. package/dist/utils/node-wasm-signer.js +286 -0
  66. package/dist/utils/node-wasm-signer.js.map +1 -0
  67. package/dist/utils/signer-server.d.ts +18 -0
  68. package/dist/utils/signer-server.d.ts.map +1 -0
  69. package/dist/utils/signer-server.js +79 -0
  70. package/dist/utils/signer-server.js.map +1 -0
  71. package/dist/utils/signer.d.ts +15 -0
  72. package/dist/utils/signer.d.ts.map +1 -0
  73. package/dist/utils/signer.js +68 -0
  74. package/dist/utils/signer.js.map +1 -0
  75. package/dist/utils/wasm-signer.d.ts +130 -0
  76. package/dist/utils/wasm-signer.d.ts.map +1 -0
  77. package/dist/utils/wasm-signer.js +178 -0
  78. package/dist/utils/wasm-signer.js.map +1 -0
  79. package/docs/API.md +195 -0
  80. package/docs/AccountApi.md +220 -0
  81. package/docs/GettingStarted.md +261 -0
  82. package/docs/OrderApi.md +199 -0
  83. package/docs/SignerClient.md +326 -0
  84. package/docs/TransactionApi.md +312 -0
  85. package/docs/WsClient.md +275 -0
  86. package/docs/types/Account.md +67 -0
  87. package/docs/types/ApiKeyPair.md +33 -0
  88. package/docs/types/CreateOrderParams.md +47 -0
  89. package/docs/types/MarketOrderParams.md +36 -0
  90. package/docs/types/SignerConfig.md +40 -0
  91. package/docs/types/WasmSignerConfig.md +30 -0
  92. package/examples/README.md +171 -0
  93. package/examples/account_info.ts +12 -0
  94. package/examples/create_cancel_order.ts +74 -0
  95. package/examples/create_market_order.ts +42 -0
  96. package/examples/create_market_order_max_slippage.ts +43 -0
  97. package/examples/create_sl_tp.ts +61 -0
  98. package/examples/create_with_multiple_keys.ts +58 -0
  99. package/examples/get_info.ts +58 -0
  100. package/examples/send_tx_batch.ts +87 -0
  101. package/examples/system_setup.ts +96 -0
  102. package/examples/transfer_update_leverage.ts +53 -0
  103. package/examples/ws.ts +24 -0
  104. package/examples/ws_async.ts +39 -0
  105. package/examples/ws_send_batch_tx.ts +113 -0
  106. package/examples/ws_send_tx.ts +94 -0
  107. package/package.json +71 -0
  108. package/wasm/lighter-signer.wasm +0 -0
  109. package/wasm/wasm_exec.js +402 -0
  110. package/wasm/wasm_exec_nodejs.js +402 -0
@@ -0,0 +1,12 @@
1
+ //Get account index and balance from the client
2
+
3
+ import { Account } from "../src/api/account-api";
4
+ import { ApiClient } from "../src/api/api-client";
5
+
6
+ async function main(): Promise<void> {
7
+ const client = new ApiClient();
8
+ const reponse = await client.get<Account>('/api/v1/account', { by: 'l1_address', value: process.env.L1_ADDRESS });
9
+ console.log(reponse.data);
10
+ }
11
+
12
+ main();
@@ -0,0 +1,74 @@
1
+ import { SignerClient } from '../src/signer/wasm-signer-client';
2
+ import * as dotenv from 'dotenv';
3
+
4
+ dotenv.config();
5
+
6
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
7
+ const API_KEY_PRIVATE_KEY = process.env['PRIVATE_KEY'];
8
+ const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '0', 10);
9
+ const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '0', 10);
10
+
11
+ async function main(): Promise<void> {
12
+ if (!API_KEY_PRIVATE_KEY) {
13
+ console.error('PRIVATE_KEY environment variable is required');
14
+ return;
15
+ }
16
+
17
+ const client = new SignerClient({
18
+ url: BASE_URL,
19
+ privateKey: API_KEY_PRIVATE_KEY,
20
+ accountIndex: ACCOUNT_INDEX,
21
+ apiKeyIndex: API_KEY_INDEX,
22
+ wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
23
+ });
24
+
25
+ await client.initialize();
26
+ await (client as any).ensureWasmClient();
27
+
28
+ const err = client.checkClient();
29
+ if (err) {
30
+ console.error('CheckClient error:', err);
31
+ return;
32
+ }
33
+
34
+ // Create order
35
+ const [tx, txHash, createErr] = await client.createOrder({
36
+ marketIndex: 0,
37
+ clientOrderIndex: 123,
38
+ baseAmount: 1000,
39
+ price: 4500,
40
+ isAsk: true,
41
+ orderType: SignerClient.ORDER_TYPE_MARKET,
42
+ timeInForce: SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
43
+ reduceOnly: false,
44
+ triggerPrice: 0,
45
+ });
46
+
47
+ console.log('Create Order:', { tx, txHash, err: createErr });
48
+ if (createErr) {
49
+ throw new Error(createErr);
50
+ }
51
+
52
+ const [auth, authErr] = await client.createAuthTokenWithExpiry(SignerClient.DEFAULT_10_MIN_AUTH_EXPIRY);
53
+ console.log('Auth token:', auth);
54
+ if (authErr) {
55
+ throw new Error(authErr);
56
+ }
57
+
58
+ // Cancel order
59
+ const [cancelTx, cancelTxHash, cancelErr] = await client.cancelOrder({
60
+ marketIndex: 0,
61
+ orderIndex: 123,
62
+ });
63
+
64
+ console.log('Cancel Order:', { tx: cancelTx, txHash: cancelTxHash, err: cancelErr });
65
+ if (cancelErr) {
66
+ throw new Error(cancelErr);
67
+ }
68
+
69
+ await client.close();
70
+ }
71
+
72
+ if (require.main === module) {
73
+ main().catch(console.error);
74
+ }
@@ -0,0 +1,42 @@
1
+ import { SignerClient } from '../src/signer/wasm-signer-client';
2
+ import * as dotenv from 'dotenv';
3
+
4
+ dotenv.config();
5
+
6
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
7
+ const API_KEY_PRIVATE_KEY = process.env['PRIVATE_KEY'];
8
+ const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '0', 10);
9
+ const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '0', 10);
10
+
11
+ async function main(): Promise<void> {
12
+ if (!API_KEY_PRIVATE_KEY) {
13
+ console.error('PRIVATE_KEY environment variable is required');
14
+ return;
15
+ }
16
+
17
+ const client = new SignerClient({
18
+ url: BASE_URL,
19
+ privateKey: API_KEY_PRIVATE_KEY,
20
+ accountIndex: ACCOUNT_INDEX,
21
+ apiKeyIndex: API_KEY_INDEX,
22
+ wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
23
+ });
24
+
25
+ await client.initialize();
26
+ await (client as any).ensureWasmClient();
27
+
28
+ const [tx, txHash, err] = await client.createMarketOrder({
29
+ marketIndex: 0,
30
+ clientOrderIndex: Date.now(),
31
+ baseAmount: 10,
32
+ avgExecutionPrice: 4500,
33
+ isAsk: true,
34
+ });
35
+
36
+ console.log('Create Market Order:', { tx, txHash, err });
37
+ await client.close();
38
+ }
39
+
40
+ if (require.main === module) {
41
+ main().catch(console.error);
42
+ }
@@ -0,0 +1,43 @@
1
+ import { SignerClient } from '../src/signer/wasm-signer-client';
2
+ import * as dotenv from 'dotenv';
3
+
4
+ dotenv.config();
5
+
6
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
7
+ const API_KEY_PRIVATE_KEY = process.env['PRIVATE_KEY'];
8
+ const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '0', 10);
9
+ const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '0', 10);
10
+
11
+ async function main(): Promise<void> {
12
+ if (!API_KEY_PRIVATE_KEY) {
13
+ console.error('PRIVATE_KEY environment variable is required');
14
+ return;
15
+ }
16
+
17
+ const client = new SignerClient({
18
+ url: BASE_URL,
19
+ privateKey: API_KEY_PRIVATE_KEY,
20
+ accountIndex: ACCOUNT_INDEX,
21
+ apiKeyIndex: API_KEY_INDEX,
22
+ wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
23
+ });
24
+
25
+ await client.initialize();
26
+ await (client as any).ensureWasmClient();
27
+
28
+ // Create market order with price limit (similar to max slippage)
29
+ const [tx, txHash, err] = await client.createMarketOrder({
30
+ marketIndex: 0,
31
+ clientOrderIndex: Date.now(),
32
+ baseAmount: 30000000,
33
+ avgExecutionPrice: 300000, // This acts as a price limit
34
+ isAsk: true,
35
+ });
36
+
37
+ console.log('Create Market Order with Price Limit:', { tx, txHash, err });
38
+ await client.close();
39
+ }
40
+
41
+ if (require.main === module) {
42
+ main().catch(console.error);
43
+ }
@@ -0,0 +1,61 @@
1
+ import { SignerClient } from '../src/signer/wasm-signer-client';
2
+ import * as dotenv from 'dotenv';
3
+
4
+ dotenv.config();
5
+
6
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
7
+ const API_KEY_PRIVATE_KEY = process.env['PRIVATE_KEY'];
8
+ const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '0', 10);
9
+ const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '0', 10);
10
+
11
+ async function main(): Promise<void> {
12
+ if (!API_KEY_PRIVATE_KEY) {
13
+ console.error('API_KEY_PRIVATE_KEY environment variable is required');
14
+ return;
15
+ }
16
+
17
+ const client = new SignerClient({
18
+ url: BASE_URL,
19
+ privateKey: API_KEY_PRIVATE_KEY,
20
+ accountIndex: ACCOUNT_INDEX,
21
+ apiKeyIndex: API_KEY_INDEX,
22
+ wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
23
+ });
24
+
25
+ await client.initialize();
26
+ await (client as any).ensureWasmClient();
27
+
28
+ // Create Take Profit order (using limit order with trigger price)
29
+ const [tpTx, tpTxHash, tpErr] = await client.createOrder({
30
+ marketIndex: 0,
31
+ clientOrderIndex: Date.now(),
32
+ baseAmount: 1000,
33
+ price: 500000,
34
+ isAsk: false,
35
+ orderType: SignerClient.ORDER_TYPE_LIMIT,
36
+ timeInForce: SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
37
+ reduceOnly: false,
38
+ triggerPrice: 500000,
39
+ });
40
+ console.log('Create TP Order:', { tx: tpTx, txHash: tpTxHash, err: tpErr });
41
+
42
+ // Create Stop Loss order (using limit order with trigger price)
43
+ const [slTx, slTxHash, slErr] = await client.createOrder({
44
+ marketIndex: 0,
45
+ clientOrderIndex: Date.now() + 1,
46
+ baseAmount: 1000,
47
+ price: 500000,
48
+ isAsk: false,
49
+ orderType: SignerClient.ORDER_TYPE_LIMIT,
50
+ timeInForce: SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
51
+ reduceOnly: false,
52
+ triggerPrice: 500000,
53
+ });
54
+ console.log('Create SL Order:', { tx: slTx, txHash: slTxHash, err: slErr });
55
+
56
+ await client.close();
57
+ }
58
+
59
+ if (require.main === module) {
60
+ main().catch(console.error);
61
+ }
@@ -0,0 +1,58 @@
1
+ import { SignerClient } from '../src/signer/wasm-signer-client';
2
+ import * as dotenv from 'dotenv';
3
+
4
+ dotenv.config();
5
+
6
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
7
+ const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '0', 10);
8
+
9
+ // Use examples/system_setup.ts or the apikeys page (for mainnet) to generate new api keys
10
+ const KEYS: Record<number, string> = {
11
+ 5: process.env['API_PRIVATE_KEY_5'] || '',
12
+ 6: process.env['API_PRIVATE_KEY_6'] || '',
13
+ 7: process.env['API_PRIVATE_KEY_7'] || '',
14
+ };
15
+
16
+ async function main(): Promise<void> {
17
+ const client = new SignerClient({
18
+ url: BASE_URL,
19
+ privateKey: KEYS[5],
20
+ accountIndex: ACCOUNT_INDEX,
21
+ apiKeyIndex: 5,
22
+ wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
23
+ });
24
+
25
+ await client.initialize();
26
+ await (client as any).ensureWasmClient();
27
+
28
+ const err = client.checkClient();
29
+ if (err) {
30
+ console.error('CheckClient error:', err);
31
+ return;
32
+ }
33
+
34
+ for (let i = 0; i < 5; i++) { // Reduced from 20 to 5 for demo
35
+ const [tx, txHash, createErr] = await client.createOrder({
36
+ marketIndex: 0,
37
+ clientOrderIndex: 123 + i,
38
+ baseAmount: 100000 + i,
39
+ price: 385000 + i,
40
+ isAsk: true,
41
+ orderType: SignerClient.ORDER_TYPE_LIMIT,
42
+ timeInForce: SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
43
+ reduceOnly: false,
44
+ triggerPrice: 0,
45
+ });
46
+ console.log({ tx, txHash, err: createErr });
47
+ }
48
+
49
+ const [cancelTx, cancelTxHash] = await client.cancelAllOrders(
50
+ SignerClient.CANCEL_ALL_TIF_IMMEDIATE,
51
+ Date.now()
52
+ );
53
+ console.log('Cancel All Orders:', { tx: cancelTx, txHash: cancelTxHash });
54
+ }
55
+
56
+ if (require.main === module) {
57
+ main().catch(console.error);
58
+ }
@@ -0,0 +1,58 @@
1
+ import { ApiClient } from '../src/api/api-client';
2
+ import { AccountApi } from '../src/api/account-api';
3
+ import { BlockApi } from '../src/api/block-api';
4
+ import { OrderApi } from '../src/api/order-api';
5
+ import { TransactionApi } from '../src/api/transaction-api';
6
+ import * as dotenv from 'dotenv';
7
+
8
+ dotenv.config();
9
+
10
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
11
+ const L1_ADDRESS = process.env['L1_ADDRESS'] || '0x8D7f03FdE1A626223364E592740a233b72395235';
12
+ const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '65', 10);
13
+
14
+ async function printApi(method: any, ...args: any[]): Promise<void> {
15
+ try {
16
+ const result = await method(...args);
17
+ console.log(`${method.name}:`, result);
18
+ } catch (error: any) {
19
+ console.log(`${method.name}: Error -`, error.message);
20
+ }
21
+ }
22
+
23
+ async function main(): Promise<void> {
24
+ const client = new ApiClient({ host: BASE_URL });
25
+
26
+ console.log('=== ACCOUNT APIS ===');
27
+ const accountApi = new AccountApi(client);
28
+ await printApi(accountApi.getAccount.bind(accountApi), 'l1_address', L1_ADDRESS);
29
+ await printApi(accountApi.getAccount.bind(accountApi), 'index', ACCOUNT_INDEX.toString());
30
+ await printApi(accountApi.getAccountsByL1Address.bind(accountApi), L1_ADDRESS);
31
+ await printApi(accountApi.getApiKeys.bind(accountApi), ACCOUNT_INDEX, 1);
32
+ await printApi(accountApi.getPublicPools.bind(accountApi), 'all', 1, 0);
33
+
34
+ console.log('\n=== BLOCK APIS ===');
35
+ const blockApi = new BlockApi(client);
36
+ await printApi(blockApi.getBlock.bind(blockApi), 'height', '1');
37
+ await printApi(blockApi.getBlocks.bind(blockApi), 0, 2, 'asc');
38
+ await printApi(blockApi.getCurrentHeight.bind(blockApi));
39
+
40
+ console.log('\n=== ORDER APIS ===');
41
+ const orderApi = new OrderApi(client);
42
+ await printApi(orderApi.getExchangeStats.bind(orderApi));
43
+ await printApi(orderApi.getOrderBookDetails.bind(orderApi), { marketIndex: 0 });
44
+ await printApi(orderApi.getOrderBooks.bind(orderApi));
45
+ await printApi(orderApi.getRecentTrades.bind(orderApi), { marketIndex: 0, limit: 2 });
46
+
47
+ console.log('\n=== TRANSACTION APIS ===');
48
+ const transactionApi = new TransactionApi(client);
49
+ await printApi(transactionApi.getBlockTransactions.bind(transactionApi), { by: 'block_height', value: '1' });
50
+ await printApi(transactionApi.getNextNonce.bind(transactionApi), ACCOUNT_INDEX, 0);
51
+ await printApi(transactionApi.getTransactions.bind(transactionApi), { limit: 2 });
52
+
53
+ await client.close();
54
+ }
55
+
56
+ if (require.main === module) {
57
+ main().catch(console.error);
58
+ }
@@ -0,0 +1,87 @@
1
+ import { SignerClient } from '../src/signer/wasm-signer-client';
2
+ import { TransactionApi } from '../src/api/transaction-api';
3
+ import { ApiClient } from '../src/api/api-client';
4
+ import * as dotenv from 'dotenv';
5
+
6
+ dotenv.config();
7
+
8
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
9
+ const API_KEY_PRIVATE_KEY = process.env['PRIVATE_KEY'];
10
+ const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '0', 10);
11
+ const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '0', 10);
12
+
13
+ async function main(): Promise<void> {
14
+ if (!API_KEY_PRIVATE_KEY) {
15
+ console.error('PRIVATE_KEY environment variable is required');
16
+ return;
17
+ }
18
+
19
+ const apiClient = new ApiClient({ host: BASE_URL });
20
+ const transactionApi = new TransactionApi(apiClient);
21
+ const client = new SignerClient({
22
+ url: BASE_URL,
23
+ privateKey: API_KEY_PRIVATE_KEY,
24
+ accountIndex: ACCOUNT_INDEX,
25
+ apiKeyIndex: API_KEY_INDEX,
26
+ wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
27
+ });
28
+
29
+ await client.initialize();
30
+ await (client as any).ensureWasmClient();
31
+
32
+ const err = client.checkClient();
33
+ if (err) {
34
+ console.error('CheckClient error:', err);
35
+ return;
36
+ }
37
+
38
+ // Get next nonce
39
+ const nextNonce = await transactionApi.getNextNonce(ACCOUNT_INDEX, API_KEY_INDEX);
40
+ let nonceValue = nextNonce.nonce;
41
+
42
+ // Sign first order
43
+ const askTxInfo = await (client as any).wallet.signCreateOrder({
44
+ marketIndex: 0,
45
+ clientOrderIndex: 1001,
46
+ baseAmount: 100000,
47
+ price: 280000,
48
+ isAsk: 1,
49
+ orderType: SignerClient.ORDER_TYPE_LIMIT,
50
+ timeInForce: SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
51
+ reduceOnly: 0,
52
+ triggerPrice: 0,
53
+ nonce: nonceValue++
54
+ });
55
+
56
+ // Sign second order
57
+ const bidTxInfo = await (client as any).wallet.signCreateOrder({
58
+ marketIndex: 0,
59
+ clientOrderIndex: 1002,
60
+ baseAmount: 200000,
61
+ price: 200000,
62
+ isAsk: 0,
63
+ orderType: SignerClient.ORDER_TYPE_LIMIT,
64
+ timeInForce: SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
65
+ reduceOnly: 0,
66
+ triggerPrice: 0,
67
+ nonce: nonceValue++
68
+ });
69
+
70
+ try {
71
+ const txHashes = await transactionApi.sendTransactionBatch({
72
+ account_index: ACCOUNT_INDEX,
73
+ api_key_index: API_KEY_INDEX,
74
+ transactions: [askTxInfo, bidTxInfo]
75
+ });
76
+ console.log('Batch transaction successful:', txHashes);
77
+ } catch (error: any) {
78
+ console.error('Error sending batch transaction:', error.message);
79
+ }
80
+
81
+ await client.close();
82
+ await apiClient.close();
83
+ }
84
+
85
+ if (require.main === module) {
86
+ main().catch(console.error);
87
+ }
@@ -0,0 +1,96 @@
1
+ import { SignerClient } from '../src/signer/wasm-signer-client';
2
+ import { ApiClient } from '../src/api/api-client';
3
+ import { AccountApi } from '../src/api/account-api';
4
+ import * as dotenv from 'dotenv';
5
+ import { ethers } from 'ethers';
6
+
7
+ dotenv.config();
8
+
9
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
10
+ const ETH_PRIVATE_KEY = process.env['ETH_PRIVATE_KEY'] || '1234567812345678123456781234567812345678123456781234567812345678';
11
+ const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '3', 10);
12
+
13
+ async function main(): Promise<void> {
14
+ // Verify that the account exists & fetch account index
15
+ const apiClient = new ApiClient({ host: BASE_URL });
16
+ const wallet = new ethers.Wallet(ETH_PRIVATE_KEY);
17
+ const ethAddress = wallet.address;
18
+
19
+ try {
20
+ const accountApi = new AccountApi(apiClient);
21
+ const response = await accountApi.getAccountsByL1Address(ethAddress);
22
+
23
+ let accountIndex: number;
24
+ if (response && response.length > 1) {
25
+ for (const account of response) {
26
+ console.log(`Found accountIndex: ${account.index}`);
27
+ }
28
+ console.log('Multiple accounts found, using the first one');
29
+ accountIndex = parseInt(response[0]!.index, 10);
30
+ } else if (response && response.length === 1) {
31
+ accountIndex = parseInt(response[0]!.index, 10);
32
+ } else {
33
+ throw new Error('No accounts found for this L1 address');
34
+ }
35
+
36
+ // Create a SignerClient first
37
+ const txClient = new SignerClient({
38
+ url: BASE_URL,
39
+ privateKey: ETH_PRIVATE_KEY,
40
+ accountIndex: accountIndex,
41
+ apiKeyIndex: API_KEY_INDEX,
42
+ wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
43
+ });
44
+
45
+ await txClient.initialize();
46
+ await (txClient as any).ensureWasmClient();
47
+
48
+ // Create a private/public key pair for the new API key
49
+ const apiKeyResult = await txClient.generateAPIKey();
50
+ if (!apiKeyResult) {
51
+ throw new Error('Failed to generate API key');
52
+ }
53
+ const { privateKey, publicKey } = apiKeyResult;
54
+
55
+ // Change the API key
56
+ const [, err] = await txClient.changeApiKey({
57
+ ethPrivateKey: ETH_PRIVATE_KEY,
58
+ newPubkey: publicKey,
59
+ });
60
+
61
+ if (err) {
62
+ throw new Error(err);
63
+ }
64
+
65
+ // Wait some time so that we receive the new API key in the response
66
+ await new Promise(resolve => setTimeout(resolve, 10000));
67
+
68
+ // Check that the API key changed on the server
69
+ const checkErr = txClient.checkClient();
70
+ if (checkErr) {
71
+ throw new Error(checkErr);
72
+ }
73
+
74
+ console.log(`
75
+ BASE_URL = '${BASE_URL}'
76
+ API_KEY_PRIVATE_KEY = '${privateKey}'
77
+ ACCOUNT_INDEX = ${accountIndex}
78
+ API_KEY_INDEX = ${API_KEY_INDEX}
79
+ `);
80
+
81
+ await txClient.close();
82
+ await apiClient.close();
83
+
84
+ } catch (error: any) {
85
+ if (error.message === 'account not found') {
86
+ console.error(`Error: account not found for ${ethAddress}`);
87
+ return;
88
+ } else {
89
+ throw error;
90
+ }
91
+ }
92
+ }
93
+
94
+ if (require.main === module) {
95
+ main().catch(console.error);
96
+ }
@@ -0,0 +1,53 @@
1
+ import { SignerClient } from '../src/signer/wasm-signer-client';
2
+ import { ApiClient } from '../src/api/api-client';
3
+ import * as dotenv from 'dotenv';
4
+
5
+ dotenv.config();
6
+
7
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
8
+ const API_KEY_PRIVATE_KEY = process.env['PRIVATE_KEY'];
9
+ const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '10', 10);
10
+ const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '10', 10);
11
+
12
+ async function main(): Promise<void> {
13
+ if (!API_KEY_PRIVATE_KEY) {
14
+ console.error('PRIVATE_KEY environment variable is required');
15
+ return;
16
+ }
17
+
18
+ const client = new SignerClient({
19
+ url: BASE_URL,
20
+ privateKey: API_KEY_PRIVATE_KEY,
21
+ accountIndex: ACCOUNT_INDEX,
22
+ apiKeyIndex: API_KEY_INDEX,
23
+ wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
24
+ });
25
+
26
+ const apiClient = new ApiClient({ host: BASE_URL });
27
+
28
+ await client.initialize();
29
+ await (client as any).ensureWasmClient();
30
+
31
+ const [authToken] = await client.createAuthTokenWithExpiry();
32
+ console.log('Auth token created:', authToken);
33
+
34
+ const err = client.checkClient();
35
+ if (err) {
36
+ console.error('CheckClient error:', err);
37
+ return;
38
+ }
39
+
40
+ const [levTx, levResponse, levErr] = await client.updateLeverage(4, SignerClient.CROSS_MARGIN_MODE, 3);
41
+ console.log('Update Leverage:', { tx: levTx, response: levResponse, err: levErr });
42
+
43
+ // Test transfer (requires proper fee calculation)
44
+ const [transferTx, transferResponse, transferErr] = await client.transfer(9, 100);
45
+ console.log('Transfer:', { tx: transferTx, response: transferResponse, err: transferErr });
46
+
47
+ await client.close();
48
+ await apiClient.close();
49
+ }
50
+
51
+ if (require.main === module) {
52
+ main().catch(console.error);
53
+ }
package/examples/ws.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { WsClient } from '../src/api/ws-client';
2
+ import * as dotenv from 'dotenv';
3
+
4
+ dotenv.config();
5
+
6
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
7
+
8
+ function onOrderBookUpdate(marketId: number, orderBook: any): void {
9
+ console.log(`Order book ${marketId}:`, JSON.stringify(orderBook, null, 2));
10
+ }
11
+
12
+ function onAccountUpdate(accountId: number, account: any): void {
13
+ console.log(`Account ${accountId}:`, JSON.stringify(account, null, 2));
14
+ }
15
+
16
+ const client = new WsClient({
17
+ url: BASE_URL,
18
+ orderBookIds: [0, 1],
19
+ accountIds: [1, 2],
20
+ onOrderBookUpdate,
21
+ onAccountUpdate,
22
+ });
23
+
24
+ client.run();
@@ -0,0 +1,39 @@
1
+ import { WsClient } from '../src/api/ws-client';
2
+ import * as dotenv from 'dotenv';
3
+
4
+ dotenv.config();
5
+
6
+ const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
7
+
8
+ function onOrderBookUpdate(marketId: number, orderBook: any): void {
9
+ console.log(`Order book ${marketId}:`, JSON.stringify(orderBook, null, 2));
10
+ }
11
+
12
+ function onAccountUpdate(accountId: number, account: any): void {
13
+ console.log(`Account ${accountId}:`, JSON.stringify(account, null, 2));
14
+ }
15
+
16
+ async function main() {
17
+ const client = new WsClient({
18
+ url: BASE_URL,
19
+ onOpen: () => console.log('WebSocket connected'),
20
+ onMessage: (message) => {
21
+ console.log('Received message:', message);
22
+ // Handle different message types here
23
+ },
24
+ onClose: () => console.log('WebSocket closed'),
25
+ onError: (error) => console.error('WebSocket error:', error)
26
+ });
27
+
28
+ await client.connect();
29
+
30
+ // Subscribe to order book updates
31
+ client.subscribe({ channel: 'orderbook', params: { market_id: 0 } });
32
+ client.subscribe({ channel: 'orderbook', params: { market_id: 1 } });
33
+
34
+ // Subscribe to account updates
35
+ client.subscribe({ channel: 'account', params: { account_index: 1 } });
36
+ client.subscribe({ channel: 'account', params: { account_index: 2 } });
37
+ }
38
+
39
+ main().catch(console.error);