@openzeppelin/relayer-plugin-channels 0.4.0 → 0.6.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.
package/README.md CHANGED
@@ -19,6 +19,10 @@ A plugin for OpenZeppelin Relayer that enables parallel transaction submission o
19
19
  - [Management API](#management-api)
20
20
  - [List Channel Accounts](#list-channel-accounts)
21
21
  - [Set Channel Accounts](#set-channel-accounts)
22
+ - [Get Fee Usage](#get-fee-usage)
23
+ - [Get Fee Limit](#get-fee-limit)
24
+ - [Set Fee Limit](#set-fee-limit)
25
+ - [Delete Fee Limit](#delete-fee-limit)
22
26
  - [Plugin Client](#plugin-client)
23
27
  - [Installation](#installation)
24
28
  - [Quick Start](#quick-start-1)
@@ -215,7 +219,11 @@ export PLUGIN_ADMIN_SECRET="your-secret-here" # Required for management API
215
219
 
216
220
  # Optional environment variables
217
221
  export LOCK_TTL_SECONDS=10 # default: 30, min: 3, max: 30
218
- export MAX_FEE=1000000 # default: 1,000,000 stroops
222
+
223
+ # Fee tracking (optional)
224
+ export FEE_LIMIT=1000000 # Default max fee per API key in stroops (disabled if not set)
225
+ export FEE_RESET_PERIOD_SECONDS=86400 # Reset fee consumption every N seconds (e.g., 86400 = 24 hours)
226
+ export API_KEY_HEADER="x-api-key" # Header name to extract API key (default: x-api-key)
219
227
  ```
220
228
 
221
229
  Your Relayer should now contain:
@@ -341,6 +349,127 @@ curl -X POST http://localhost:8080/api/v1/plugins/channels/call \
341
349
  }
342
350
  ```
343
351
 
352
+ ### Get Fee Usage
353
+
354
+ Query fee consumption for a specific API key:
355
+
356
+ ```bash
357
+ curl -X POST http://localhost:8080/api/v1/plugins/channels/call \
358
+ -H "Authorization: Bearer YOUR_API_KEY" \
359
+ -H "Content-Type: application/json" \
360
+ -d '{
361
+ "params": {
362
+ "management": {
363
+ "action": "getFeeUsage",
364
+ "adminSecret": "your-secret-here",
365
+ "apiKey": "client-api-key-to-query"
366
+ }
367
+ }
368
+ }'
369
+ ```
370
+
371
+ **Response:**
372
+
373
+ ```json
374
+ {
375
+ "consumed": 500000,
376
+ "limit": 1000000,
377
+ "remaining": 500000,
378
+ "periodStartAt": "2024-01-15T00:00:00.000Z",
379
+ "periodEndsAt": "2024-01-16T00:00:00.000Z"
380
+ }
381
+ ```
382
+
383
+ - `limit`: Effective fee limit (custom if set, otherwise default)
384
+ - `remaining`: Remaining fee budget in stroops
385
+ - `periodStartAt`: Datetime string when current period started (if reset period configured)
386
+ - `periodEndsAt`: Datetime string when period will reset (if reset period configured)
387
+
388
+ ### Get Fee Limit
389
+
390
+ Query fee limit configuration for a specific API key:
391
+
392
+ ```bash
393
+ curl -X POST http://localhost:8080/api/v1/plugins/channels/call \
394
+ -H "Authorization: Bearer YOUR_API_KEY" \
395
+ -H "Content-Type: application/json" \
396
+ -d '{
397
+ "params": {
398
+ "management": {
399
+ "action": "getFeeLimit",
400
+ "adminSecret": "your-secret-here",
401
+ "apiKey": "client-api-key-to-query"
402
+ }
403
+ }
404
+ }'
405
+ ```
406
+
407
+ **Response:**
408
+
409
+ ```json
410
+ {
411
+ "limit": 500000
412
+ }
413
+ ```
414
+
415
+ ### Set Fee Limit
416
+
417
+ Set a custom fee limit for a specific API key:
418
+
419
+ ```bash
420
+ curl -X POST http://localhost:8080/api/v1/plugins/channels/call \
421
+ -H "Authorization: Bearer YOUR_API_KEY" \
422
+ -H "Content-Type: application/json" \
423
+ -d '{
424
+ "params": {
425
+ "management": {
426
+ "action": "setFeeLimit",
427
+ "adminSecret": "your-secret-here",
428
+ "apiKey": "client-api-key",
429
+ "limit": 500000
430
+ }
431
+ }
432
+ }'
433
+ ```
434
+
435
+ **Response:**
436
+
437
+ ```json
438
+ {
439
+ "ok": true,
440
+ "limit": 500000
441
+ }
442
+ ```
443
+
444
+ Note: If custom limit is set to 0 it will block all transactions
445
+
446
+ ### Delete Fee Limit
447
+
448
+ Remove a custom fee limit for a specific API key (reverts to default limit):
449
+
450
+ ```bash
451
+ curl -X POST http://localhost:8080/api/v1/plugins/channels/call \
452
+ -H "Authorization: Bearer YOUR_API_KEY" \
453
+ -H "Content-Type: application/json" \
454
+ -d '{
455
+ "params": {
456
+ "management": {
457
+ "action": "deleteFeeLimit",
458
+ "adminSecret": "your-secret-here",
459
+ "apiKey": "client-api-key"
460
+ }
461
+ }
462
+ }'
463
+ ```
464
+
465
+ **Response:**
466
+
467
+ ```json
468
+ {
469
+ "ok": true
470
+ }
471
+ ```
472
+
344
473
  **Important Notes:**
345
474
 
346
475
  - You must configure at least one channel account before the plugin can process transactions
@@ -477,6 +606,47 @@ console.log(result.ok); // true
477
606
  console.log(result.appliedRelayerIds); // ['channel-001', 'channel-002', 'channel-003']
478
607
  ```
479
608
 
609
+ #### Get Fee Usage (Management)
610
+
611
+ ```typescript
612
+ // Query fee consumption for an API key (requires adminSecret)
613
+ const usage = await adminClient.getFeeUsage("client-api-key");
614
+
615
+ console.log(usage.consumed); // 500000 (stroops)
616
+ console.log(usage.limit); // 1000000 (effective limit)
617
+ console.log(usage.remaining); // 500000 (remaining budget)
618
+ console.log(usage.periodStartAt); // '2024-01-15T00:00:00.000Z'
619
+ console.log(usage.periodEndsAt); // '2024-01-16T00:00:00.000Z'
620
+ ```
621
+
622
+ #### Get Fee Limit (Management)
623
+
624
+ ```typescript
625
+ // Query fee limit configuration for an API key (requires adminSecret)
626
+ const limitInfo = await adminClient.getFeeLimit("client-api-key");
627
+
628
+ console.log(limitInfo.limit); // 500000 (custom limit if set, otherwise default)
629
+ ```
630
+
631
+ #### Set Fee Limit (Management)
632
+
633
+ ```typescript
634
+ // Set a custom fee limit for an API key (requires adminSecret)
635
+ const result = await adminClient.setFeeLimit("client-api-key", 500000);
636
+
637
+ console.log(result.ok); // true
638
+ console.log(result.limit); // 500000
639
+ ```
640
+
641
+ #### Delete Fee Limit (Management)
642
+
643
+ ```typescript
644
+ // Remove custom fee limit, revert to default (requires adminSecret)
645
+ const result = await adminClient.deleteFeeLimit("client-api-key");
646
+
647
+ console.log(result.ok); // true
648
+ ```
649
+
480
650
  ### Error Handling
481
651
 
482
652
  The client provides three types of errors:
@@ -531,6 +701,10 @@ import type {
531
701
  ChannelsTransactionResponse,
532
702
  ListChannelAccountsResponse,
533
703
  SetChannelAccountsResponse,
704
+ GetFeeUsageResponse,
705
+ GetFeeLimitResponse,
706
+ SetFeeLimitResponse,
707
+ DeleteFeeLimitResponse,
534
708
  } from "@openzeppelin/relayer-plugin-channels";
535
709
  ```
536
710
 
@@ -539,13 +713,14 @@ import type {
539
713
  ```typescript
540
714
  interface ChannelsClientConfig {
541
715
  // Required
542
- baseUrl: string; // Service or Relayer URL
716
+ baseUrl: string; // Service URL
543
717
  apiKey: string; // API key for authentication
544
718
 
545
719
  // Optional
546
720
  pluginId?: string; // Include when connecting to a Relayer directly
547
721
  adminSecret?: string; // Required for management operations
548
722
  timeout?: number; // Request timeout in ms (default: 30000)
723
+ apiKeyHeader?: string; // Header name for API key (default: 'x-api-key')
549
724
  }
550
725
  ```
551
726
 
@@ -659,6 +834,16 @@ Plugin error example:
659
834
  - **Value**: `{ token: string, lockedAt: ISOString }`
660
835
  - **TTL**: Configured by `LOCK_TTL_SECONDS`.
661
836
 
837
+ ### Fee Tracking
838
+
839
+ - **Key**: `<network>:api-key-fees:<apiKey>`
840
+ - **Value**: `{ consumed: number, periodStart?: number }` (fees in stroops, period start timestamp in ms)
841
+
842
+ ### Custom Fee Limits
843
+
844
+ - **Key**: `<network>:api-key-limit:<apiKey>`
845
+ - **Value**: `{ limit: number }` (custom fee limit in stroops)
846
+
662
847
  ## Error Codes
663
848
 
664
849
  - `CONFIG_MISSING`: Missing required environment variable
@@ -676,6 +861,8 @@ Plugin error example:
676
861
  - `MANAGEMENT_DISABLED`: Management API not enabled
677
862
  - `UNAUTHORIZED`: Invalid admin secret
678
863
  - `LOCKED_CONFLICT`: Cannot remove locked channel accounts
864
+ - `API_KEY_REQUIRED`: API key header missing when `FEE_LIMIT` is configured (HTTP 403)
865
+ - `FEE_LIMIT_EXCEEDED`: API key has exceeded its fee limit (HTTP 429)
679
866
 
680
867
  ## License
681
868
 
@@ -1,4 +1,4 @@
1
- import type { ChannelsClientConfig, ChannelsXdrRequest, ChannelsFuncAuthRequest, ChannelsTransactionResponse, ListChannelAccountsResponse, SetChannelAccountsResponse } from "./types";
1
+ import type { ChannelsClientConfig, ChannelsXdrRequest, ChannelsFuncAuthRequest, ChannelsTransactionResponse, ListChannelAccountsResponse, SetChannelAccountsResponse, GetFeeUsageResponse, GetFeeLimitResponse, SetFeeLimitResponse, DeleteFeeLimitResponse } from "./types";
2
2
  /**
3
3
  * Client for interacting with the Channels plugin
4
4
  *
@@ -88,6 +88,55 @@ export declare class ChannelsClient {
88
88
  * ]);
89
89
  */
90
90
  setChannelAccounts(relayerIds: string[]): Promise<SetChannelAccountsResponse>;
91
+ /**
92
+ * Get fee usage for a specific API key (requires adminSecret)
93
+ *
94
+ * @param apiKey The client API key to query fee usage for
95
+ * @returns Fee usage data including total consumed
96
+ * @throws {Error} If adminSecret not provided in config
97
+ * @throws {PluginTransportError} Network/HTTP failures
98
+ * @throws {PluginExecutionError} Plugin rejected the request
99
+ * @throws {PluginUnexpectedError} Malformed response or client-side errors
100
+ *
101
+ * @example
102
+ * const usage = await client.getFeeUsage('client-api-key-123');
103
+ * console.log(`Consumed: ${usage.consumed} stroops`);
104
+ */
105
+ getFeeUsage(apiKey: string): Promise<GetFeeUsageResponse>;
106
+ /**
107
+ * Get fee limit configuration for a specific API key (requires adminSecret)
108
+ *
109
+ * @param apiKey The client API key to query fee limit for
110
+ * @returns Fee limit data
111
+ * @throws {Error} If adminSecret not provided in config
112
+ * @throws {PluginTransportError} Network/HTTP failures
113
+ * @throws {PluginExecutionError} Plugin rejected the request
114
+ * @throws {PluginUnexpectedError} Malformed response or client-side errors
115
+ */
116
+ getFeeLimit(apiKey: string): Promise<GetFeeLimitResponse>;
117
+ /**
118
+ * Set a custom fee limit for a specific API key (requires adminSecret)
119
+ *
120
+ * @param apiKey The client API key to set the limit for
121
+ * @param limit The fee limit in stroops (0 blocks all transactions)
122
+ * @returns Confirmation with the applied limit
123
+ * @throws {Error} If adminSecret not provided in config
124
+ * @throws {PluginTransportError} Network/HTTP failures
125
+ * @throws {PluginExecutionError} Plugin rejected the request
126
+ * @throws {PluginUnexpectedError} Malformed response or client-side errors
127
+ */
128
+ setFeeLimit(apiKey: string, limit: number): Promise<SetFeeLimitResponse>;
129
+ /**
130
+ * Delete a custom fee limit for a specific API key (requires adminSecret)
131
+ *
132
+ * @param apiKey The client API key to remove the custom limit for
133
+ * @returns Confirmation of deletion
134
+ * @throws {Error} If adminSecret not provided in config
135
+ * @throws {PluginTransportError} Network/HTTP failures
136
+ * @throws {PluginExecutionError} Plugin rejected the request
137
+ * @throws {PluginUnexpectedError} Malformed response or client-side errors
138
+ */
139
+ deleteFeeLimit(apiKey: string): Promise<DeleteFeeLimitResponse>;
91
140
  /**
92
141
  * Ensures adminSecret is configured
93
142
  *
@@ -1 +1 @@
1
- {"version":3,"file":"channels-client.d.ts","sourceRoot":"","sources":["../../src/client/channels-client.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAE3B,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;gBAEvB,MAAM,EAAE,oBAAoB;IA6BxC;;;;;;;;;;;;;OAaG;IACG,iBAAiB,CACrB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,2BAA2B,CAAC;IAIvC;;;;;;;;;;;;;;;OAeG;IACG,wBAAwB,CAC5B,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,2BAA2B,CAAC;IAIvC;;;;;;;;;;;;OAYG;IACG,mBAAmB,IAAI,OAAO,CAAC,2BAA2B,CAAC;IASjE;;;;;;;;;;;;;;;OAeG;IACG,kBAAkB,CACtB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,0BAA0B,CAAC;IAUtC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;;;;;;OAOG;IAEH,OAAO,CAAC,eAAe;IAoBvB;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAUrB;;;;;;;;OAQG;YACW,IAAI;IA6BlB;;;;;;OAMG;YACW,QAAQ;CAYvB"}
1
+ {"version":3,"file":"channels-client.d.ts","sourceRoot":"","sources":["../../src/client/channels-client.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EAEvB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAgB;IAC7C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAS;gBAEvB,MAAM,EAAE,oBAAoB;IAiCxC;;;;;;;;;;;;;OAaG;IACG,iBAAiB,CACrB,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,2BAA2B,CAAC;IAIvC;;;;;;;;;;;;;;;OAeG;IACG,wBAAwB,CAC5B,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,2BAA2B,CAAC;IAIvC;;;;;;;;;;;;OAYG;IACG,mBAAmB,IAAI,OAAO,CAAC,2BAA2B,CAAC;IASjE;;;;;;;;;;;;;;;OAeG;IACG,kBAAkB,CACtB,UAAU,EAAE,MAAM,EAAE,GACnB,OAAO,CAAC,0BAA0B,CAAC;IAUtC;;;;;;;;;;;;;OAaG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAU/D;;;;;;;;;OASG;IACG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAU/D;;;;;;;;;;OAUG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,mBAAmB,CAAC;IAW/B;;;;;;;;;OASG;IACG,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAUrE;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAS1B;;;;;;;OAOG;IAEH,OAAO,CAAC,eAAe;IAoBvB;;;;;;OAMG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAUrB;;;;;;;;OAQG;YACW,IAAI;IA6BlB;;;;;;OAMG;YACW,QAAQ;CAYvB"}
@@ -33,9 +33,13 @@ class ChannelsClient {
33
33
  // Route through Relayer plugin system if pluginId provided, otherwise connect directly
34
34
  if ("pluginId" in config && config.pluginId) {
35
35
  this.pluginId = config.pluginId;
36
+ const apiKeyHeader = config.apiKeyHeader || "x-api-key";
36
37
  const relayerConfig = new relayer_sdk_1.Configuration({
37
38
  basePath: config.baseUrl,
38
39
  accessToken: config.apiKey,
40
+ baseOptions: {
41
+ headers: { [apiKeyHeader]: config.apiKey },
42
+ },
39
43
  });
40
44
  this.pluginsApi = new relayer_sdk_1.PluginsApi(relayerConfig);
41
45
  }
@@ -135,6 +139,88 @@ class ChannelsClient {
135
139
  },
136
140
  });
137
141
  }
142
+ /**
143
+ * Get fee usage for a specific API key (requires adminSecret)
144
+ *
145
+ * @param apiKey The client API key to query fee usage for
146
+ * @returns Fee usage data including total consumed
147
+ * @throws {Error} If adminSecret not provided in config
148
+ * @throws {PluginTransportError} Network/HTTP failures
149
+ * @throws {PluginExecutionError} Plugin rejected the request
150
+ * @throws {PluginUnexpectedError} Malformed response or client-side errors
151
+ *
152
+ * @example
153
+ * const usage = await client.getFeeUsage('client-api-key-123');
154
+ * console.log(`Consumed: ${usage.consumed} stroops`);
155
+ */
156
+ async getFeeUsage(apiKey) {
157
+ return this.call({
158
+ management: {
159
+ action: "getFeeUsage",
160
+ adminSecret: this.requireAdminSecret(),
161
+ apiKey,
162
+ },
163
+ });
164
+ }
165
+ /**
166
+ * Get fee limit configuration for a specific API key (requires adminSecret)
167
+ *
168
+ * @param apiKey The client API key to query fee limit for
169
+ * @returns Fee limit data
170
+ * @throws {Error} If adminSecret not provided in config
171
+ * @throws {PluginTransportError} Network/HTTP failures
172
+ * @throws {PluginExecutionError} Plugin rejected the request
173
+ * @throws {PluginUnexpectedError} Malformed response or client-side errors
174
+ */
175
+ async getFeeLimit(apiKey) {
176
+ return this.call({
177
+ management: {
178
+ action: "getFeeLimit",
179
+ adminSecret: this.requireAdminSecret(),
180
+ apiKey,
181
+ },
182
+ });
183
+ }
184
+ /**
185
+ * Set a custom fee limit for a specific API key (requires adminSecret)
186
+ *
187
+ * @param apiKey The client API key to set the limit for
188
+ * @param limit The fee limit in stroops (0 blocks all transactions)
189
+ * @returns Confirmation with the applied limit
190
+ * @throws {Error} If adminSecret not provided in config
191
+ * @throws {PluginTransportError} Network/HTTP failures
192
+ * @throws {PluginExecutionError} Plugin rejected the request
193
+ * @throws {PluginUnexpectedError} Malformed response or client-side errors
194
+ */
195
+ async setFeeLimit(apiKey, limit) {
196
+ return this.call({
197
+ management: {
198
+ action: "setFeeLimit",
199
+ adminSecret: this.requireAdminSecret(),
200
+ apiKey,
201
+ limit,
202
+ },
203
+ });
204
+ }
205
+ /**
206
+ * Delete a custom fee limit for a specific API key (requires adminSecret)
207
+ *
208
+ * @param apiKey The client API key to remove the custom limit for
209
+ * @returns Confirmation of deletion
210
+ * @throws {Error} If adminSecret not provided in config
211
+ * @throws {PluginTransportError} Network/HTTP failures
212
+ * @throws {PluginExecutionError} Plugin rejected the request
213
+ * @throws {PluginUnexpectedError} Malformed response or client-side errors
214
+ */
215
+ async deleteFeeLimit(apiKey) {
216
+ return this.call({
217
+ management: {
218
+ action: "deleteFeeLimit",
219
+ adminSecret: this.requireAdminSecret(),
220
+ apiKey,
221
+ },
222
+ });
223
+ }
138
224
  /**
139
225
  * Ensures adminSecret is configured
140
226
  *
@@ -5,6 +5,6 @@
5
5
  * in both direct HTTP mode and OpenZeppelin Relayer mode.
6
6
  */
7
7
  export { ChannelsClient } from "./channels-client";
8
- export { ChannelsClientConfig, DirectHttpConfig, RelayerConfig, ChannelsXdrRequest, ChannelsFuncAuthRequest, ChannelsTransactionResponse, ListChannelAccountsResponse, SetChannelAccountsResponse, } from "./types";
8
+ export { ChannelsClientConfig, DirectHttpConfig, RelayerConfig, ChannelsXdrRequest, ChannelsFuncAuthRequest, ChannelsTransactionResponse, ListChannelAccountsResponse, SetChannelAccountsResponse, GetFeeUsageResponse, GetFeeLimitResponse, SetFeeLimitResponse, DeleteFeeLimitResponse, } from "./types";
9
9
  export { PluginClientError, PluginTransportError, PluginExecutionError, PluginUnexpectedError, } from "./errors";
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,GAC3B,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,uBAAuB,EACvB,2BAA2B,EAC3B,2BAA2B,EAC3B,0BAA0B,EAC1B,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,UAAU,CAAC"}
@@ -26,6 +26,8 @@ export interface RelayerConfig {
26
26
  adminSecret?: string;
27
27
  /** Optional request timeout in milliseconds (default: 30000) */
28
28
  timeout?: number;
29
+ /** Header name for API key forwarding to plugin (default: 'x-api-key') */
30
+ apiKeyHeader?: string;
29
31
  }
30
32
  /**
31
33
  * Configuration for ChannelsClient
@@ -92,6 +94,64 @@ export interface SetChannelAccountsResponse {
92
94
  traces?: any[];
93
95
  };
94
96
  }
97
+ /**
98
+ * Response from getting fee usage
99
+ */
100
+ export interface GetFeeUsageResponse {
101
+ /** Total fees consumed (in stroops) */
102
+ consumed: number;
103
+ /** Effective fee limit (in stroops), undefined if unlimited */
104
+ limit?: number;
105
+ /** Remaining fee budget (in stroops), undefined if unlimited */
106
+ remaining?: number;
107
+ /** When the current reset period started, undefined if no reset period */
108
+ periodStartAt?: string;
109
+ /** When the current period will end, undefined if no reset period */
110
+ periodEndsAt?: string;
111
+ /** Optional metadata (logs and traces) */
112
+ metadata?: {
113
+ logs?: LogEntry[];
114
+ traces?: any[];
115
+ };
116
+ }
117
+ /**
118
+ * Response from getting fee limit
119
+ */
120
+ export interface GetFeeLimitResponse {
121
+ /** Fee limit (in stroops), undefined if unlimited */
122
+ limit?: number;
123
+ /** Optional metadata (logs and traces) */
124
+ metadata?: {
125
+ logs?: LogEntry[];
126
+ traces?: any[];
127
+ };
128
+ }
129
+ /**
130
+ * Response from setting fee limit
131
+ */
132
+ export interface SetFeeLimitResponse {
133
+ /** Success indicator */
134
+ ok: boolean;
135
+ /** The limit that was set (in stroops) */
136
+ limit: number;
137
+ /** Optional metadata (logs and traces) */
138
+ metadata?: {
139
+ logs?: LogEntry[];
140
+ traces?: any[];
141
+ };
142
+ }
143
+ /**
144
+ * Response from deleting fee limit
145
+ */
146
+ export interface DeleteFeeLimitResponse {
147
+ /** Success indicator */
148
+ ok: boolean;
149
+ /** Optional metadata (logs and traces) */
150
+ metadata?: {
151
+ logs?: LogEntry[];
152
+ traces?: any[];
153
+ };
154
+ }
95
155
  /**
96
156
  * Plugin response structure for successful operations
97
157
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,gBAAgB,GAAG,aAAa,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,iDAAiD;IACjD,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sCAAsC;IACtC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,gCAAgC;IAChC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,yBAAyB;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,oEAAoE;IACpE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,0CAA0C;IAC1C,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,wBAAwB;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,6CAA6C;IAC7C,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,0CAA0C;IAC1C,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAChB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC;QAClB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;KAChB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,qBAAqB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,11 @@
6
6
  export interface ChannelAccountsConfig {
7
7
  fundRelayerId: string;
8
8
  network: "testnet" | "mainnet";
9
+ lockTtlSeconds: number;
10
+ adminSecret?: string;
11
+ feeLimit?: number;
12
+ feeResetPeriodMs?: number;
13
+ apiKeyHeader: string;
9
14
  }
10
15
  /**
11
16
  * Load configuration from environment variables
@@ -15,12 +20,4 @@ export declare function loadConfig(): ChannelAccountsConfig;
15
20
  * Get the network passphrase based on the configuration
16
21
  */
17
22
  export declare function getNetworkPassphrase(network: "testnet" | "mainnet"): string;
18
- /**
19
- * Get the per-channel lock TTL in seconds (default 30)
20
- */
21
- export declare function getLockTtlSeconds(): number;
22
- /**
23
- * Get the admin secret for management API
24
- */
25
- export declare function getAdminSecret(): string | undefined;
26
23
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/plugin/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;CAChC;AAcD;;GAEG;AACH,wBAAgB,UAAU,IAAI,qBAAqB,CAelD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAE3E;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAY1C;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAKnD"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/plugin/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,SAAS,GAAG,SAAS,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB;AAwDD;;GAEG;AACH,wBAAgB,UAAU,IAAI,qBAAqB,CAkBlD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAE3E"}
@@ -7,8 +7,6 @@
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.loadConfig = loadConfig;
9
9
  exports.getNetworkPassphrase = getNetworkPassphrase;
10
- exports.getLockTtlSeconds = getLockTtlSeconds;
11
- exports.getAdminSecret = getAdminSecret;
12
10
  const stellar_sdk_1 = require("@stellar/stellar-sdk");
13
11
  const relayer_sdk_1 = require("@openzeppelin/relayer-sdk");
14
12
  const constants_1 = require("./constants");
@@ -23,6 +21,46 @@ function requireEnv(name) {
23
21
  }
24
22
  return v.trim();
25
23
  }
24
+ function parseOptionalString(name) {
25
+ const v = process.env[name];
26
+ if (!v)
27
+ return undefined;
28
+ const t = v.trim();
29
+ return t.length ? t : undefined;
30
+ }
31
+ function parseLockTtl() {
32
+ const raw = process.env.LOCK_TTL_SECONDS;
33
+ if (!raw)
34
+ return constants_1.CONFIG.DEFAULT_LOCK_TTL_SECONDS;
35
+ const n = Number(raw);
36
+ if (!Number.isFinite(n) ||
37
+ n < constants_1.CONFIG.MIN_LOCK_TTL_SECONDS ||
38
+ n > constants_1.CONFIG.MAX_LOCK_TTL_SECONDS) {
39
+ return constants_1.CONFIG.DEFAULT_LOCK_TTL_SECONDS;
40
+ }
41
+ return Math.floor(n);
42
+ }
43
+ function parseFeeLimit() {
44
+ const raw = process.env.FEE_LIMIT;
45
+ if (!raw)
46
+ return undefined;
47
+ const n = Number(raw);
48
+ return Number.isFinite(n) && n >= 0 ? Math.floor(n) : undefined;
49
+ }
50
+ function parseFeeResetPeriod() {
51
+ const raw = process.env.FEE_RESET_PERIOD_SECONDS;
52
+ if (!raw)
53
+ return undefined;
54
+ const n = Number(raw);
55
+ return Number.isFinite(n) && n > 0 ? Math.floor(n) * 1000 : undefined;
56
+ }
57
+ function parseApiKeyHeader() {
58
+ const raw = process.env.API_KEY_HEADER;
59
+ if (!raw)
60
+ return "x-api-key";
61
+ const trimmed = raw.trim().toLowerCase();
62
+ return trimmed.length > 0 ? trimmed : "x-api-key";
63
+ }
26
64
  /**
27
65
  * Load configuration from environment variables
28
66
  */
@@ -34,10 +72,14 @@ function loadConfig() {
34
72
  status: constants_1.HTTP_STATUS.BAD_REQUEST,
35
73
  });
36
74
  }
37
- const fundRelayerId = requireEnv("FUND_RELAYER_ID");
38
75
  return {
39
- fundRelayerId,
76
+ fundRelayerId: requireEnv("FUND_RELAYER_ID"),
40
77
  network: networkRaw,
78
+ lockTtlSeconds: parseLockTtl(),
79
+ adminSecret: parseOptionalString("PLUGIN_ADMIN_SECRET"),
80
+ feeLimit: parseFeeLimit(),
81
+ feeResetPeriodMs: parseFeeResetPeriod(),
82
+ apiKeyHeader: parseApiKeyHeader(),
41
83
  };
42
84
  }
43
85
  /**
@@ -46,28 +88,3 @@ function loadConfig() {
46
88
  function getNetworkPassphrase(network) {
47
89
  return network === "mainnet" ? stellar_sdk_1.Networks.PUBLIC : stellar_sdk_1.Networks.TESTNET;
48
90
  }
49
- /**
50
- * Get the per-channel lock TTL in seconds (default 30)
51
- */
52
- function getLockTtlSeconds() {
53
- const raw = process.env.LOCK_TTL_SECONDS;
54
- if (!raw)
55
- return constants_1.CONFIG.DEFAULT_LOCK_TTL_SECONDS;
56
- const n = Number(raw);
57
- if (!Number.isFinite(n) ||
58
- n < constants_1.CONFIG.MIN_LOCK_TTL_SECONDS ||
59
- n > constants_1.CONFIG.MAX_LOCK_TTL_SECONDS) {
60
- return constants_1.CONFIG.DEFAULT_LOCK_TTL_SECONDS;
61
- }
62
- return Math.floor(n);
63
- }
64
- /**
65
- * Get the admin secret for management API
66
- */
67
- function getAdminSecret() {
68
- const v = process.env.PLUGIN_ADMIN_SECRET;
69
- if (!v)
70
- return undefined;
71
- const t = v.trim();
72
- return t.length ? t : undefined;
73
- }
@@ -8,6 +8,7 @@ export declare const HTTP_STATUS: {
8
8
  readonly UNAUTHORIZED: 401;
9
9
  readonly FORBIDDEN: 403;
10
10
  readonly CONFLICT: 409;
11
+ readonly TOO_MANY_REQUESTS: 429;
11
12
  readonly INTERNAL_SERVER_ERROR: 500;
12
13
  readonly BAD_GATEWAY: 502;
13
14
  readonly SERVICE_UNAVAILABLE: 503;
@@ -15,7 +16,7 @@ export declare const HTTP_STATUS: {
15
16
  };
16
17
  export declare const CONFIG: {
17
18
  readonly DEFAULT_LOCK_TTL_SECONDS: 30;
18
- readonly MIN_LOCK_TTL_SECONDS: 10;
19
+ readonly MIN_LOCK_TTL_SECONDS: 3;
19
20
  readonly MAX_LOCK_TTL_SECONDS: 30;
20
21
  };
21
22
  export declare const POOL: {
@@ -38,8 +39,6 @@ export declare const POLLING: {
38
39
  readonly TIMEOUT_MS: 25000;
39
40
  };
40
41
  export declare const FEE: {
41
- readonly MIN_BASE_FEE: 205;
42
- readonly MAX_BASE_FEE: 605;
43
42
  readonly NON_SOROBAN_FEE: 100000;
44
43
  };
45
44
  //# sourceMappingURL=constants.d.ts.map