@openzeppelin/relayer-plugin-channels 0.5.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/dist/plugin/constants.d.ts +0 -2
- package/dist/plugin/constants.d.ts.map +1 -1
- package/dist/plugin/constants.js +0 -2
- package/dist/plugin/fee.d.ts +7 -3
- package/dist/plugin/fee.d.ts.map +1 -1
- package/dist/plugin/fee.js +34 -12
- package/dist/plugin/handler.d.ts +9 -0
- package/dist/plugin/handler.d.ts.map +1 -1
- package/dist/plugin/handler.js +67 -37
- package/dist/plugin/simulation.d.ts +2 -0
- package/dist/plugin/simulation.d.ts.map +1 -1
- package/dist/plugin/simulation.js +32 -13
- package/dist/plugin/submit.d.ts +2 -0
- package/dist/plugin/submit.d.ts.map +1 -1
- package/dist/plugin/submit.js +15 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/plugin/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAGX,eAAO,MAAM,MAAM;;;;CAIT,CAAC;AAGX,eAAO,MAAM,IAAI;;;;;CAOP,CAAC;AAGX,eAAO,MAAM,IAAI;;CAEP,CAAC;AAGX,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAGX,eAAO,MAAM,OAAO;;;CAGV,CAAC;AAEX,eAAO,MAAM,GAAG
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/plugin/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAGX,eAAO,MAAM,MAAM;;;;CAIT,CAAC;AAGX,eAAO,MAAM,IAAI;;;;;CAOP,CAAC;AAGX,eAAO,MAAM,IAAI;;CAEP,CAAC;AAGX,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAGX,eAAO,MAAM,OAAO;;;CAGV,CAAC;AAEX,eAAO,MAAM,GAAG;;CAGN,CAAC"}
|
package/dist/plugin/constants.js
CHANGED
package/dist/plugin/fee.d.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* fee.ts
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* - For Soroban transactions: use resourceFee +
|
|
6
|
-
* - For non-Soroban: use NON_SOROBAN_FEE
|
|
4
|
+
* Static fee calculation for fee bump submissions matching launchtube.
|
|
5
|
+
* - For Soroban transactions: use resourceFee + inclusion fee (BASE_FEE * 2 + 3)
|
|
6
|
+
* - For non-Soroban: use NON_SOROBAN_FEE + inclusion fee
|
|
7
|
+
* - KALE contract gets reduced fee (BASE_FEE * 2 + 1)
|
|
7
8
|
*/
|
|
8
9
|
import { Transaction } from "@stellar/stellar-sdk";
|
|
10
|
+
export declare const KALE_CONTRACT = "CDL74RF5BLYR2YBLCCI7F5FB6TPSCLKEJUBSD2RSVWZ4YHF3VMFAIGWA";
|
|
11
|
+
export declare const INCLUSION_FEE_DEFAULT: number;
|
|
12
|
+
export declare const INCLUSION_FEE_KALE: number;
|
|
9
13
|
export declare function calculateMaxFee(transaction: Transaction): number;
|
|
10
14
|
//# sourceMappingURL=fee.d.ts.map
|
package/dist/plugin/fee.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fee.d.ts","sourceRoot":"","sources":["../../src/plugin/fee.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"fee.d.ts","sourceRoot":"","sources":["../../src/plugin/fee.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAEL,WAAW,EAIZ,MAAM,sBAAsB,CAAC;AAG9B,eAAO,MAAM,aAAa,6DACkC,CAAC;AAC7D,eAAO,MAAM,qBAAqB,QAA2B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA2B,CAAC;AA8B3D,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,CAsBhE"}
|
package/dist/plugin/fee.js
CHANGED
|
@@ -2,14 +2,41 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* fee.ts
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* - For Soroban transactions: use resourceFee +
|
|
7
|
-
* - For non-Soroban: use NON_SOROBAN_FEE
|
|
5
|
+
* Static fee calculation for fee bump submissions matching launchtube.
|
|
6
|
+
* - For Soroban transactions: use resourceFee + inclusion fee (BASE_FEE * 2 + 3)
|
|
7
|
+
* - For non-Soroban: use NON_SOROBAN_FEE + inclusion fee
|
|
8
|
+
* - KALE contract gets reduced fee (BASE_FEE * 2 + 1)
|
|
8
9
|
*/
|
|
9
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.INCLUSION_FEE_KALE = exports.INCLUSION_FEE_DEFAULT = exports.KALE_CONTRACT = void 0;
|
|
10
12
|
exports.calculateMaxFee = calculateMaxFee;
|
|
11
13
|
const stellar_sdk_1 = require("@stellar/stellar-sdk");
|
|
12
14
|
const constants_1 = require("./constants");
|
|
15
|
+
exports.KALE_CONTRACT = "CDL74RF5BLYR2YBLCCI7F5FB6TPSCLKEJUBSD2RSVWZ4YHF3VMFAIGWA";
|
|
16
|
+
exports.INCLUSION_FEE_DEFAULT = Number(stellar_sdk_1.BASE_FEE) * 2 + 3;
|
|
17
|
+
exports.INCLUSION_FEE_KALE = Number(stellar_sdk_1.BASE_FEE) * 2 + 1;
|
|
18
|
+
function getInclusionFee(transaction) {
|
|
19
|
+
try {
|
|
20
|
+
if (transaction.operations.length !== 1)
|
|
21
|
+
return exports.INCLUSION_FEE_DEFAULT;
|
|
22
|
+
const op = transaction.operations[0];
|
|
23
|
+
if (op.type !== "invokeHostFunction")
|
|
24
|
+
return exports.INCLUSION_FEE_DEFAULT;
|
|
25
|
+
const invokeOp = op;
|
|
26
|
+
if (invokeOp.func.switch() !==
|
|
27
|
+
stellar_sdk_1.xdr.HostFunctionType.hostFunctionTypeInvokeContract()) {
|
|
28
|
+
return exports.INCLUSION_FEE_DEFAULT;
|
|
29
|
+
}
|
|
30
|
+
const invokeContract = invokeOp.func.invokeContract();
|
|
31
|
+
const contract = stellar_sdk_1.StrKey.encodeContract(invokeContract.contractAddress().contractId());
|
|
32
|
+
return contract === exports.KALE_CONTRACT
|
|
33
|
+
? exports.INCLUSION_FEE_KALE
|
|
34
|
+
: exports.INCLUSION_FEE_DEFAULT;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return exports.INCLUSION_FEE_DEFAULT;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
13
40
|
function calculateMaxFee(transaction) {
|
|
14
41
|
const envelope = transaction.toEnvelope();
|
|
15
42
|
let resourceFee = 0n;
|
|
@@ -19,15 +46,10 @@ function calculateMaxFee(transaction) {
|
|
|
19
46
|
resourceFee = sorobanData.resourceFee().toBigInt();
|
|
20
47
|
}
|
|
21
48
|
}
|
|
22
|
-
const
|
|
49
|
+
const inclusionFee = getInclusionFee(transaction);
|
|
23
50
|
const fee = resourceFee > 0n
|
|
24
|
-
? resourceFee + BigInt(
|
|
25
|
-
: BigInt(constants_1.FEE.NON_SOROBAN_FEE +
|
|
26
|
-
console.debug(`[channels] Calculated max_fee: ${Number(fee)} stroops (resourceFee: ${resourceFee},
|
|
51
|
+
? resourceFee + BigInt(inclusionFee)
|
|
52
|
+
: BigInt(constants_1.FEE.NON_SOROBAN_FEE + inclusionFee);
|
|
53
|
+
console.debug(`[channels] Calculated max_fee: ${Number(fee)} stroops (resourceFee: ${resourceFee}, inclusionFee: ${inclusionFee})`);
|
|
27
54
|
return Number(fee);
|
|
28
55
|
}
|
|
29
|
-
function getRandomInt(min, max) {
|
|
30
|
-
const mn = Math.ceil(min);
|
|
31
|
-
const mx = Math.floor(max);
|
|
32
|
-
return Math.floor(Math.random() * (mx - mn + 1)) + mn;
|
|
33
|
-
}
|
package/dist/plugin/handler.d.ts
CHANGED
|
@@ -5,6 +5,15 @@
|
|
|
5
5
|
* Orchestrates the transaction processing pipeline using channel accounts with fee bumping.
|
|
6
6
|
*/
|
|
7
7
|
import { PluginContext } from "@openzeppelin/relayer-sdk";
|
|
8
|
+
import { Transaction, xdr } from "@stellar/stellar-sdk";
|
|
9
|
+
/**
|
|
10
|
+
* Extracts func and auth from an unsigned Soroban transaction.
|
|
11
|
+
* Returns null if the transaction is not a single invokeHostFunction operation.
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractFuncAuthFromUnsignedXdr(tx: Transaction): {
|
|
14
|
+
func: xdr.HostFunction;
|
|
15
|
+
auth: xdr.SorobanAuthorizationEntry[];
|
|
16
|
+
} | null;
|
|
8
17
|
/**
|
|
9
18
|
* Main plugin handler exported for OpenZeppelin Relayer
|
|
10
19
|
*/
|
|
@@ -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;
|
|
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;AAcxD;;;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;AAiOD;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CAElE"}
|
package/dist/plugin/handler.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* Orchestrates the transaction processing pipeline using channel accounts with fee bumping.
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.extractFuncAuthFromUnsignedXdr = extractFuncAuthFromUnsignedXdr;
|
|
9
10
|
exports.handler = handler;
|
|
10
11
|
const relayer_sdk_1 = require("@openzeppelin/relayer-sdk");
|
|
11
12
|
const pool_1 = require("./pool");
|
|
@@ -23,8 +24,44 @@ function getApiKey(headers, headerName) {
|
|
|
23
24
|
const values = headers[headerName];
|
|
24
25
|
return values?.[0]?.trim() || undefined;
|
|
25
26
|
}
|
|
26
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Extracts func and auth from an unsigned Soroban transaction.
|
|
29
|
+
* Returns null if the transaction is not a single invokeHostFunction operation.
|
|
30
|
+
*/
|
|
31
|
+
function extractFuncAuthFromUnsignedXdr(tx) {
|
|
32
|
+
const ops = tx.operations;
|
|
33
|
+
if (ops.length !== 1) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const envelope = tx.toEnvelope();
|
|
37
|
+
const rawOp = envelope.v1().tx().operations()[0].body();
|
|
38
|
+
if (rawOp.switch() !== stellar_sdk_1.xdr.OperationType.invokeHostFunction()) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const invokeHostFn = rawOp.invokeHostFunctionOp();
|
|
42
|
+
return {
|
|
43
|
+
func: invokeHostFn.hostFunction(),
|
|
44
|
+
auth: invokeHostFn.auth(),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async function handleXdrSubmit(xdrStr, fundRelayer, fundAddress, network, networkPassphrase, api, pool, tracker) {
|
|
27
48
|
const tx = new stellar_sdk_1.Transaction(xdrStr, networkPassphrase);
|
|
49
|
+
// Unsigned XDR: extract func+auth and route through channel path
|
|
50
|
+
if (tx.signatures.length === 0) {
|
|
51
|
+
const extracted = extractFuncAuthFromUnsignedXdr(tx);
|
|
52
|
+
if (!extracted) {
|
|
53
|
+
throw (0, relayer_sdk_1.pluginError)("Unsigned XDR must contain exactly one invokeHostFunction operation", {
|
|
54
|
+
code: "INVALID_UNSIGNED_XDR",
|
|
55
|
+
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
56
|
+
details: {
|
|
57
|
+
operationCount: tx.operations.length,
|
|
58
|
+
operationType: tx.operations[0]?.type,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
console.log(`[channels] Unsigned XDR detected, extracting func+auth and routing through channel path`);
|
|
63
|
+
return handleFuncAuthSubmit(extracted.func, extracted.auth, api, pool, fundRelayer, fundAddress, network, networkPassphrase, tracker);
|
|
64
|
+
}
|
|
28
65
|
const validated = (0, tx_1.validateExistingTransactionForSubmitOnly)(tx);
|
|
29
66
|
const maxFee = (0, fee_1.calculateMaxFee)(validated);
|
|
30
67
|
await tracker?.checkBudget(maxFee);
|
|
@@ -97,47 +134,40 @@ async function channelAccounts(context) {
|
|
|
97
134
|
resetPeriodMs: config.feeResetPeriodMs,
|
|
98
135
|
});
|
|
99
136
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
const fundStatus = await fundRelayer.getRelayerStatus();
|
|
115
|
-
if (fundStatus.network_type !== "stellar") {
|
|
116
|
-
throw (0, relayer_sdk_1.pluginError)("Fund relayer network type must be stellar", {
|
|
117
|
-
code: "UNSUPPORTED_NETWORK",
|
|
118
|
-
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
119
|
-
details: {
|
|
120
|
-
network_type: fundStatus.network_type,
|
|
121
|
-
relayerId: config.fundRelayerId,
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
// 3. Branch by request type
|
|
126
|
-
if (request.type === "xdr") {
|
|
127
|
-
console.log(`[channels] Flow: XDR submit-only`);
|
|
128
|
-
return await handleXdrSubmit(request.xdr, fundRelayer, config.network, networkPassphrase, api, tracker);
|
|
129
|
-
}
|
|
130
|
-
console.log(`[channels] Flow: func+auth with channel account`);
|
|
131
|
-
return await handleFuncAuthSubmit(request.func, request.auth, api, pool, fundRelayer, fundInfo.address, config.network, networkPassphrase, tracker);
|
|
137
|
+
// 1. Validate and parse request (xdr OR func+auth)
|
|
138
|
+
const request = (0, validation_1.validateAndParseRequest)(params);
|
|
139
|
+
console.debug(`[channels] Request type: ${request.type}, auth entries: ${request.type === "func-auth" ? request.auth.length : "N/A"}`);
|
|
140
|
+
// 2. Get fund relayer
|
|
141
|
+
const fundRelayer = api.useRelayer(config.fundRelayerId);
|
|
142
|
+
const fundInfo = await fundRelayer.getRelayer();
|
|
143
|
+
if (!fundInfo || !fundInfo.address) {
|
|
144
|
+
throw (0, relayer_sdk_1.pluginError)("Fund relayer not found", {
|
|
145
|
+
code: "RELAYER_UNAVAILABLE",
|
|
146
|
+
status: constants_1.HTTP_STATUS.BAD_GATEWAY,
|
|
147
|
+
details: { relayerId: config.fundRelayerId },
|
|
148
|
+
});
|
|
132
149
|
}
|
|
133
|
-
|
|
134
|
-
|
|
150
|
+
if (fundInfo.network_type !== "stellar") {
|
|
151
|
+
throw (0, relayer_sdk_1.pluginError)("Fund relayer network type must be stellar", {
|
|
152
|
+
code: "UNSUPPORTED_NETWORK",
|
|
153
|
+
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
154
|
+
details: {
|
|
155
|
+
network_type: fundInfo.network_type,
|
|
156
|
+
relayerId: config.fundRelayerId,
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// 3. Branch by request type
|
|
161
|
+
if (request.type === "xdr") {
|
|
162
|
+
console.log(`[channels] Flow: XDR submit-only`);
|
|
163
|
+
return await handleXdrSubmit(request.xdr, fundRelayer, fundInfo.address, config.network, networkPassphrase, api, pool, tracker);
|
|
135
164
|
}
|
|
165
|
+
console.log(`[channels] Flow: func+auth with channel account`);
|
|
166
|
+
return await handleFuncAuthSubmit(request.func, request.auth, api, pool, fundRelayer, fundInfo.address, config.network, networkPassphrase, tracker);
|
|
136
167
|
}
|
|
137
168
|
/**
|
|
138
169
|
* Main plugin handler exported for OpenZeppelin Relayer
|
|
139
170
|
*/
|
|
140
171
|
async function handler(context) {
|
|
141
|
-
|
|
142
|
-
return result;
|
|
172
|
+
return channelAccounts(context);
|
|
143
173
|
}
|
|
@@ -12,4 +12,6 @@ export interface ChannelAccount {
|
|
|
12
12
|
sequence: string;
|
|
13
13
|
}
|
|
14
14
|
export declare function simulateAndBuildWithChannel(func: xdr.HostFunction, auth: xdr.SorobanAuthorizationEntry[] | undefined, channel: ChannelAccount, _fundAddress: string, relayer: Relayer, networkPassphrase: string): Promise<Transaction>;
|
|
15
|
+
/** Extract human-readable message + error type from simulation error diagnostic events */
|
|
16
|
+
export declare function parseSimulationError(error: string): string;
|
|
15
17
|
//# sourceMappingURL=simulation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"simulation.d.ts","sourceRoot":"","sources":["../../src/plugin/simulation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAIL,WAAW,EAEX,GAAG,EACJ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,OAAO,EACR,MAAM,2BAA2B,CAAC;AAGnC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,GAAG,CAAC,YAAY,EACtB,IAAI,EAAE,GAAG,CAAC,yBAAyB,EAAE,GAAG,SAAS,EACjD,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,OAAO,EAChB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"simulation.d.ts","sourceRoot":"","sources":["../../src/plugin/simulation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAIL,WAAW,EAEX,GAAG,EACJ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAGL,OAAO,EACR,MAAM,2BAA2B,CAAC;AAGnC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,GAAG,CAAC,YAAY,EACtB,IAAI,EAAE,GAAG,CAAC,yBAAyB,EAAE,GAAG,SAAS,EACjD,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,OAAO,EAChB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,WAAW,CAAC,CAoGtB;AAED,0FAA0F;AAC1F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAe1D"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.simulateAndBuildWithChannel = simulateAndBuildWithChannel;
|
|
11
|
+
exports.parseSimulationError = parseSimulationError;
|
|
11
12
|
const stellar_sdk_1 = require("@stellar/stellar-sdk");
|
|
12
13
|
const relayer_sdk_1 = require("@openzeppelin/relayer-sdk");
|
|
13
14
|
const constants_1 = require("./constants");
|
|
@@ -51,23 +52,26 @@ async function simulateAndBuildWithChannel(func, auth, channel, _fundAddress, re
|
|
|
51
52
|
}
|
|
52
53
|
if (rpcResponse.error) {
|
|
53
54
|
const { code, message, description, data } = rpcResponse.error;
|
|
54
|
-
|
|
55
|
+
console.error(`[channels] RPC error: code=${code}, message=${message}, detail=${description || data}`);
|
|
56
|
+
throw (0, relayer_sdk_1.pluginError)("Simulation RPC failed", {
|
|
55
57
|
code: "SIMULATION_RPC_FAILURE",
|
|
58
|
+
status: constants_1.HTTP_STATUS.BAD_GATEWAY,
|
|
59
|
+
details: { message: "RPC provider error" },
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
const simResult = {
|
|
63
|
+
id: String(rpcResponse.id ?? "1"),
|
|
64
|
+
...rpcResponse.result,
|
|
65
|
+
};
|
|
66
|
+
if ("error" in simResult && simResult.error) {
|
|
67
|
+
console.error(`[channels] Simulation error: ${simResult.error}`);
|
|
68
|
+
throw (0, relayer_sdk_1.pluginError)("Simulation failed", {
|
|
69
|
+
code: "SIMULATION_FAILED",
|
|
56
70
|
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
57
|
-
details: {
|
|
58
|
-
rpcCode: code,
|
|
59
|
-
message,
|
|
60
|
-
description: description || data,
|
|
61
|
-
},
|
|
71
|
+
details: { error: parseSimulationError(simResult.error) },
|
|
62
72
|
});
|
|
63
73
|
}
|
|
64
74
|
try {
|
|
65
|
-
// Format simulation result for SDK's assembleTransaction
|
|
66
|
-
const simResult = {
|
|
67
|
-
id: String(rpcResponse.id ?? "1"),
|
|
68
|
-
...rpcResponse.result,
|
|
69
|
-
};
|
|
70
|
-
console.debug(`[channels] Simulation result:`, JSON.stringify(simResult, null, 2));
|
|
71
75
|
// Use SDK's assembleTransaction to apply simulation results
|
|
72
76
|
const prepared = stellar_sdk_1.rpc
|
|
73
77
|
.assembleTransaction(transaction, simResult)
|
|
@@ -83,7 +87,8 @@ async function simulateAndBuildWithChannel(func, auth, channel, _fundAddress, re
|
|
|
83
87
|
return prepared;
|
|
84
88
|
}
|
|
85
89
|
catch (err) {
|
|
86
|
-
|
|
90
|
+
console.error(`[channels] Assembly error: ${err instanceof Error ? err.message : String(err)}`);
|
|
91
|
+
throw (0, relayer_sdk_1.pluginError)("Simulation failed", {
|
|
87
92
|
code: "SIMULATION_FAILED",
|
|
88
93
|
status: constants_1.HTTP_STATUS.INTERNAL_SERVER_ERROR,
|
|
89
94
|
details: {
|
|
@@ -92,3 +97,17 @@ async function simulateAndBuildWithChannel(func, auth, channel, _fundAddress, re
|
|
|
92
97
|
});
|
|
93
98
|
}
|
|
94
99
|
}
|
|
100
|
+
/** Extract human-readable message + error type from simulation error diagnostic events */
|
|
101
|
+
function parseSimulationError(error) {
|
|
102
|
+
const firstLine = error.split("\n")[0]?.trim() || "Simulation failed";
|
|
103
|
+
const errorType = firstLine.match(/Error\(([^)]+)\)/)?.[1];
|
|
104
|
+
const arrayMatch = error.match(/data:\s*\["((?:[^"\\]|\\.)*)"/);
|
|
105
|
+
if (arrayMatch?.[1] && arrayMatch[1].length > 3) {
|
|
106
|
+
return errorType ? `${arrayMatch[1]} (${errorType})` : arrayMatch[1];
|
|
107
|
+
}
|
|
108
|
+
const stringMatch = error.match(/data:\s*"((?:[^"\\]|\\.)*)"/);
|
|
109
|
+
if (stringMatch?.[1] && stringMatch[1].length > 3) {
|
|
110
|
+
return errorType ? `${stringMatch[1]} (${errorType})` : stringMatch[1];
|
|
111
|
+
}
|
|
112
|
+
return firstLine;
|
|
113
|
+
}
|
package/dist/plugin/submit.d.ts
CHANGED
|
@@ -18,4 +18,6 @@ export declare function signWithChannelAndFund(transaction: Transaction, channel
|
|
|
18
18
|
* Submit transaction with fee bump and wait for confirmation
|
|
19
19
|
*/
|
|
20
20
|
export declare function submitWithFeeBumpAndWait(fundRelayer: Relayer, signedXdr: string, network: "testnet" | "mainnet", maxFee: number, api: PluginAPI, tracker?: FeeTracker): Promise<ChannelAccountsResponse>;
|
|
21
|
+
/** Strip provider wrapper text, extract last segment (e.g., "TxInsufficientBalance") */
|
|
22
|
+
export declare function sanitizeReason(reason: string): string;
|
|
21
23
|
//# sourceMappingURL=submit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../src/plugin/submit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAEL,OAAO,EAGP,SAAS,EACV,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,OAAO,EACvB,YAAY,EAAE,OAAO,EACrB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,WAAW,CAAC,CA2BtB;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,OAAO,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,SAAS,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,uBAAuB,CAAC,
|
|
1
|
+
{"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../src/plugin/submit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAEL,OAAO,EAGP,SAAS,EACV,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,WAAW,EACxB,cAAc,EAAE,OAAO,EACvB,YAAY,EAAE,OAAO,EACrB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,WAAW,CAAC,CA2BtB;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,WAAW,EAAE,OAAO,EACpB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,SAAS,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,UAAU,GACnB,OAAO,CAAC,uBAAuB,CAAC,CAoElC;AAgBD,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAOrD"}
|
package/dist/plugin/submit.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.signWithChannelAndFund = signWithChannelAndFund;
|
|
9
9
|
exports.submitWithFeeBumpAndWait = submitWithFeeBumpAndWait;
|
|
10
|
+
exports.sanitizeReason = sanitizeReason;
|
|
10
11
|
const stellar_sdk_1 = require("@stellar/stellar-sdk");
|
|
11
12
|
const relayer_sdk_1 = require("@openzeppelin/relayer-sdk");
|
|
12
13
|
const constants_1 = require("./constants");
|
|
@@ -62,12 +63,15 @@ async function submitWithFeeBumpAndWait(fundRelayer, signedXdr, network, maxFee,
|
|
|
62
63
|
if (tracker) {
|
|
63
64
|
await tracker.recordUsage(maxFee);
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
+
const rawReason = final.status_reason || "Transaction failed";
|
|
67
|
+
console.error(`[channels] Transaction failed: ${rawReason}`);
|
|
68
|
+
const reason = sanitizeReason(rawReason);
|
|
69
|
+
throw (0, relayer_sdk_1.pluginError)(reason, {
|
|
66
70
|
code: "ONCHAIN_FAILED",
|
|
67
71
|
status: constants_1.HTTP_STATUS.BAD_REQUEST,
|
|
68
72
|
details: {
|
|
69
73
|
status: String(final.status),
|
|
70
|
-
reason
|
|
74
|
+
reason,
|
|
71
75
|
id: final.id,
|
|
72
76
|
hash: final.hash ?? null,
|
|
73
77
|
},
|
|
@@ -108,3 +112,12 @@ function isSignTransactionResponseStellar(data) {
|
|
|
108
112
|
"signature" in data &&
|
|
109
113
|
"signedXdr" in data);
|
|
110
114
|
}
|
|
115
|
+
/** Strip provider wrapper text, extract last segment (e.g., "TxInsufficientBalance") */
|
|
116
|
+
function sanitizeReason(reason) {
|
|
117
|
+
const segments = reason.split(/:\s*/);
|
|
118
|
+
const last = segments[segments.length - 1]?.trim();
|
|
119
|
+
if (last && last.length > 2 && !last.toLowerCase().includes("provider")) {
|
|
120
|
+
return last;
|
|
121
|
+
}
|
|
122
|
+
return reason.length > 100 ? reason.slice(0, 100) + "..." : reason;
|
|
123
|
+
}
|