@openzeppelin/relayer-plugin-channels 0.3.1 → 0.5.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 +189 -3
- package/dist/client/channels-client.d.ts +50 -1
- package/dist/client/channels-client.d.ts.map +1 -1
- package/dist/client/channels-client.js +90 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/types.d.ts +64 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/plugin/config.d.ts +5 -13
- package/dist/plugin/config.d.ts.map +1 -1
- package/dist/plugin/config.js +46 -45
- package/dist/plugin/constants.d.ts +3 -3
- package/dist/plugin/constants.d.ts.map +1 -1
- package/dist/plugin/constants.js +4 -3
- package/dist/plugin/fee-tracking.d.ts +81 -0
- package/dist/plugin/fee-tracking.d.ts.map +1 -0
- package/dist/plugin/fee-tracking.js +146 -0
- package/dist/plugin/fee.d.ts +2 -3
- package/dist/plugin/fee.d.ts.map +1 -1
- package/dist/plugin/fee.js +6 -14
- package/dist/plugin/handler.d.ts.map +1 -1
- package/dist/plugin/handler.js +36 -10
- package/dist/plugin/management.d.ts +5 -1
- package/dist/plugin/management.d.ts.map +1 -1
- package/dist/plugin/management.js +113 -18
- package/dist/plugin/pool.d.ts +1 -1
- package/dist/plugin/pool.d.ts.map +1 -1
- package/dist/plugin/pool.js +4 -6
- package/dist/plugin/simulation.d.ts +3 -2
- package/dist/plugin/simulation.d.ts.map +1 -1
- package/dist/plugin/simulation.js +49 -7
- package/dist/plugin/submit.d.ts +2 -1
- package/dist/plugin/submit.d.ts.map +1 -1
- package/dist/plugin/submit.js +10 -2
- package/package.json +13 -13
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)
|
|
@@ -210,13 +214,16 @@ Set the required environment variables for the plugin:
|
|
|
210
214
|
```bash
|
|
211
215
|
# Required environment variables
|
|
212
216
|
export STELLAR_NETWORK="testnet" # or "mainnet"
|
|
213
|
-
export SOROBAN_RPC_URL="https://soroban-testnet.stellar.org"
|
|
214
217
|
export FUND_RELAYER_ID="channels-fund"
|
|
215
218
|
export PLUGIN_ADMIN_SECRET="your-secret-here" # Required for management API
|
|
216
219
|
|
|
217
220
|
# Optional environment variables
|
|
218
221
|
export LOCK_TTL_SECONDS=10 # default: 30, min: 3, max: 30
|
|
219
|
-
|
|
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)
|
|
220
227
|
```
|
|
221
228
|
|
|
222
229
|
Your Relayer should now contain:
|
|
@@ -342,6 +349,127 @@ curl -X POST http://localhost:8080/api/v1/plugins/channels/call \
|
|
|
342
349
|
}
|
|
343
350
|
```
|
|
344
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
|
+
|
|
345
473
|
**Important Notes:**
|
|
346
474
|
|
|
347
475
|
- You must configure at least one channel account before the plugin can process transactions
|
|
@@ -478,6 +606,47 @@ console.log(result.ok); // true
|
|
|
478
606
|
console.log(result.appliedRelayerIds); // ['channel-001', 'channel-002', 'channel-003']
|
|
479
607
|
```
|
|
480
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
|
+
|
|
481
650
|
### Error Handling
|
|
482
651
|
|
|
483
652
|
The client provides three types of errors:
|
|
@@ -532,6 +701,10 @@ import type {
|
|
|
532
701
|
ChannelsTransactionResponse,
|
|
533
702
|
ListChannelAccountsResponse,
|
|
534
703
|
SetChannelAccountsResponse,
|
|
704
|
+
GetFeeUsageResponse,
|
|
705
|
+
GetFeeLimitResponse,
|
|
706
|
+
SetFeeLimitResponse,
|
|
707
|
+
DeleteFeeLimitResponse,
|
|
535
708
|
} from "@openzeppelin/relayer-plugin-channels";
|
|
536
709
|
```
|
|
537
710
|
|
|
@@ -540,13 +713,14 @@ import type {
|
|
|
540
713
|
```typescript
|
|
541
714
|
interface ChannelsClientConfig {
|
|
542
715
|
// Required
|
|
543
|
-
baseUrl: string; // Service
|
|
716
|
+
baseUrl: string; // Service URL
|
|
544
717
|
apiKey: string; // API key for authentication
|
|
545
718
|
|
|
546
719
|
// Optional
|
|
547
720
|
pluginId?: string; // Include when connecting to a Relayer directly
|
|
548
721
|
adminSecret?: string; // Required for management operations
|
|
549
722
|
timeout?: number; // Request timeout in ms (default: 30000)
|
|
723
|
+
apiKeyHeader?: string; // Header name for API key (default: 'x-api-key')
|
|
550
724
|
}
|
|
551
725
|
```
|
|
552
726
|
|
|
@@ -660,6 +834,16 @@ Plugin error example:
|
|
|
660
834
|
- **Value**: `{ token: string, lockedAt: ISOString }`
|
|
661
835
|
- **TTL**: Configured by `LOCK_TTL_SECONDS`.
|
|
662
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
|
+
|
|
663
847
|
## Error Codes
|
|
664
848
|
|
|
665
849
|
- `CONFIG_MISSING`: Missing required environment variable
|
|
@@ -677,6 +861,8 @@ Plugin error example:
|
|
|
677
861
|
- `MANAGEMENT_DISABLED`: Management API not enabled
|
|
678
862
|
- `UNAUTHORIZED`: Invalid admin secret
|
|
679
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)
|
|
680
866
|
|
|
681
867
|
## License
|
|
682
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,
|
|
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
|
*
|
|
@@ -221,7 +307,10 @@ class ChannelsClient {
|
|
|
221
307
|
const response = this.validateResponse(responseBody);
|
|
222
308
|
// Handle execution errors
|
|
223
309
|
if (!response.success) {
|
|
224
|
-
|
|
310
|
+
const errorDetails = response.metadata
|
|
311
|
+
? { ...response.data, metadata: response.metadata }
|
|
312
|
+
: response.data;
|
|
313
|
+
throw new errors_1.PluginExecutionError(response.error || "Plugin execution failed", errorDetails);
|
|
225
314
|
}
|
|
226
315
|
// Return data with metadata if present
|
|
227
316
|
return this.mergeMetadata(response.data, response.metadata);
|
package/dist/client/index.d.ts
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/client/types.d.ts
CHANGED
|
@@ -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
|
*/
|
|
@@ -110,6 +170,10 @@ export interface PluginResponseError {
|
|
|
110
170
|
success: false;
|
|
111
171
|
error: string;
|
|
112
172
|
data?: any;
|
|
173
|
+
metadata?: {
|
|
174
|
+
logs?: LogEntry[];
|
|
175
|
+
traces?: any[];
|
|
176
|
+
};
|
|
113
177
|
}
|
|
114
178
|
/**
|
|
115
179
|
* Discriminated union type for all plugin responses
|
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/client/types.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin/config.d.ts
CHANGED
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
export interface ChannelAccountsConfig {
|
|
7
7
|
fundRelayerId: string;
|
|
8
8
|
network: "testnet" | "mainnet";
|
|
9
|
-
|
|
9
|
+
lockTtlSeconds: number;
|
|
10
|
+
adminSecret?: string;
|
|
11
|
+
feeLimit?: number;
|
|
12
|
+
feeResetPeriodMs?: number;
|
|
13
|
+
apiKeyHeader: string;
|
|
10
14
|
}
|
|
11
15
|
/**
|
|
12
16
|
* Load configuration from environment variables
|
|
@@ -16,16 +20,4 @@ export declare function loadConfig(): ChannelAccountsConfig;
|
|
|
16
20
|
* Get the network passphrase based on the configuration
|
|
17
21
|
*/
|
|
18
22
|
export declare function getNetworkPassphrase(network: "testnet" | "mainnet"): string;
|
|
19
|
-
/**
|
|
20
|
-
* Get the per-channel lock TTL in seconds (default 30)
|
|
21
|
-
*/
|
|
22
|
-
export declare function getLockTtlSeconds(): number;
|
|
23
|
-
/**
|
|
24
|
-
* Get the max fee for fee bump transactions
|
|
25
|
-
*/
|
|
26
|
-
export declare function getMaxFee(): number;
|
|
27
|
-
/**
|
|
28
|
-
* Get the admin secret for management API
|
|
29
|
-
*/
|
|
30
|
-
export declare function getAdminSecret(): string | undefined;
|
|
31
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;IAC/B,
|
|
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"}
|