lighter-ts-sdk 1.0.0 → 1.0.2
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/README.md +62 -49
- package/dist/api/transaction-api.d.ts +5 -1
- package/dist/api/transaction-api.d.ts.map +1 -1
- package/dist/api/transaction-api.js.map +1 -1
- package/dist/api/ws-order-client.d.ts +82 -0
- package/dist/api/ws-order-client.d.ts.map +1 -0
- package/dist/api/ws-order-client.js +281 -0
- package/dist/api/ws-order-client.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/signer/signer-client.d.ts.map +1 -1
- package/dist/signer/signer-client.js +5 -3
- package/dist/signer/signer-client.js.map +1 -1
- package/dist/signer/wasm-signer-client.d.ts +104 -10
- package/dist/signer/wasm-signer-client.d.ts.map +1 -1
- package/dist/signer/wasm-signer-client.js +643 -356
- package/dist/signer/wasm-signer-client.js.map +1 -1
- package/dist/utils/advanced-cache.d.ts +66 -0
- package/dist/utils/advanced-cache.d.ts.map +1 -0
- package/dist/utils/advanced-cache.js +204 -0
- package/dist/utils/advanced-cache.js.map +1 -0
- package/dist/utils/exceptions.d.ts +24 -0
- package/dist/utils/exceptions.d.ts.map +1 -1
- package/dist/utils/exceptions.js +48 -1
- package/dist/utils/exceptions.js.map +1 -1
- package/dist/utils/logger.d.ts +35 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +96 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/memory-pool.d.ts +98 -0
- package/dist/utils/memory-pool.d.ts.map +1 -0
- package/dist/utils/memory-pool.js +190 -0
- package/dist/utils/memory-pool.js.map +1 -0
- package/dist/utils/node-wasm-signer.d.ts +8 -0
- package/dist/utils/node-wasm-signer.d.ts.map +1 -1
- package/dist/utils/node-wasm-signer.js +84 -29
- package/dist/utils/node-wasm-signer.js.map +1 -1
- package/dist/utils/nonce-cache.d.ts +29 -0
- package/dist/utils/nonce-cache.d.ts.map +1 -0
- package/dist/utils/nonce-cache.js +111 -0
- package/dist/utils/nonce-cache.js.map +1 -0
- package/dist/utils/optimized-http-client.d.ts +29 -0
- package/dist/utils/optimized-http-client.d.ts.map +1 -0
- package/dist/utils/optimized-http-client.js +142 -0
- package/dist/utils/optimized-http-client.js.map +1 -0
- package/dist/utils/performance-monitor.d.ts +41 -0
- package/dist/utils/performance-monitor.d.ts.map +1 -0
- package/dist/utils/performance-monitor.js +183 -0
- package/dist/utils/performance-monitor.js.map +1 -0
- package/dist/utils/request-batcher.d.ts +45 -0
- package/dist/utils/request-batcher.d.ts.map +1 -0
- package/dist/utils/request-batcher.js +177 -0
- package/dist/utils/request-batcher.js.map +1 -0
- package/dist/utils/wasm-manager.d.ts +30 -0
- package/dist/utils/wasm-manager.d.ts.map +1 -0
- package/dist/utils/wasm-manager.js +115 -0
- package/dist/utils/wasm-manager.js.map +1 -0
- package/docs/AccountApi.md +1 -1
- package/docs/GettingStarted.md +8 -8
- package/docs/OrderApi.md +1 -1
- package/docs/SignerClient.md +1 -1
- package/docs/TransactionApi.md +1 -1
- package/docs/WsClient.md +1 -1
- package/docs/types/Account.md +1 -1
- package/docs/types/ApiKeyPair.md +1 -1
- package/docs/types/CreateOrderParams.md +1 -1
- package/docs/types/MarketOrderParams.md +1 -1
- package/docs/types/SignerConfig.md +1 -1
- package/docs/types/WasmSignerConfig.md +1 -1
- package/examples/README.md +1 -1
- package/examples/account_info.ts +5 -2
- package/examples/cancel_all_orders.ts +77 -0
- package/examples/close_all_positions.ts +69 -0
- package/examples/create_cancel_order.ts +48 -8
- package/examples/create_market_order.ts +42 -1
- package/examples/create_market_order_if_slippage.ts +69 -0
- package/examples/create_market_order_max_slippage.ts +43 -43
- package/examples/create_sl_tp.ts +114 -29
- package/examples/create_with_multiple_keys.ts +77 -58
- package/examples/get_info.ts +1 -1
- package/examples/market_data_json.ts +80 -0
- package/examples/wait_for_transaction.ts +101 -0
- package/examples/ws.ts +64 -24
- package/examples/ws_async.ts +40 -39
- package/package.json +70 -70
- package/dist/utils/signer.d.ts +0 -15
- package/dist/utils/signer.d.ts.map +0 -1
- package/dist/utils/signer.js +0 -68
- package/dist/utils/signer.js.map +0 -1
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Close all positions by creating opposite market orders
|
|
2
|
+
// This example shows how to close all open positions
|
|
3
|
+
|
|
4
|
+
import { SignerClient } from '../src/signer/wasm-signer-client';
|
|
5
|
+
import * as dotenv from 'dotenv';
|
|
6
|
+
|
|
7
|
+
dotenv.config();
|
|
8
|
+
|
|
9
|
+
const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
|
|
10
|
+
const API_KEY_PRIVATE_KEY = process.env['API_PRIVATE_KEY'];
|
|
11
|
+
const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '0', 10);
|
|
12
|
+
const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '0', 10);
|
|
13
|
+
|
|
14
|
+
async function main(): Promise<void> {
|
|
15
|
+
if (!API_KEY_PRIVATE_KEY) {
|
|
16
|
+
console.error('API_PRIVATE_KEY environment variable is required');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const client = new SignerClient({
|
|
21
|
+
url: BASE_URL,
|
|
22
|
+
privateKey: API_KEY_PRIVATE_KEY,
|
|
23
|
+
accountIndex: ACCOUNT_INDEX,
|
|
24
|
+
apiKeyIndex: API_KEY_INDEX,
|
|
25
|
+
wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
await client.initialize();
|
|
29
|
+
await (client as any).ensureWasmClient();
|
|
30
|
+
|
|
31
|
+
const err = client.checkClient();
|
|
32
|
+
if (err) {
|
|
33
|
+
console.error('CheckClient error:', err);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log('🔄 Closing all positions...');
|
|
38
|
+
|
|
39
|
+
// Close all positions
|
|
40
|
+
const [closedTransactions, , errors] = await client.closeAllPositions();
|
|
41
|
+
|
|
42
|
+
console.log('\n📊 Results:');
|
|
43
|
+
console.log(` Positions closed: ${closedTransactions.length}`);
|
|
44
|
+
console.log(` Errors: ${errors.length}`);
|
|
45
|
+
|
|
46
|
+
if (errors.length > 0) {
|
|
47
|
+
console.log('\n❌ Errors encountered:');
|
|
48
|
+
errors.forEach((error, index) => {
|
|
49
|
+
console.log(` ${index + 1}. ${error}`);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (closedTransactions.length > 0) {
|
|
54
|
+
console.log('\n✅ Successfully closed positions:');
|
|
55
|
+
closedTransactions.forEach((tx, index) => {
|
|
56
|
+
console.log(` ${index + 1}. Market ${tx.MarketIndex}: ${tx.IsAsk ? 'Sell' : 'Buy'} ${tx.BaseAmount} units`);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (closedTransactions.length === 0 && errors.length === 0) {
|
|
61
|
+
console.log('ℹ️ No open positions found to close.');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
await client.close();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (require.main === module) {
|
|
68
|
+
main().catch(console.error);
|
|
69
|
+
}
|
|
@@ -36,9 +36,9 @@ async function main(): Promise<void> {
|
|
|
36
36
|
marketIndex: 0,
|
|
37
37
|
clientOrderIndex: 123,
|
|
38
38
|
baseAmount: 1000,
|
|
39
|
-
price:
|
|
39
|
+
price: 450000,
|
|
40
40
|
isAsk: true,
|
|
41
|
-
orderType: SignerClient.
|
|
41
|
+
orderType: SignerClient.ORDER_TYPE_LIMIT,
|
|
42
42
|
timeInForce: SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
|
43
43
|
reduceOnly: false,
|
|
44
44
|
triggerPrice: 0,
|
|
@@ -49,10 +49,31 @@ async function main(): Promise<void> {
|
|
|
49
49
|
throw new Error(createErr);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
console.log('
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
console.log('✅ Order created successfully!');
|
|
53
|
+
console.log('📋 Order Details:');
|
|
54
|
+
console.log(` Market Index: ${tx.MarketIndex}`);
|
|
55
|
+
console.log(` Client Order Index: ${tx.ClientOrderIndex}`);
|
|
56
|
+
console.log(` Base Amount: ${tx.BaseAmount}`);
|
|
57
|
+
console.log(` Price: ${tx.Price}`);
|
|
58
|
+
console.log(` Is Ask: ${tx.IsAsk ? 'Yes (Sell)' : 'No (Buy)'}`);
|
|
59
|
+
console.log(` Order Type: ${tx.Type === 0 ? 'Limit' : 'Market'}`);
|
|
60
|
+
console.log(` Time In Force: ${tx.TimeInForce === 1 ? 'Good Till Time' : 'Immediate or Cancel'}`);
|
|
61
|
+
console.log(` Nonce: ${tx.Nonce}`);
|
|
62
|
+
|
|
63
|
+
// Wait for transaction confirmation if txHash is available
|
|
64
|
+
if (txHash) {
|
|
65
|
+
console.log('\n⏳ Waiting for transaction confirmation...');
|
|
66
|
+
try {
|
|
67
|
+
const confirmedTx = await client.waitForTransaction(txHash, 30000, 1000);
|
|
68
|
+
console.log('✅ Transaction confirmed!');
|
|
69
|
+
console.log(` Hash: ${confirmedTx.hash}`);
|
|
70
|
+
console.log(` Status: ${confirmedTx.status}`);
|
|
71
|
+
console.log(` Block Height: ${confirmedTx.block_height}`);
|
|
72
|
+
} catch (waitError) {
|
|
73
|
+
console.log('⚠️ Transaction confirmation timeout or failed:', waitError instanceof Error ? waitError.message : 'Unknown error');
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
console.log('⚠️ No transaction hash available for confirmation');
|
|
56
77
|
}
|
|
57
78
|
|
|
58
79
|
// Cancel order
|
|
@@ -61,9 +82,28 @@ async function main(): Promise<void> {
|
|
|
61
82
|
orderIndex: 123,
|
|
62
83
|
});
|
|
63
84
|
|
|
64
|
-
console.log('
|
|
85
|
+
console.log('\nCancel Order:', { tx: cancelTx, txHash: cancelTxHash, err: cancelErr });
|
|
65
86
|
if (cancelErr) {
|
|
66
|
-
|
|
87
|
+
console.log('❌ Cancel order error:', cancelErr);
|
|
88
|
+
} else {
|
|
89
|
+
console.log('✅ Order cancelled successfully!');
|
|
90
|
+
console.log('📋 Cancel Order Details:');
|
|
91
|
+
console.log(` Market Index: ${cancelTx.MarketIndex}`);
|
|
92
|
+
console.log(` Order Index: ${cancelTx.OrderIndex}`);
|
|
93
|
+
console.log(` Nonce: ${cancelTx.Nonce}`);
|
|
94
|
+
|
|
95
|
+
// Wait for cancellation transaction confirmation if txHash is available
|
|
96
|
+
if (cancelTxHash) {
|
|
97
|
+
console.log('\n⏳ Waiting for cancellation transaction confirmation...');
|
|
98
|
+
try {
|
|
99
|
+
const confirmedCancelTx = await client.waitForTransaction(cancelTxHash, 30000, 1000);
|
|
100
|
+
console.log('✅ Cancellation transaction confirmed!');
|
|
101
|
+
console.log(` Hash: ${confirmedCancelTx.hash}`);
|
|
102
|
+
console.log(` Status: ${confirmedCancelTx.status}`);
|
|
103
|
+
} catch (waitError) {
|
|
104
|
+
console.log('⚠️ Cancellation transaction confirmation timeout:', waitError instanceof Error ? waitError.message : 'Unknown error');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
67
107
|
}
|
|
68
108
|
|
|
69
109
|
await client.close();
|
|
@@ -29,11 +29,52 @@ async function main(): Promise<void> {
|
|
|
29
29
|
marketIndex: 0,
|
|
30
30
|
clientOrderIndex: Date.now(),
|
|
31
31
|
baseAmount: 10,
|
|
32
|
-
avgExecutionPrice: 4500,
|
|
32
|
+
avgExecutionPrice: 4500,
|
|
33
33
|
isAsk: true,
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
console.log('Create Market Order:', { tx, txHash, err });
|
|
37
|
+
if (err) {
|
|
38
|
+
console.error('❌ Market order failed:', err);
|
|
39
|
+
} else {
|
|
40
|
+
console.log('✅ Market order created successfully!');
|
|
41
|
+
console.log('📋 Order Details:');
|
|
42
|
+
console.log(` Market Index: ${tx.MarketIndex}`);
|
|
43
|
+
console.log(` Client Order Index: ${tx.ClientOrderIndex}`);
|
|
44
|
+
console.log(` Base Amount: ${tx.BaseAmount}`);
|
|
45
|
+
console.log(` Price: ${tx.Price}`);
|
|
46
|
+
console.log(` Is Ask: ${tx.IsAsk ? 'Yes (Sell)' : 'No (Buy)'}`);
|
|
47
|
+
console.log(` Order Type: ${tx.Type === 0 ? 'Limit' : 'Market'}`);
|
|
48
|
+
console.log(` Nonce: ${tx.Nonce}`);
|
|
49
|
+
|
|
50
|
+
// Wait for transaction confirmation if txHash is available
|
|
51
|
+
if (txHash) {
|
|
52
|
+
console.log('\n⏳ Waiting for transaction confirmation...');
|
|
53
|
+
try {
|
|
54
|
+
const confirmedTx = await client.waitForTransaction(txHash, 30000, 1000);
|
|
55
|
+
console.log('✅ Transaction confirmed!');
|
|
56
|
+
console.log(` Hash: ${confirmedTx.hash}`);
|
|
57
|
+
console.log(` Status: ${confirmedTx.status}`);
|
|
58
|
+
console.log(` Block Height: ${confirmedTx.block_height}`);
|
|
59
|
+
} catch (waitError) {
|
|
60
|
+
console.log('⚠️ Transaction confirmation failed:', waitError instanceof Error ? waitError.message : 'Unknown error');
|
|
61
|
+
|
|
62
|
+
// Check if it's a timeout or actual failure
|
|
63
|
+
if (waitError instanceof Error) {
|
|
64
|
+
if (waitError.message.includes('did not confirm within')) {
|
|
65
|
+
console.log(' → This is a timeout - transaction may still be processing');
|
|
66
|
+
} else if (waitError.message.includes('failed with status')) {
|
|
67
|
+
console.log(' → This is a transaction failure - the order was rejected');
|
|
68
|
+
} else {
|
|
69
|
+
console.log(' → This is an API or network error');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
console.log('⚠️ No transaction hash available for confirmation');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
37
78
|
await client.close();
|
|
38
79
|
}
|
|
39
80
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Create market order only if slippage is acceptable
|
|
2
|
+
// This example shows how to create a market order that only executes if slippage is within limits
|
|
3
|
+
|
|
4
|
+
import { SignerClient } from '../src/signer/wasm-signer-client';
|
|
5
|
+
import * as dotenv from 'dotenv';
|
|
6
|
+
|
|
7
|
+
dotenv.config();
|
|
8
|
+
|
|
9
|
+
const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
|
|
10
|
+
const API_KEY_PRIVATE_KEY = process.env['PRIVATE_KEY'];
|
|
11
|
+
const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '0', 10);
|
|
12
|
+
const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '0', 10);
|
|
13
|
+
|
|
14
|
+
async function main(): Promise<void> {
|
|
15
|
+
if (!API_KEY_PRIVATE_KEY) {
|
|
16
|
+
console.error('PRIVATE_KEY environment variable is required');
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const client = new SignerClient({
|
|
21
|
+
url: BASE_URL,
|
|
22
|
+
privateKey: API_KEY_PRIVATE_KEY,
|
|
23
|
+
accountIndex: ACCOUNT_INDEX,
|
|
24
|
+
apiKeyIndex: API_KEY_INDEX,
|
|
25
|
+
wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
await client.initialize();
|
|
29
|
+
await (client as any).ensureWasmClient();
|
|
30
|
+
|
|
31
|
+
const err = client.checkClient();
|
|
32
|
+
if (err) {
|
|
33
|
+
console.error('CheckClient error:', err);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Create market order only if slippage is acceptable
|
|
38
|
+
const [tx, txHash, err_result] = await client.createMarketOrder_ifSlippage({
|
|
39
|
+
marketIndex: 0, // ETH market
|
|
40
|
+
clientOrderIndex: Date.now(),
|
|
41
|
+
baseAmount: 1000000, // 0.001 ETH (in wei scale)
|
|
42
|
+
maxSlippage: 0.005, // 0.5% max slippage (very strict)
|
|
43
|
+
isAsk: false, // Buy order
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
console.log('Create Market Order if Slippage Acceptable:', { tx, txHash, err: err_result });
|
|
47
|
+
|
|
48
|
+
if (err_result) {
|
|
49
|
+
console.log('❌ Order not created:', err_result);
|
|
50
|
+
} else {
|
|
51
|
+
console.log('✅ Order created successfully!');
|
|
52
|
+
console.log('📋 Order Details:');
|
|
53
|
+
console.log(` Market Index: ${tx.MarketIndex}`);
|
|
54
|
+
console.log(` Client Order Index: ${tx.ClientOrderIndex}`);
|
|
55
|
+
console.log(` Base Amount: ${tx.BaseAmount}`);
|
|
56
|
+
console.log(` Price: ${tx.Price}`);
|
|
57
|
+
console.log(` Is Ask: ${tx.IsAsk ? 'Yes (Sell)' : 'No (Buy)'}`);
|
|
58
|
+
console.log(` Order Type: ${tx.Type === 0 ? 'Limit' : 'Market'}`);
|
|
59
|
+
console.log(` Time In Force: ${tx.TimeInForce === 0 ? 'Immediate or Cancel' : 'Good Till Time'}`);
|
|
60
|
+
console.log(` Nonce: ${tx.Nonce}`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
await client.close();
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (require.main === module) {
|
|
67
|
+
main().catch(console.error);
|
|
68
|
+
}
|
|
69
|
+
|
|
@@ -1,43 +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
|
|
29
|
-
const [tx, txHash, err] = await client.
|
|
30
|
-
marketIndex: 0,
|
|
31
|
-
clientOrderIndex: Date.now(),
|
|
32
|
-
baseAmount:
|
|
33
|
-
|
|
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
|
-
}
|
|
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 maximum slippage limit
|
|
29
|
+
const [tx, txHash, err] = await client.createMarketOrder_maxSlippage({
|
|
30
|
+
marketIndex: 0,
|
|
31
|
+
clientOrderIndex: Date.now(),
|
|
32
|
+
baseAmount: 1000000, // 0.001 ETH (in wei scale)
|
|
33
|
+
maxSlippage: 0.01, // 1% max slippage
|
|
34
|
+
isAsk: true, // Sell order
|
|
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
|
+
}
|
package/examples/create_sl_tp.ts
CHANGED
|
@@ -4,13 +4,13 @@ import * as dotenv from 'dotenv';
|
|
|
4
4
|
dotenv.config();
|
|
5
5
|
|
|
6
6
|
const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
|
|
7
|
-
const API_KEY_PRIVATE_KEY = process.env['
|
|
7
|
+
const API_KEY_PRIVATE_KEY = process.env['API_PRIVATE_KEY'];
|
|
8
8
|
const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '0', 10);
|
|
9
9
|
const API_KEY_INDEX = parseInt(process.env['API_KEY_INDEX'] || '0', 10);
|
|
10
10
|
|
|
11
11
|
async function main(): Promise<void> {
|
|
12
12
|
if (!API_KEY_PRIVATE_KEY) {
|
|
13
|
-
console.error('
|
|
13
|
+
console.error('API_PRIVATE_KEY environment variable is required');
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -25,33 +25,118 @@ async function main(): Promise<void> {
|
|
|
25
25
|
await client.initialize();
|
|
26
26
|
await (client as any).ensureWasmClient();
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
28
|
+
console.log('🎯 Creating Take Profit and Stop Loss orders...\n');
|
|
29
|
+
|
|
30
|
+
// Example: Assume we have a long position and want to set TP/SL
|
|
31
|
+
const marketIndex = 0; // ETH/USDC
|
|
32
|
+
const baseAmount = 1000000; // 0.001 ETH
|
|
33
|
+
const takeProfitPrice = 420000000; // $4200 (5% profit)
|
|
34
|
+
const stopLossPrice = 380000000; // $3800 (5% loss)
|
|
35
|
+
const clientOrderIndex = Date.now();
|
|
36
|
+
|
|
37
|
+
// Create Take Profit Limit order
|
|
38
|
+
console.log('📈 Creating Take Profit Limit Order...');
|
|
39
|
+
const [tpTx, tpTxHash, tpErr] = await client.createTpLimitOrder(
|
|
40
|
+
marketIndex,
|
|
41
|
+
clientOrderIndex,
|
|
42
|
+
baseAmount,
|
|
43
|
+
takeProfitPrice, // trigger price
|
|
44
|
+
takeProfitPrice, // limit price
|
|
45
|
+
true, // isAsk = true (sell order to take profit on long position)
|
|
46
|
+
true // reduceOnly = true (closing position)
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
if (tpErr) {
|
|
50
|
+
console.error('❌ Take Profit order failed:', tpErr);
|
|
51
|
+
} else {
|
|
52
|
+
console.log('✅ Take Profit order created successfully!');
|
|
53
|
+
console.log(` Order Index: ${tpTx.ClientOrderIndex}`);
|
|
54
|
+
console.log(` Trigger Price: $${takeProfitPrice / 100000}`);
|
|
55
|
+
console.log(` Limit Price: $${takeProfitPrice / 100000}`);
|
|
56
|
+
console.log(` Amount: ${baseAmount} units`);
|
|
57
|
+
console.log(` TX Hash: ${tpTxHash}`);
|
|
58
|
+
|
|
59
|
+
// Wait for transaction confirmation if txHash is available
|
|
60
|
+
if (tpTxHash) {
|
|
61
|
+
console.log('⏳ Waiting for Take Profit transaction confirmation...');
|
|
62
|
+
try {
|
|
63
|
+
const confirmedTx = await client.waitForTransaction(tpTxHash, 30000, 1000);
|
|
64
|
+
console.log('✅ Take Profit transaction confirmed!');
|
|
65
|
+
console.log(` Hash: ${confirmedTx.hash}`);
|
|
66
|
+
console.log(` Status: ${confirmedTx.status}\n`);
|
|
67
|
+
} catch (waitError) {
|
|
68
|
+
console.log('⚠️ Take Profit transaction confirmation timeout:', waitError instanceof Error ? waitError.message : 'Unknown error\n');
|
|
69
|
+
}
|
|
70
|
+
} else {
|
|
71
|
+
console.log('⚠️ No transaction hash available for Take Profit confirmation\n');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Create Stop Loss order (market order) - Note: Currently has issues with expiry validation
|
|
76
|
+
console.log('🛡️ Creating Stop Loss Order...');
|
|
77
|
+
console.log('⚠️ Note: Stop Loss market orders currently have expiry validation issues');
|
|
78
|
+
console.log(' Consider using Stop Loss Limit orders instead for better reliability\n');
|
|
79
|
+
|
|
80
|
+
// Uncomment the following code when the Stop Loss market order issue is resolved:
|
|
81
|
+
/*
|
|
82
|
+
const [slTx, slTxHash, slErr] = await client.createSlOrder(
|
|
83
|
+
marketIndex,
|
|
84
|
+
clientOrderIndex + 1,
|
|
85
|
+
baseAmount,
|
|
86
|
+
stopLossPrice, // trigger price
|
|
87
|
+
0, // price = 0 for market order
|
|
88
|
+
true, // isAsk = true (sell order to stop loss on long position)
|
|
89
|
+
true // reduceOnly = true (closing position)
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (slErr) {
|
|
93
|
+
console.error('❌ Stop Loss order failed:', slErr);
|
|
94
|
+
} else {
|
|
95
|
+
console.log('✅ Stop Loss order created successfully!');
|
|
96
|
+
console.log(` Order Index: ${slTx.ClientOrderIndex}`);
|
|
97
|
+
console.log(` Trigger Price: $${stopLossPrice / 100000}`);
|
|
98
|
+
console.log(` Amount: ${baseAmount} units`);
|
|
99
|
+
console.log(` TX Hash: ${slTxHash}\n`);
|
|
100
|
+
}
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
// Create Stop Loss Limit order (alternative to market order)
|
|
104
|
+
console.log('🛡️ Creating Stop Loss Limit Order...');
|
|
105
|
+
const [slLimitTx, slLimitTxHash, slLimitErr] = await client.createSlLimitOrder(
|
|
106
|
+
marketIndex,
|
|
107
|
+
clientOrderIndex + 2,
|
|
108
|
+
baseAmount,
|
|
109
|
+
stopLossPrice, // trigger price
|
|
110
|
+
stopLossPrice - 1000000, // limit price (slightly below trigger)
|
|
111
|
+
true, // isAsk = true (sell order to stop loss on long position)
|
|
112
|
+
true // reduceOnly = true (closing position)
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
if (slLimitErr) {
|
|
116
|
+
console.error('❌ Stop Loss Limit order failed:', slLimitErr);
|
|
117
|
+
} else {
|
|
118
|
+
console.log('✅ Stop Loss Limit order created successfully!');
|
|
119
|
+
console.log(` Order Index: ${slLimitTx.ClientOrderIndex}`);
|
|
120
|
+
console.log(` Trigger Price: $${stopLossPrice / 100000}`);
|
|
121
|
+
console.log(` Limit Price: $${(stopLossPrice - 1000000) / 100000}`);
|
|
122
|
+
console.log(` Amount: ${baseAmount} units`);
|
|
123
|
+
console.log(` TX Hash: ${slLimitTxHash}`);
|
|
124
|
+
|
|
125
|
+
// Wait for transaction confirmation if txHash is available
|
|
126
|
+
if (slLimitTxHash) {
|
|
127
|
+
console.log('⏳ Waiting for Stop Loss Limit transaction confirmation...');
|
|
128
|
+
try {
|
|
129
|
+
const confirmedTx = await client.waitForTransaction(slLimitTxHash, 30000, 1000);
|
|
130
|
+
console.log('✅ Stop Loss Limit transaction confirmed!');
|
|
131
|
+
console.log(` Hash: ${confirmedTx.hash}`);
|
|
132
|
+
console.log(` Status: ${confirmedTx.status}\n`);
|
|
133
|
+
} catch (waitError) {
|
|
134
|
+
console.log('⚠️ Stop Loss Limit transaction confirmation timeout:', waitError instanceof Error ? waitError.message : 'Unknown error\n');
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
console.log('⚠️ No transaction hash available for Stop Loss Limit confirmation\n');
|
|
138
|
+
}
|
|
139
|
+
}
|
|
55
140
|
|
|
56
141
|
await client.close();
|
|
57
142
|
}
|
|
@@ -1,58 +1,77 @@
|
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
+
// Check if required keys are available
|
|
17
|
+
const requiredKey = KEYS[5];
|
|
18
|
+
if (!requiredKey) {
|
|
19
|
+
console.error('API_PRIVATE_KEY_5 environment variable is required');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function main(): Promise<void> {
|
|
24
|
+
const client = new SignerClient({
|
|
25
|
+
url: BASE_URL,
|
|
26
|
+
privateKey: requiredKey!,
|
|
27
|
+
accountIndex: ACCOUNT_INDEX,
|
|
28
|
+
apiKeyIndex: 5,
|
|
29
|
+
wasmConfig: { wasmPath: 'wasm/lighter-signer.wasm' }
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
await client.initialize();
|
|
33
|
+
await (client as any).ensureWasmClient();
|
|
34
|
+
|
|
35
|
+
const err = client.checkClient();
|
|
36
|
+
if (err) {
|
|
37
|
+
console.error('CheckClient error:', err);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
for (let i = 0; i < 5; i++) { // Reduced from 20 to 5 for demo
|
|
42
|
+
const [tx, txHash, createErr] = await client.createOrder({
|
|
43
|
+
marketIndex: 0,
|
|
44
|
+
clientOrderIndex: 123 + i,
|
|
45
|
+
baseAmount: 100000 + i,
|
|
46
|
+
price: 385000 + i,
|
|
47
|
+
isAsk: true,
|
|
48
|
+
orderType: SignerClient.ORDER_TYPE_LIMIT,
|
|
49
|
+
timeInForce: SignerClient.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
|
|
50
|
+
reduceOnly: false,
|
|
51
|
+
triggerPrice: 0,
|
|
52
|
+
});
|
|
53
|
+
console.log({ tx, txHash, err: createErr });
|
|
54
|
+
|
|
55
|
+
if (!createErr && txHash) {
|
|
56
|
+
console.log('⏳ Waiting for transaction confirmation...');
|
|
57
|
+
try {
|
|
58
|
+
const confirmedTx = await client.waitForTransaction(txHash, 30000, 1000);
|
|
59
|
+
console.log('✅ Transaction confirmed!');
|
|
60
|
+
console.log(` Hash: ${confirmedTx.hash}`);
|
|
61
|
+
console.log(` Status: ${confirmedTx.status}`);
|
|
62
|
+
} catch (waitError) {
|
|
63
|
+
console.log('⚠️ Transaction confirmation timeout:', waitError instanceof Error ? waitError.message : 'Unknown error');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const [cancelTx, cancelApiResponse, cancelErr] = await client.cancelAllOrders(
|
|
69
|
+
SignerClient.CANCEL_ALL_TIF_IMMEDIATE,
|
|
70
|
+
Date.now()
|
|
71
|
+
);
|
|
72
|
+
console.log('Cancel All Orders:', { tx: cancelTx, apiResponse: cancelApiResponse, err: cancelErr });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (require.main === module) {
|
|
76
|
+
main().catch(console.error);
|
|
77
|
+
}
|
package/examples/get_info.ts
CHANGED
|
@@ -8,7 +8,7 @@ import * as dotenv from 'dotenv';
|
|
|
8
8
|
dotenv.config();
|
|
9
9
|
|
|
10
10
|
const BASE_URL = process.env['BASE_URL'] || 'https://mainnet.zklighter.elliot.ai';
|
|
11
|
-
const L1_ADDRESS = process.env['L1_ADDRESS'] || '
|
|
11
|
+
const L1_ADDRESS = process.env['L1_ADDRESS'] || '0x23bc4Dc9172d15Bbe02E57C0269EcD46c007EB95';
|
|
12
12
|
const ACCOUNT_INDEX = parseInt(process.env['ACCOUNT_INDEX'] || '65', 10);
|
|
13
13
|
|
|
14
14
|
async function printApi(method: any, ...args: any[]): Promise<void> {
|