@openzeppelin/relayer-plugin-channels 0.16.0 → 0.17.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 +88 -2
- package/dist/client/types.d.ts +4 -0
- package/dist/client/types.d.ts.map +1 -1
- package/dist/plugin/config.d.ts +2 -0
- package/dist/plugin/config.d.ts.map +1 -1
- package/dist/plugin/config.js +14 -0
- package/dist/plugin/handler.d.ts.map +1 -1
- package/dist/plugin/handler.js +16 -5
- package/dist/plugin/types.d.ts +3 -0
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/plugin/validation.d.ts.map +1 -1
- package/dist/plugin/validation.js +38 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ A plugin for OpenZeppelin Relayer that enables parallel transaction submission o
|
|
|
16
16
|
- [Development](#development)
|
|
17
17
|
- [Overview](#overview)
|
|
18
18
|
- [Architecture](#architecture)
|
|
19
|
+
- [x402 Fund Relayer](#x402-fund-relayer)
|
|
19
20
|
- [Contract Capacity Limits](#contract-capacity-limits)
|
|
20
21
|
- [Management API](#management-api)
|
|
21
22
|
- [List Channel Accounts](#list-channel-accounts)
|
|
@@ -221,6 +222,8 @@ export FUND_RELAYER_ID="channels-fund"
|
|
|
221
222
|
export PLUGIN_ADMIN_SECRET="your-secret-here" # Required for management API
|
|
222
223
|
|
|
223
224
|
# Optional environment variables
|
|
225
|
+
# Comma-separated list of allowed alternative fund relayers (e.g., for x402 or similar flows)
|
|
226
|
+
export ALLOWED_FUND_RELAYER_IDS="x402-channels-fund"
|
|
224
227
|
export LOCK_TTL_SECONDS=10 # default: 30, min: 3, max: 30
|
|
225
228
|
|
|
226
229
|
# Fee tracking (optional)
|
|
@@ -308,6 +311,71 @@ The Channels plugin accepts Soroban operations and handles all the complexity of
|
|
|
308
311
|
- **Channel Accounts**: Provide unique sequence numbers for parallel transaction submission
|
|
309
312
|
- The channel account is the transaction source and signer; the fund account wraps it in a fee bump
|
|
310
313
|
|
|
314
|
+
## Alternative Fund Relayers
|
|
315
|
+
|
|
316
|
+
The plugin supports optional secondary fund relayers for [x402](https://www.x402.org/) and similar payment flows. Pass `fundRelayerId` in the request and allowlist that ID through `ALLOWED_FUND_RELAYER_IDS`.
|
|
317
|
+
|
|
318
|
+
### Configuration
|
|
319
|
+
|
|
320
|
+
```bash
|
|
321
|
+
export ALLOWED_FUND_RELAYER_IDS="x402-fund"
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
Every allowed alternative fund relayer must reference a relayer configured in your Relayer's `config.json`, just like the primary fund account. Add it alongside your existing relayers:
|
|
325
|
+
|
|
326
|
+
```json
|
|
327
|
+
{
|
|
328
|
+
"id": "x402-fund",
|
|
329
|
+
"name": "x402 Fund Account",
|
|
330
|
+
"network": "testnet",
|
|
331
|
+
"paused": false,
|
|
332
|
+
"network_type": "stellar",
|
|
333
|
+
"signer_id": "x402-fund-signer",
|
|
334
|
+
"policies": {
|
|
335
|
+
"concurrent_transactions": true,
|
|
336
|
+
"fee_payment_strategy": "relayer"
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
### Preferred usage
|
|
342
|
+
|
|
343
|
+
Pass `fundRelayerId` in any `xdr` or `func`+`auth` request to route fee bumping through the specified fund relayer:
|
|
344
|
+
|
|
345
|
+
```bash
|
|
346
|
+
curl -X POST http://localhost:8080/api/v1/plugins/channels/call \
|
|
347
|
+
-H "Authorization: Bearer YOUR_API_KEY" \
|
|
348
|
+
-H "Content-Type: application/json" \
|
|
349
|
+
-d '{
|
|
350
|
+
"params": {
|
|
351
|
+
"xdr": "AAAAAgAAAAB...",
|
|
352
|
+
"fundRelayerId": "x402-fund"
|
|
353
|
+
}
|
|
354
|
+
}'
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
Or with `func`+`auth`:
|
|
358
|
+
|
|
359
|
+
```bash
|
|
360
|
+
curl -X POST http://localhost:8080/api/v1/plugins/channels/call \
|
|
361
|
+
-H "Authorization: Bearer YOUR_API_KEY" \
|
|
362
|
+
-H "Content-Type: application/json" \
|
|
363
|
+
-d '{
|
|
364
|
+
"params": {
|
|
365
|
+
"func": "AAAABAAAAAEAAAAGc3ltYm9s...",
|
|
366
|
+
"auth": ["AAAACAAAAAEAAAA..."],
|
|
367
|
+
"fundRelayerId": "x402-fund"
|
|
368
|
+
}
|
|
369
|
+
}'
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Notes
|
|
373
|
+
|
|
374
|
+
- If `fundRelayerId` is provided but not listed in `ALLOWED_FUND_RELAYER_IDS`, the plugin rejects the request
|
|
375
|
+
- When `fundRelayerId` is omitted, the primary `FUND_RELAYER_ID` is used
|
|
376
|
+
- `fundRelayerId` must be a non-empty string
|
|
377
|
+
- `getTransaction` requests can also include `fundRelayerId`; polling should use the same relayer selection as submission
|
|
378
|
+
|
|
311
379
|
## Contract Capacity Limits
|
|
312
380
|
|
|
313
381
|
High-volume contracts can monopolize the channel pool, starving other traffic. Contract capacity limits allow you to reserve a portion of the pool for non-limited contracts.
|
|
@@ -671,6 +739,23 @@ const result = await client.submitSorobanTransaction({
|
|
|
671
739
|
console.log(result.hash);
|
|
672
740
|
```
|
|
673
741
|
|
|
742
|
+
#### Submit with Alternative Fund Relayer
|
|
743
|
+
|
|
744
|
+
```typescript
|
|
745
|
+
// Submit using an alternative fund relayer for fee bumping
|
|
746
|
+
const result = await client.submitTransaction({
|
|
747
|
+
xdr: 'AAAAAgAAAAC...', // Complete transaction envelope XDR
|
|
748
|
+
fundRelayerId: 'x402-fund',
|
|
749
|
+
});
|
|
750
|
+
|
|
751
|
+
// Also works with func+auth
|
|
752
|
+
const result2 = await client.submitSorobanTransaction({
|
|
753
|
+
func: 'AAAABAAAAAEAAAAGc3ltYm9s...',
|
|
754
|
+
auth: ['AAAACAAAAAEAAAA...'],
|
|
755
|
+
fundRelayerId: 'x402-fund',
|
|
756
|
+
});
|
|
757
|
+
```
|
|
758
|
+
|
|
674
759
|
#### List Channel Accounts (Management)
|
|
675
760
|
|
|
676
761
|
```typescript
|
|
@@ -800,8 +885,8 @@ All request and response types are fully typed:
|
|
|
800
885
|
|
|
801
886
|
```typescript
|
|
802
887
|
import type {
|
|
803
|
-
ChannelsXdrRequest,
|
|
804
|
-
ChannelsFuncAuthRequest,
|
|
888
|
+
ChannelsXdrRequest, // includes optional x402 field
|
|
889
|
+
ChannelsFuncAuthRequest, // includes optional x402 field
|
|
805
890
|
ChannelsTransactionResponse,
|
|
806
891
|
ListChannelAccountsResponse,
|
|
807
892
|
SetChannelAccountsResponse,
|
|
@@ -867,6 +952,7 @@ curl -X POST http://localhost:8080/api/v1/plugins/channels/call \
|
|
|
867
952
|
- `func` (string): Soroban host function XDR (base64)
|
|
868
953
|
- `auth` (array): Array of Soroban authorization entry XDRs (base64)
|
|
869
954
|
- `skipWait` (boolean, optional): When `true`, returns immediately after submitting the transaction without waiting for confirmation. Defaults to `false`. Must be a boolean — non-boolean values (e.g., `"false"`, `1`) are rejected.
|
|
955
|
+
- `fundRelayerId` (string, optional): Uses the specified alternative fund relayer for fee bumping instead of the primary fund account. Must be present in `ALLOWED_FUND_RELAYER_IDS`.
|
|
870
956
|
- `getTransaction` (object, optional): Poll for a transaction's status by ID. Cannot be combined with other parameters.
|
|
871
957
|
|
|
872
958
|
**Note**: Provide either `xdr` OR `func`+`auth` OR `getTransaction`, not a combination.
|
package/dist/client/types.d.ts
CHANGED
|
@@ -44,6 +44,8 @@ export interface ChannelsXdrRequest {
|
|
|
44
44
|
xdr: string;
|
|
45
45
|
/** When true, returns immediately after submission without waiting for confirmation */
|
|
46
46
|
skipWait?: boolean;
|
|
47
|
+
/** Alternative fund relayer ID for fee bumping (must be in the allowed list) */
|
|
48
|
+
fundRelayerId?: string;
|
|
47
49
|
}
|
|
48
50
|
/**
|
|
49
51
|
* Transaction submission using Soroban function and authorization
|
|
@@ -55,6 +57,8 @@ export interface ChannelsFuncAuthRequest {
|
|
|
55
57
|
auth: string[];
|
|
56
58
|
/** When true, returns immediately after submission without waiting for confirmation */
|
|
57
59
|
skipWait?: boolean;
|
|
60
|
+
/** Alternative fund relayer ID for fee bumping (must be in the allowed list) */
|
|
61
|
+
fundRelayerId?: string;
|
|
58
62
|
}
|
|
59
63
|
/**
|
|
60
64
|
* Request to get a transaction by ID
|
|
@@ -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;IACjB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;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;IACZ,uFAAuF;IACvF,QAAQ,CAAC,EAAE,OAAO,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
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export interface ChannelAccountsConfig {
|
|
7
7
|
fundRelayerId: string;
|
|
8
|
+
/** Map of allowed alternative fund relayer IDs (e.g. { "x402-channels-fund": true }) */
|
|
9
|
+
allowedFundRelayerIds: Set<string>;
|
|
8
10
|
network: 'testnet' | 'mainnet';
|
|
9
11
|
lockTtlSeconds: number;
|
|
10
12
|
adminSecret?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/plugin/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,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;IACrB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,2BAA2B,EAAE,MAAM,CAAC;IACpC,kCAAkC,EAAE,MAAM,CAAC;CAC5C;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/plugin/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,MAAM,CAAC;IACtB,wFAAwF;IACxF,qBAAqB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACnC,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;IACrB,gBAAgB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,2BAA2B,EAAE,MAAM,CAAC;IACpC,kCAAkC,EAAE,MAAM,CAAC;CAC5C;AAsHD;;GAEG;AACH,wBAAgB,UAAU,IAAI,qBAAqB,CA2BlD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAE3E"}
|
package/dist/plugin/config.js
CHANGED
|
@@ -105,6 +105,18 @@ function parseSequenceNumberCacheMaxAge() {
|
|
|
105
105
|
const n = Number(raw);
|
|
106
106
|
return Number.isFinite(n) && n > 0 ? Math.floor(n) : constants_1.CONFIG.DEFAULT_SEQUENCE_NUMBER_CACHE_MAX_AGE_MS;
|
|
107
107
|
}
|
|
108
|
+
function parseAllowedFundRelayerIds() {
|
|
109
|
+
const ids = new Set();
|
|
110
|
+
const raw = process.env.ALLOWED_FUND_RELAYER_IDS;
|
|
111
|
+
if (raw) {
|
|
112
|
+
for (const id of raw.split(',')) {
|
|
113
|
+
const trimmed = id.trim();
|
|
114
|
+
if (trimmed.length > 0)
|
|
115
|
+
ids.add(trimmed);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return ids;
|
|
119
|
+
}
|
|
108
120
|
function parseContractCapacityRatio() {
|
|
109
121
|
const raw = process.env.CONTRACT_CAPACITY_RATIO;
|
|
110
122
|
if (!raw)
|
|
@@ -126,8 +138,10 @@ function loadConfig() {
|
|
|
126
138
|
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
127
139
|
});
|
|
128
140
|
}
|
|
141
|
+
const allowedFundRelayerIds = parseAllowedFundRelayerIds();
|
|
129
142
|
return {
|
|
130
143
|
fundRelayerId: requireEnv('FUND_RELAYER_ID'),
|
|
144
|
+
allowedFundRelayerIds,
|
|
131
145
|
network: networkRaw,
|
|
132
146
|
lockTtlSeconds: parseLockTtl(),
|
|
133
147
|
adminSecret: parseOptionalString('PLUGIN_ADMIN_SECRET'),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/plugin/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAe,MAAM,2BAA2B,CAAC;AASvE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AA2BxD;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,WAAW,GACd;IAAE,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,yBAAyB,EAAE,CAAA;CAAE,GAAG,IAAI,CAkB1E;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/plugin/handler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAe,MAAM,2BAA2B,CAAC;AASvE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AA2BxD;;;GAGG;AACH,wBAAgB,8BAA8B,CAC5C,EAAE,EAAE,WAAW,GACd;IAAE,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC;IAAC,IAAI,EAAE,GAAG,CAAC,yBAAyB,EAAE,CAAA;CAAE,GAAG,IAAI,CAkB1E;AA4SD;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CAElE"}
|
package/dist/plugin/handler.js
CHANGED
|
@@ -186,11 +186,22 @@ async function channelAccounts(context) {
|
|
|
186
186
|
resetPeriodMs: config.feeResetPeriodMs,
|
|
187
187
|
});
|
|
188
188
|
}
|
|
189
|
-
//
|
|
189
|
+
// Validate and parse request (xdr OR func+auth)
|
|
190
190
|
const request = (0, validation_1.validateAndParseRequest)(params);
|
|
191
191
|
console.debug(`[channels] Request type: ${request.type}, auth entries: ${request.type === 'func-auth' ? request.auth.length : 'N/A'}`);
|
|
192
|
-
//
|
|
193
|
-
|
|
192
|
+
// Get fund relayer (use alternative fund relayer when requested)
|
|
193
|
+
let fundRelayerId = config.fundRelayerId;
|
|
194
|
+
if (request.fundRelayerId) {
|
|
195
|
+
if (!config.allowedFundRelayerIds.has(request.fundRelayerId)) {
|
|
196
|
+
throw (0, relayer_sdk_1.pluginError)(`Fund relayer '${request.fundRelayerId}' is not in the allowed list`, {
|
|
197
|
+
code: 'CONFIG_MISSING',
|
|
198
|
+
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
199
|
+
details: { fundRelayerId: request.fundRelayerId },
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
fundRelayerId = request.fundRelayerId;
|
|
203
|
+
}
|
|
204
|
+
const fundRelayer = api.useRelayer(fundRelayerId);
|
|
194
205
|
// 2a. Handle get-transaction early — no pool, channel, or simulation needed
|
|
195
206
|
if (request.type === 'get-transaction') {
|
|
196
207
|
const res = await fundRelayer.getTransaction({ transactionId: request.transactionId });
|
|
@@ -206,14 +217,14 @@ async function channelAccounts(context) {
|
|
|
206
217
|
throw (0, relayer_sdk_1.pluginError)('Fund relayer not found', {
|
|
207
218
|
code: 'RELAYER_UNAVAILABLE',
|
|
208
219
|
status: constants_1.HTTP_STATUS.BAD_GATEWAY,
|
|
209
|
-
details: { relayerId:
|
|
220
|
+
details: { relayerId: fundRelayerId },
|
|
210
221
|
});
|
|
211
222
|
}
|
|
212
223
|
if (fundInfo.network_type !== 'stellar') {
|
|
213
224
|
throw (0, relayer_sdk_1.pluginError)('Fund relayer network type must be stellar', {
|
|
214
225
|
code: 'UNSUPPORTED_NETWORK',
|
|
215
226
|
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
216
|
-
details: { network_type: fundInfo.network_type, relayerId:
|
|
227
|
+
details: { network_type: fundInfo.network_type, relayerId: fundRelayerId },
|
|
217
228
|
});
|
|
218
229
|
}
|
|
219
230
|
// 3. Build acquire options for contract capacity limits
|
package/dist/plugin/types.d.ts
CHANGED
|
@@ -13,14 +13,17 @@ export type ChannelAccountsRequest = {
|
|
|
13
13
|
type: 'xdr';
|
|
14
14
|
xdr: string;
|
|
15
15
|
skipWait: boolean;
|
|
16
|
+
fundRelayerId?: string;
|
|
16
17
|
} | {
|
|
17
18
|
type: 'func-auth';
|
|
18
19
|
func: xdr.HostFunction;
|
|
19
20
|
auth: xdr.SorobanAuthorizationEntry[];
|
|
20
21
|
skipWait: boolean;
|
|
22
|
+
fundRelayerId?: string;
|
|
21
23
|
} | {
|
|
22
24
|
type: 'get-transaction';
|
|
23
25
|
transactionId: string;
|
|
26
|
+
fundRelayerId?: string;
|
|
24
27
|
};
|
|
25
28
|
/**
|
|
26
29
|
* Plugin response format aligned with launchtube
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugin/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugin/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;GAIG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GACvE;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC;IACvB,IAAI,EAAE,GAAG,CAAC,yBAAyB,EAAE,CAAC;IACtC,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACD;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE;QACV,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,qBAAqB,GAAG,oBAAoB,CAAC;QACrD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;KACvB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,OAAO,CAAC;IACZ,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/plugin/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/plugin/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAqBjD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,GAAG,GAAG,sBAAsB,CAmJ3E"}
|
|
@@ -10,6 +10,21 @@ exports.validateAndParseRequest = validateAndParseRequest;
|
|
|
10
10
|
const stellar_sdk_1 = require("@stellar/stellar-sdk");
|
|
11
11
|
const relayer_sdk_1 = require("@openzeppelin/relayer-sdk");
|
|
12
12
|
const constants_1 = require("./constants");
|
|
13
|
+
function validateFundRelayerId(params) {
|
|
14
|
+
if (params.fundRelayerId !== undefined &&
|
|
15
|
+
(typeof params.fundRelayerId !== 'string' || params.fundRelayerId.trim() === '')) {
|
|
16
|
+
throw (0, relayer_sdk_1.pluginError)('`fundRelayerId` must be a non-empty string', {
|
|
17
|
+
code: 'INVALID_PARAMS',
|
|
18
|
+
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function parseFundRelayerId(params) {
|
|
23
|
+
if (params.fundRelayerId !== undefined && typeof params.fundRelayerId === 'string') {
|
|
24
|
+
return params.fundRelayerId.trim();
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
13
28
|
function validateAndParseRequest(params) {
|
|
14
29
|
if (!params || typeof params !== 'object') {
|
|
15
30
|
throw (0, relayer_sdk_1.pluginError)('Invalid request: params must be an object', {
|
|
@@ -21,7 +36,7 @@ function validateAndParseRequest(params) {
|
|
|
21
36
|
const keys = Object.keys(params);
|
|
22
37
|
// Mode: getTransaction
|
|
23
38
|
if ('getTransaction' in params) {
|
|
24
|
-
const unknown = keys.filter((k) =>
|
|
39
|
+
const unknown = keys.filter((k) => !['getTransaction', 'fundRelayerId'].includes(k));
|
|
25
40
|
if (unknown.length > 0) {
|
|
26
41
|
throw (0, relayer_sdk_1.pluginError)('`getTransaction` request must not include other parameters', {
|
|
27
42
|
code: 'INVALID_PARAMS',
|
|
@@ -29,6 +44,7 @@ function validateAndParseRequest(params) {
|
|
|
29
44
|
details: { unknown },
|
|
30
45
|
});
|
|
31
46
|
}
|
|
47
|
+
validateFundRelayerId(params);
|
|
32
48
|
const gt = params.getTransaction;
|
|
33
49
|
if (!gt || typeof gt !== 'object' || typeof gt.transactionId !== 'string' || gt.transactionId.trim() === '') {
|
|
34
50
|
throw (0, relayer_sdk_1.pluginError)('`getTransaction.transactionId` must be a non-empty string', {
|
|
@@ -44,7 +60,11 @@ function validateAndParseRequest(params) {
|
|
|
44
60
|
details: { unknown: unknownInner },
|
|
45
61
|
});
|
|
46
62
|
}
|
|
47
|
-
return {
|
|
63
|
+
return {
|
|
64
|
+
type: 'get-transaction',
|
|
65
|
+
transactionId: gt.transactionId.trim(),
|
|
66
|
+
fundRelayerId: parseFundRelayerId(params),
|
|
67
|
+
};
|
|
48
68
|
}
|
|
49
69
|
// Mode: XDR
|
|
50
70
|
if ('xdr' in params) {
|
|
@@ -55,7 +75,7 @@ function validateAndParseRequest(params) {
|
|
|
55
75
|
});
|
|
56
76
|
}
|
|
57
77
|
// Strict: cannot include func/auth when using xdr
|
|
58
|
-
const unknown = keys.filter((k) => !['xdr', 'skipWait'].includes(k));
|
|
78
|
+
const unknown = keys.filter((k) => !['xdr', 'skipWait', 'fundRelayerId'].includes(k));
|
|
59
79
|
if (unknown.length > 0) {
|
|
60
80
|
throw (0, relayer_sdk_1.pluginError)('`xdr` request must not include other parameters', {
|
|
61
81
|
code: 'INVALID_PARAMS',
|
|
@@ -69,7 +89,13 @@ function validateAndParseRequest(params) {
|
|
|
69
89
|
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
70
90
|
});
|
|
71
91
|
}
|
|
72
|
-
|
|
92
|
+
validateFundRelayerId(params);
|
|
93
|
+
return {
|
|
94
|
+
type: 'xdr',
|
|
95
|
+
xdr: params.xdr.trim(),
|
|
96
|
+
skipWait: params.skipWait === true,
|
|
97
|
+
fundRelayerId: parseFundRelayerId(params),
|
|
98
|
+
};
|
|
73
99
|
}
|
|
74
100
|
// Mode: func+auth
|
|
75
101
|
if ('func' in params || 'auth' in params) {
|
|
@@ -113,7 +139,14 @@ function validateAndParseRequest(params) {
|
|
|
113
139
|
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
114
140
|
});
|
|
115
141
|
}
|
|
116
|
-
|
|
142
|
+
validateFundRelayerId(params);
|
|
143
|
+
return {
|
|
144
|
+
type: 'func-auth',
|
|
145
|
+
func,
|
|
146
|
+
auth,
|
|
147
|
+
skipWait: params.skipWait === true,
|
|
148
|
+
fundRelayerId: parseFundRelayerId(params),
|
|
149
|
+
};
|
|
117
150
|
}
|
|
118
151
|
throw (0, relayer_sdk_1.pluginError)('Must pass either `xdr` or `func` and `auth`', {
|
|
119
152
|
code: 'INVALID_PARAMS',
|