x3ui-api 1.0.3 → 1.0.5

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 CHANGED
@@ -13,7 +13,10 @@ npm install x3ui-api
13
13
  - Authentication with x3ui panel
14
14
  - Get system statistics (CPU, memory, network, etc.)
15
15
  - Manage inbounds (list, add, update, delete)
16
- - Convenient Reality inbound builder
16
+ - Protocol-specific builders with fluent API:
17
+ - VLESS with Reality support
18
+ - VMess with HTTP Upgrade support
19
+ - WireGuard support
17
20
  - Client management with fluent API
18
21
  - TypeScript support
19
22
 
@@ -59,15 +62,72 @@ async function main() {
59
62
  main();
60
63
  ```
61
64
 
62
- ### Creating a Reality Inbound
65
+ ### Creating a VMess Inbound
66
+
67
+ The library provides a convenient builder pattern for creating VMess inbounds with HTTP Upgrade:
68
+
69
+ ```javascript
70
+ const X3UIClient = require('x3ui-api');
71
+ const vmess = require('x3ui-api/src/protocols/vmess');
72
+
73
+ const client = new X3UIClient({
74
+ baseURL: 'http://your-x3ui-panel.com:54321'
75
+ });
76
+
77
+ async function createVmessInbound() {
78
+ try {
79
+ await client.login('admin', 'password');
80
+
81
+ // Create a VMess inbound builder
82
+ let builder = new vmess.VmessBuilder(client)
83
+ .setRemark('My VMess Inbound')
84
+ .setPort(8443) // Optional, will auto-generate if not provided
85
+ .setHttpUpgradeHost('your-domain.com');
86
+
87
+ // Add a client
88
+ builder.addClient()
89
+ .setEmail('user@example.com')
90
+ .setTotalGB(100) // 100 GB traffic limit
91
+ .setExpiryTime(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30 days
92
+
93
+ // Build and add the inbound
94
+ const inbound = await builder.build();
95
+ const createdInbound = await client.addInbound(inbound);
96
+
97
+ // Update the builder with the server-returned inbound to get all metrics and IDs
98
+ builder = new vmess.VmessBuilder(client, createdInbound);
99
+
100
+ console.log('Inbound created:', createdInbound);
101
+
102
+ // Get connection link for the client (now with accurate server-assigned values)
103
+ const link = builder.getClientLink(0, 'your-server-ip.com');
104
+ console.log('Client connection link:', link);
105
+ } catch (error) {
106
+ console.error('Error creating inbound:', error.message);
107
+ }
108
+ }
109
+
110
+ createVmessInbound();
111
+ ```
112
+
113
+ ### Creating a VLESS Reality Inbound
63
114
 
64
115
  The library provides a convenient builder pattern for creating Reality inbounds:
65
116
 
66
117
  ```javascript
118
+ const X3UIClient = require('x3ui-api');
119
+ const vless = require('x3ui-api/src/protocols/vless');
120
+
121
+ const client = new X3UIClient({
122
+ baseURL: 'http://your-x3ui-panel.com:54321'
123
+ });
124
+
67
125
  async function createRealityInbound() {
68
126
  try {
127
+ await client.login('admin', 'password');
128
+
69
129
  // Create a Reality inbound builder
70
- const builder = client.createRealityBuilder({
130
+ let builder = new vless.RealityBuilder(client, {
71
131
  remark: 'My Reality Inbound',
72
132
  port: 8443 // Optional, will auto-generate if not provided
73
133
  });
@@ -79,18 +139,21 @@ async function createRealityInbound() {
79
139
  .setFingerprint('chrome');
80
140
 
81
141
  // Add a client
82
- const clientBuilder = builder.addClient()
142
+ builder.addClient()
83
143
  .setEmail('user@example.com')
84
144
  .setTotalGB(100) // 100 GB traffic limit
85
145
  .setExpiryTime(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30 days
86
146
 
87
147
  // Build and add the inbound
88
148
  const inbound = await builder.build();
89
- const result = await client.addInbound(inbound);
149
+ const createdInbound = await client.addInbound(inbound);
150
+
151
+ // Update the builder with the server-returned inbound to get all metrics and IDs
152
+ builder = new vless.RealityBuilder(client, createdInbound);
90
153
 
91
- console.log('Inbound created:', result);
154
+ console.log('Inbound created:', createdInbound);
92
155
 
93
- // Get connection link for the client
156
+ // Get connection link for the client (now with accurate server-assigned values)
94
157
  const link = builder.getClientLink(0, 'your-server-ip.com');
95
158
  console.log('Client connection link:', link);
96
159
  } catch (error) {
@@ -99,24 +162,145 @@ async function createRealityInbound() {
99
162
  }
100
163
  ```
101
164
 
165
+ ### Creating a WireGuard Inbound
166
+
167
+ The library provides a convenient builder pattern for creating WireGuard inbounds:
168
+
169
+ ```javascript
170
+ const X3UIClient = require('x3ui-api');
171
+ const wireguard = require('x3ui-api/src/protocols/wireguard');
172
+
173
+ const client = new X3UIClient({
174
+ baseURL: 'http://your-x3ui-panel.com:54321'
175
+ });
176
+
177
+ async function createWireguardInbound() {
178
+ try {
179
+ await client.login('admin', 'password');
180
+
181
+ // Create a WireGuard inbound builder
182
+ let builder = new wireguard.WireguardBuilder(client)
183
+ .setRemark('My WireGuard Inbound')
184
+ .setPort(51820) // WireGuard port, will auto-generate if not provided
185
+ .setMtu(1420); // Optional, default is 1420
186
+
187
+ // Keys are automatically generated, but you can set them manually if needed
188
+ // builder.setSecretKey('your-base64-encoded-secret-key');
189
+
190
+ // Add a client
191
+ const clientBuilder = builder.addClient()
192
+ .setEmail('user@example.com')
193
+ .setTotalGB(100) // 100 GB traffic limit
194
+ .setExpiryTime(Date.now() + 30 * 24 * 60 * 60 * 1000); // 30 days
195
+
196
+ // Generate key pair for the client (or you can set them manually)
197
+ clientBuilder.generateKeyPair();
198
+
199
+ // Set allowed IPs (default is 10.0.0.2/32)
200
+ clientBuilder.setAllowedIPs(['10.0.0.2/32']);
201
+
202
+ // Optionally generate a pre-shared key for additional security
203
+ clientBuilder.generatePresharedKey();
204
+
205
+ // Build and add the inbound
206
+ const inbound = await builder.build();
207
+ const createdInbound = await client.addInbound(inbound);
208
+
209
+ // Update the builder with the server-returned inbound to get all metrics and IDs
210
+ builder = new wireguard.WireguardBuilder(client, createdInbound);
211
+
212
+ console.log('Inbound created:', createdInbound);
213
+
214
+ // Get WireGuard configuration for the client
215
+ const config = builder.getClientConfig(0, 'your-server-ip.com');
216
+ console.log('Client configuration:');
217
+ console.log(config);
218
+ } catch (error) {
219
+ console.error('Error creating inbound:', error.message);
220
+ }
221
+ }
222
+
223
+ createWireguardInbound();
224
+ ```
225
+
226
+ ### Real-World Example
227
+
228
+ Here's a complete example showing how to create a VMess inbound and get the client link:
229
+
230
+ ```javascript
231
+ const X3UIClient = require('x3ui-api');
232
+ const vmess = require('x3ui-api/src/protocols/vmess');
233
+
234
+ const client = new X3UIClient({
235
+ baseURL: 'https://your-panel-url.com/path/',
236
+ });
237
+
238
+ (async () => {
239
+ await client.login('username', 'password');
240
+
241
+ // Create VMess builder with HTTP Upgrade
242
+ let vmessBuilder = new vmess.VmessBuilder(client)
243
+ .setRemark("My VMess Inbound")
244
+ .setHttpUpgradeHost("your-domain.com");
245
+
246
+ // Add the inbound to the server
247
+ const vmessInbound = await client.addInbound(await vmessBuilder.build());
248
+
249
+ // Create a new builder with the server-returned inbound to get accurate client links
250
+ vmessBuilder = new vmess.VmessBuilder(client, vmessInbound);
251
+
252
+ // Generate and output the client connection link
253
+ console.log(vmessBuilder.getClientLink(0, "your-domain.com"));
254
+ })();
255
+ ```
256
+
102
257
  ### Managing Existing Inbounds
103
258
 
104
259
  ```javascript
105
260
  async function manageInbounds() {
106
- // Get all inbounds
107
- const inbounds = await client.getInbounds();
108
-
109
- if (inbounds.length > 0) {
110
- const inboundId = inbounds[0].id;
111
-
112
- // Update an inbound
113
- await client.updateInbound(inboundId, {
114
- remark: 'Updated Inbound Name',
115
- enable: true
116
- });
261
+ try {
262
+ // Get all inbounds
263
+ const inbounds = await client.getInbounds();
117
264
 
118
- // Delete an inbound
119
- await client.deleteInbound(inboundId);
265
+ if (inbounds.length > 0) {
266
+ // Get the first inbound
267
+ const inbound = inbounds[0];
268
+ const inboundId = inbound.id;
269
+
270
+ // IMPORTANT: When updating an inbound, always start with the complete inbound object
271
+ // to avoid losing data, then modify only what you need to change
272
+
273
+ // Example 1: Update the remark and enable status
274
+ inbound.remark = 'Updated Inbound Name';
275
+ inbound.enable = true;
276
+
277
+ // Send the complete updated inbound back to the server
278
+ await client.updateInbound(inboundId, inbound);
279
+
280
+ // Example 2: Add a new client to an existing inbound
281
+ if (inbound.protocol === 'vmess') {
282
+ // Create a builder with the existing inbound
283
+ const builder = new vmess.VmessBuilder(client, inbound);
284
+
285
+ // Add a new client
286
+ builder.addClient()
287
+ .setEmail('newuser@example.com')
288
+ .setTotalGB(50);
289
+
290
+ // Build the updated inbound and send it to the server
291
+ const updatedInbound = await builder.build();
292
+ await client.updateInbound(inboundId, updatedInbound);
293
+
294
+ // Get the link for the new client
295
+ const link = builder.getClientLink(builder.clients.length - 1, 'your-server-ip.com');
296
+ console.log('New client link:', link);
297
+ }
298
+
299
+ // Example 3: Delete an inbound
300
+ await client.deleteInbound(inboundId);
301
+ }
302
+ } catch (error) {
303
+ console.error('Error managing inbounds:', error.message);
120
304
  }
121
305
  }
122
306
  ```
@@ -140,18 +324,44 @@ new X3UIClient({
140
324
  - `login(username: string, password: string)` - Authenticate with the panel
141
325
  - `getSystemStats()` - Get system statistics
142
326
  - `getInbounds()` - Get all configured inbounds
143
- - `addInbound(config)` - Add a new inbound
144
- - `updateInbound(id, config)` - Update an existing inbound
327
+ - `addInbound(config)` - Add a new inbound and returns the created inbound with server-assigned values
328
+ - `updateInbound(id, config)` - Update an existing inbound with the complete inbound configuration
145
329
  - `deleteInbound(id)` - Delete an inbound
146
330
  - `getNewX25519Cert()` - Generate a new X25519 certificate
147
- - `createRealityBuilder(options)` - Create a Reality inbound builder
148
331
 
149
- ### RealityBuilder
332
+ ### Protocol Builders
150
333
 
151
- Builder class for creating Reality inbounds with a fluent API.
334
+ The library provides protocol-specific builders for creating different types of inbounds:
152
335
 
153
- #### Methods
336
+ #### VMess Builder
337
+
338
+ ```javascript
339
+ const vmess = require('x3ui-api/src/protocols/vmess');
340
+ const builder = new vmess.VmessBuilder(client, options);
341
+ ```
154
342
 
343
+ Methods:
344
+ - `setPort(port)` - Set the port for the inbound
345
+ - `setRemark(remark)` - Set the name/remark for the inbound
346
+ - `setNetwork(network)` - Set the network type (default: 'httpupgrade')
347
+ - `setSecurity(security)` - Set the security type (default: 'none')
348
+ - `setHttpUpgradePath(path)` - Set the HTTP upgrade path
349
+ - `setHttpUpgradeHost(host)` - Set the HTTP upgrade host
350
+ - `setSniffing(enabled, destOverride, metadataOnly, routeOnly)` - Configure sniffing
351
+ - `setListenIP(ip)` - Set listen IP address
352
+ - `setExpiryTime(timestamp)` - Set inbound expiry time
353
+ - `addClient(options)` - Add a new client to the inbound
354
+ - `getClientLink(clientIndex, host, port)` - Get connection link for a client
355
+ - `build()` - Build the final inbound config
356
+
357
+ #### VLESS Reality Builder
358
+
359
+ ```javascript
360
+ const vless = require('x3ui-api/src/protocols/vless');
361
+ const builder = new vless.RealityBuilder(client, options);
362
+ ```
363
+
364
+ Methods:
155
365
  - `setPort(port)` - Set the port for the inbound
156
366
  - `setRemark(remark)` - Set the name/remark for the inbound
157
367
  - `setDest(dest)` - Set the destination address (e.g., "yahoo.com:443")
@@ -165,6 +375,44 @@ Builder class for creating Reality inbounds with a fluent API.
165
375
  - `getClientLink(clientIndex, host)` - Get connection link for a client
166
376
  - `build()` - Build the final inbound config
167
377
 
378
+ #### WireGuard Builder
379
+
380
+ ```javascript
381
+ const wireguard = require('x3ui-api/src/protocols/wireguard');
382
+ const builder = new wireguard.WireguardBuilder(client, options);
383
+ ```
384
+
385
+ Methods:
386
+ - `setPort(port)` - Set the port for the inbound
387
+ - `setRemark(remark)` - Set the name/remark for the inbound
388
+ - `setMtu(mtu)` - Set the MTU value (default: 1420)
389
+ - `setSecretKey(secretKey)` - Set the server's secret key (automatically generates if not provided)
390
+ - `setNoKernelTun(noKernelTun)` - Set whether to disable kernel TUN support
391
+ - `setSniffing(enabled, destOverride, metadataOnly, routeOnly)` - Configure sniffing
392
+ - `setListenIP(ip)` - Set listen IP address
393
+ - `setExpiryTime(timestamp)` - Set inbound expiry time
394
+ - `addClient(options)` - Add a new client to the inbound
395
+ - `getClientLink(clientIndex, host, port)` - Get connection link for a client
396
+ - `getClientConfig(clientIndex, host, port)` - Get WireGuard configuration file content for a client
397
+ - `build()` - Build the final inbound config
398
+
399
+ ##### WireGuard Client Builder
400
+
401
+ Methods:
402
+ - `setPrivateKey(privateKey)` - Set client's private key
403
+ - `setPublicKey(publicKey)` - Set client's public key
404
+ - `setPreSharedKey(preSharedKey)` - Set pre-shared key for additional security
405
+ - `setAllowedIPs(allowedIPs)` - Set allowed IP ranges (default: ['10.0.0.2/32'])
406
+ - `setKeepAlive(keepAlive)` - Set keep-alive interval in seconds
407
+ - `generateKeyPair()` - Generate a new key pair for the client
408
+ - `generatePresharedKey()` - Generate a new pre-shared key
409
+ - `setEmail(email)` - Set client email
410
+ - `setTotalGB(gb)` - Set total traffic limit in GB
411
+ - `setExpiryTime(timestamp)` - Set client expiry time
412
+ - `setTgId(id)` - Set Telegram ID
413
+ - `getLink(host, port)` - Get WireGuard configuration as text
414
+ - `getConfigFile(host, port)` - Get WireGuard configuration file content
415
+
168
416
  ## License
169
417
 
170
418
  MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "x3ui-api",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "API client for x3ui panel",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -0,0 +1,37 @@
1
+ import {ClientSettings, InboundConfig} from "../index";
2
+ import InboundBuilder from "./IndoundBuilder";
3
+
4
+ export default class ClientBuilder {
5
+
6
+ constructor(parent: InboundBuilder | InboundConfig);
7
+
8
+ /**
9
+ * Set client UUID. If not provided, will be auto-generated
10
+ */
11
+ setId(id: string): this;
12
+
13
+ /**
14
+ * Set client email
15
+ */
16
+ setEmail(email: string): this;
17
+
18
+ /**
19
+ * Set total traffic limit in GB
20
+ */
21
+ setTotalGB(gb: number): this;
22
+
23
+ /**
24
+ * Set expiry time in unix timestamp
25
+ */
26
+ setExpiryTime(timestamp: number): this;
27
+
28
+ /**
29
+ * Set Telegram ID
30
+ */
31
+ setTgId(id: string): this;
32
+
33
+ /**
34
+ * Build the client configuration
35
+ */
36
+ build(): ClientSettings;
37
+ }
@@ -0,0 +1,57 @@
1
+ const crypto = require("crypto");
2
+
3
+ module.exports = class ClientBuilder {
4
+ constructor(parent) {
5
+ this.parent = parent;
6
+ this.id = '';
7
+ this.flow = '';
8
+ this.email = '';
9
+ this.limitIp = 0;
10
+ this.totalGB = 0;
11
+ this.expiryTime = 0;
12
+ this.enable = true;
13
+ this.tgId = '';
14
+ this.subId = '';
15
+ this.reset = 0;
16
+ }
17
+
18
+ setId(id) {
19
+ this.id = id;
20
+ return this;
21
+ }
22
+
23
+ setEmail(email) {
24
+ this.email = email;
25
+ return this;
26
+ }
27
+
28
+ setTotalGB(gb) {
29
+ this.totalGB = gb;
30
+ return this;
31
+ }
32
+
33
+ setExpiryTime(timestamp) {
34
+ this.expiryTime = timestamp;
35
+ return this;
36
+ }
37
+
38
+ setTgId(id) {
39
+ this.tgId = id;
40
+ return this;
41
+ }
42
+
43
+ build() {
44
+ return {
45
+ id: this.id || crypto.randomUUID(),
46
+ flow: this.flow,
47
+ email: this.email || Math.random().toString(36).substring(2, 10),
48
+ limitIp: this.limitIp,
49
+ totalGB: this.totalGB,
50
+ expiryTime: this.expiryTime,
51
+ enable: this.enable,
52
+ tgId: this.tgId,
53
+ subId: this.subId || Math.random().toString(36).substring(2, 18),
54
+ reset: this.reset
55
+ };
56
+ }
57
+ }
@@ -0,0 +1 @@
1
+ export default class InboundBuilder {}
@@ -0,0 +1,31 @@
1
+ import {AxiosInstance} from "axios";
2
+ import {
3
+ InboundConfig,
4
+ LoginResponse,
5
+ SystemStats,
6
+ X3UIConfig
7
+ } from "../index";
8
+
9
+ export default class X3UIClient {
10
+ private client: AxiosInstance;
11
+
12
+ constructor(config: X3UIConfig);
13
+
14
+ login(username: string, password: string): Promise<LoginResponse>;
15
+
16
+ getSystemStats(): Promise<SystemStats>;
17
+
18
+ getInbounds(): Promise<InboundConfig[]>;
19
+
20
+ addInbound(config: Omit<InboundConfig, 'id'>): Promise<InboundConfig>;
21
+
22
+ updateInbound(id: number, config: Partial<InboundConfig>): Promise<void>;
23
+
24
+ deleteInbound(id: number): Promise<void>;
25
+
26
+ getInboundTraffic(id: number): Promise<{ up: number; down: number }>;
27
+
28
+ resetInboundTraffic(id: number): Promise<void>;
29
+
30
+ getNewX25519Cert(): Promise<{ privateKey: string; publicKey: string }>;
31
+ }
@@ -0,0 +1,147 @@
1
+ const axios = require("axios");
2
+
3
+ module.exports = class X3UIClient {
4
+ constructor(config) {
5
+ this.parseJSONSettings = config.parseJSONSettings || true;
6
+ this.client = axios.create({
7
+ baseURL: config.baseURL,
8
+ headers: config.token ? {
9
+ 'Cookie': `lang=en-US; 3x-ui=${config.token}`,
10
+ } : {
11
+ 'Cookie': 'lang=en-US'
12
+ }
13
+ });
14
+ }
15
+
16
+ /**
17
+ * Login to the x3ui panel
18
+ * @param {string} username Panel username
19
+ * @param {string} password Panel password
20
+ * @returns {Promise<{success: boolean, msg: string, obj: any}>} Login response with success status and token
21
+ */
22
+ async login(username, password) {
23
+ const formData = new URLSearchParams();
24
+ formData.append('username', username);
25
+ formData.append('password', password);
26
+
27
+ const response = await this.client.post('/login', formData, {
28
+ headers: {
29
+ 'Content-Type': 'application/x-www-form-urlencoded'
30
+ }
31
+ });
32
+
33
+ if (response.data.success) {
34
+ this.client.defaults.headers.Cookie = `lang=en-US; ${response.headers.get("set-cookie")[0].split(";")[0]}`;
35
+ }
36
+
37
+ return response.data;
38
+ }
39
+
40
+ async getSystemStats() {
41
+ const response = await this.client.post('/server/status');
42
+ return response.data.obj;
43
+ }
44
+
45
+ /**
46
+ * Get all inbounds
47
+ * @returns {Promise<Array<{
48
+ * id?: number,
49
+ * up: number,
50
+ * down: number,
51
+ * total: number,
52
+ * remark: string,
53
+ * enable: boolean,
54
+ * expiryTime: number | null,
55
+ * listen: string,
56
+ * port: number,
57
+ * protocol: string,
58
+ * settings: any,
59
+ * streamSettings: any,
60
+ * sniffing: any
61
+ * }>>}
62
+ */
63
+ async getInbounds() {
64
+ const response = await this.client.get('/panel/api/inbounds/list');
65
+ let inbounds = response.data.obj;
66
+ if (this.parseJSONSettings) {
67
+ inbounds = inbounds.map(inbound => this.parseInbound(inbound));
68
+ }
69
+ return inbounds;
70
+ }
71
+
72
+ parseInbound(inbound) {
73
+ if (this.parseJSONSettings) {
74
+ inbound.settings = inbound.settings && inbound.settings.length > 0 ? JSON.parse(inbound.settings) : {};
75
+ inbound.streamSettings = inbound.streamSettings && inbound.streamSettings.length > 0 ? JSON.parse(inbound.streamSettings) : {};
76
+ inbound.sniffing = inbound.sniffing && inbound.sniffing.length > 0 ? JSON.parse(inbound.sniffing) : {};
77
+ inbound.allocate = inbound.allocate && inbound.allocate.length > 0 ? JSON.parse(inbound.allocate) : {};
78
+ }
79
+ return inbound;
80
+ }
81
+
82
+ stringifyInbound(inbound) {
83
+ inbound.settings = JSON.stringify(inbound.settings);
84
+ inbound.streamSettings = JSON.stringify(inbound.streamSettings);
85
+ inbound.sniffing = JSON.stringify(inbound.sniffing);
86
+ inbound.allocate = JSON.stringify(inbound.allocate);
87
+ return inbound;
88
+ }
89
+
90
+ /**
91
+ * Add new inbound
92
+ * @param {Object} config Inbound configuration
93
+ * @param {number} config.up Upload traffic in bytes
94
+ * @param {number} config.down Download traffic in bytes
95
+ * @param {number} config.total Total traffic limit in bytes
96
+ * @param {string} config.remark Inbound remark/name
97
+ * @param {boolean} config.enable Enable status
98
+ * @param {number|null} config.expiryTime Expiry timestamp
99
+ * @param {string} config.listen Listen address
100
+ * @param {number} config.port Port number
101
+ * @param {string} config.protocol Protocol type
102
+ * @param {Object} config.settings Protocol settings
103
+ * @param {Object} config.streamSettings Stream settings
104
+ * @param {Object} config.sniffing Sniffing settings
105
+ * @param {Object} config.allocate Allocation settings
106
+ * @returns {Promise<void>}
107
+ */
108
+ async addInbound(config) {
109
+ config = this.stringifyInbound(config);
110
+ const response = await this.client.post('/panel/api/inbounds/add', config);
111
+ if(!response.data.success)
112
+ throw new Error(response.data.msg);
113
+ return this.parseInbound(response.data.obj);
114
+ }
115
+
116
+ /**
117
+ * Update existing inbound
118
+ * @param {number} id Inbound ID
119
+ * @param {Object} config Partial inbound configuration
120
+ * @returns {Promise<void>}
121
+ */
122
+ async updateInbound(id, config) {
123
+ config = this.stringifyInbound(config);
124
+ const response = await this.client.post(`/panel/api/inbounds/update/${id}`, config);
125
+ if(!response.data.success)
126
+ throw new Error(response.data.msg);
127
+ return this.parseInbound(response.data.obj);
128
+ }
129
+
130
+ /**
131
+ * Delete inbound
132
+ * @param {number} id Inbound ID
133
+ * @returns {Promise<void>}
134
+ */
135
+ async deleteInbound(id) {
136
+ await this.client.post(`/panel/api/inbounds/del/${id}`);
137
+ }
138
+
139
+ /**
140
+ * Get new X25519 certificate
141
+ * @returns {Promise<{privateKey: string, publicKey: string}>} New X25519 key pair
142
+ */
143
+ async getNewX25519Cert() {
144
+ const response = await this.client.post('/server/getNewX25519Cert');
145
+ return response.data.obj;
146
+ }
147
+ }