@stellar/typescript-wallet-sdk 3.0.0-beta.1779920488639 → 3.0.1
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/CHANGELOG.MD +7 -0
- package/lib/bundle.js +20 -9
- package/lib/bundle.js.map +1 -1
- package/lib/bundle_browser.js +20 -9
- package/lib/bundle_browser.js.map +1 -1
- package/lib/walletSdk/Horizon/Stellar.d.ts +15 -4
- package/package.json +2 -2
- package/src/walletSdk/Horizon/Stellar.ts +23 -7
- package/test/stellar.test.ts +6 -5
|
@@ -44,11 +44,22 @@ export declare class Stellar {
|
|
|
44
44
|
*/
|
|
45
45
|
makeFeeBump({ feeAddress, transaction, baseFee, }: FeeBumpTransactionParams): FeeBumpTransaction;
|
|
46
46
|
/**
|
|
47
|
-
* Submits a signed transaction to
|
|
48
|
-
*
|
|
47
|
+
* Submits a signed transaction to Horizon.
|
|
48
|
+
*
|
|
49
|
+
* On HTTP 504 (timeout), retries with exponential backoff up to
|
|
50
|
+
* {@link SUBMIT_504_MAX_RETRIES} times. Any non-504 error is rethrown
|
|
51
|
+
* immediately without retrying.
|
|
52
|
+
*
|
|
49
53
|
* @param {Transaction|FeeBumpTransaction} signedTransaction - The signed transaction to submit.
|
|
50
|
-
* @returns {boolean} `true` if the
|
|
51
|
-
* @throws {TransactionSubmitFailedError} If
|
|
54
|
+
* @returns {boolean} `true` if Horizon confirmed the submission as successful.
|
|
55
|
+
* @throws {TransactionSubmitFailedError} If Horizon responded with a non-successful
|
|
56
|
+
* submission result (the transaction reached Horizon but was rejected).
|
|
57
|
+
* @throws The underlying 504 error if every retry attempt timed out. In this
|
|
58
|
+
* case the transaction's on-chain status is **indeterminate** — Horizon may
|
|
59
|
+
* have ingested it on the final attempt without responding in time. Callers
|
|
60
|
+
* should poll the transaction hash to determine the actual outcome rather
|
|
61
|
+
* than resubmit blindly; resubmitting a signed transaction with the same
|
|
62
|
+
* sequence number will fail with `tx_bad_seq` once the original lands.
|
|
52
63
|
*/
|
|
53
64
|
submitTransaction(signedTransaction: Transaction | FeeBumpTransaction): Promise<boolean>;
|
|
54
65
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stellar/typescript-wallet-sdk",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=20"
|
|
6
6
|
},
|
|
@@ -75,4 +75,4 @@
|
|
|
75
75
|
"example:sep24": "ts-node examples/sep24/sep24.ts",
|
|
76
76
|
"example:sep12": "ts-node examples/sep12/sep12.ts"
|
|
77
77
|
}
|
|
78
|
-
}
|
|
78
|
+
}
|
|
@@ -125,11 +125,22 @@ export class Stellar {
|
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
/**
|
|
128
|
-
* Submits a signed transaction to
|
|
129
|
-
*
|
|
128
|
+
* Submits a signed transaction to Horizon.
|
|
129
|
+
*
|
|
130
|
+
* On HTTP 504 (timeout), retries with exponential backoff up to
|
|
131
|
+
* {@link SUBMIT_504_MAX_RETRIES} times. Any non-504 error is rethrown
|
|
132
|
+
* immediately without retrying.
|
|
133
|
+
*
|
|
130
134
|
* @param {Transaction|FeeBumpTransaction} signedTransaction - The signed transaction to submit.
|
|
131
|
-
* @returns {boolean} `true` if the
|
|
132
|
-
* @throws {TransactionSubmitFailedError} If
|
|
135
|
+
* @returns {boolean} `true` if Horizon confirmed the submission as successful.
|
|
136
|
+
* @throws {TransactionSubmitFailedError} If Horizon responded with a non-successful
|
|
137
|
+
* submission result (the transaction reached Horizon but was rejected).
|
|
138
|
+
* @throws The underlying 504 error if every retry attempt timed out. In this
|
|
139
|
+
* case the transaction's on-chain status is **indeterminate** — Horizon may
|
|
140
|
+
* have ingested it on the final attempt without responding in time. Callers
|
|
141
|
+
* should poll the transaction hash to determine the actual outcome rather
|
|
142
|
+
* than resubmit blindly; resubmitting a signed transaction with the same
|
|
143
|
+
* sequence number will fail with `tx_bad_seq` once the original lands.
|
|
133
144
|
*/
|
|
134
145
|
async submitTransaction(
|
|
135
146
|
signedTransaction: Transaction | FeeBumpTransaction,
|
|
@@ -152,12 +163,17 @@ export class Stellar {
|
|
|
152
163
|
}
|
|
153
164
|
// https://developers.stellar.org/api/errors/http-status-codes/horizon-specific/timeout
|
|
154
165
|
// https://developers.stellar.org/docs/encyclopedia/error-handling#timeouts
|
|
166
|
+
// Equal-jitter backoff: each attempt waits at least half the capped
|
|
167
|
+
// exponential delay (a deterministic, progressive floor) plus a random
|
|
168
|
+
// amount up to the other half. Keeps the schedule predictable while
|
|
169
|
+
// smoothing correlated retries across many clients during a Horizon
|
|
170
|
+
// outage. Total sleep stays within SUBMIT_504_MAX_DELAY_MS.
|
|
155
171
|
const cappedDelay = Math.min(
|
|
156
172
|
SUBMIT_504_BASE_DELAY_MS * 2 ** attempt,
|
|
157
173
|
SUBMIT_504_MAX_DELAY_MS,
|
|
158
174
|
);
|
|
159
|
-
const
|
|
160
|
-
await sleep(
|
|
175
|
+
const half = cappedDelay / 2;
|
|
176
|
+
await sleep(half + Math.random() * half);
|
|
161
177
|
}
|
|
162
178
|
}
|
|
163
179
|
throw lastError;
|
|
@@ -218,7 +234,7 @@ export class Stellar {
|
|
|
218
234
|
if (resultCode === "tx_too_late") {
|
|
219
235
|
const newFee = parseInt(transaction.fee) + baseFeeIncrease;
|
|
220
236
|
|
|
221
|
-
if (maxFee
|
|
237
|
+
if (maxFee && newFee > maxFee) {
|
|
222
238
|
throw new TransactionSubmitWithFeeIncreaseFailedError(maxFee, e);
|
|
223
239
|
}
|
|
224
240
|
|
package/test/stellar.test.ts
CHANGED
|
@@ -282,8 +282,9 @@ describe("Stellar", () => {
|
|
|
282
282
|
const tx = {} as Transaction;
|
|
283
283
|
const promise = stellar.submitTransaction(tx);
|
|
284
284
|
|
|
285
|
-
//
|
|
286
|
-
|
|
285
|
+
// Equal-jitter sleep at attempt 0 with Math.random stubbed to 0 is
|
|
286
|
+
// cappedDelay/2 = 1000/2 = 500ms.
|
|
287
|
+
await clock.tickAsync(500);
|
|
287
288
|
|
|
288
289
|
await expect(promise).resolves.toBe(true);
|
|
289
290
|
expect(serverStub).toHaveBeenCalledTimes(2);
|
|
@@ -311,9 +312,9 @@ describe("Stellar", () => {
|
|
|
311
312
|
// the test runner mid-tick.
|
|
312
313
|
promise.catch(() => undefined);
|
|
313
314
|
|
|
314
|
-
// Sum of
|
|
315
|
-
// 1000 + 2000 + 4000 + 8000
|
|
316
|
-
await clock.tickAsync(
|
|
315
|
+
// Sum of equal-jitter sleeps (cappedDelay/2) with Math.random stubbed
|
|
316
|
+
// to 0: 500 + 1000 + 2000 + 4000 + 8000 = 15500ms.
|
|
317
|
+
await clock.tickAsync(15500);
|
|
317
318
|
|
|
318
319
|
await expect(promise).rejects.toMatchObject({
|
|
319
320
|
response: { status: 504 },
|