submitAndWait in scripts/deploy.mjs only special-cases sendResult.status === "ERROR":
const sendResult = await server.sendTransaction(prepared);
if (sendResult.status === "ERROR") {
throw new Error(`Send failed: ${JSON.stringify(sendResult.errorResult)}`);
}
let getResult = await server.getTransaction(sendResult.hash);
while (getResult.status === "NOT_FOUND") { ... }
Soroban RPC's sendTransaction can also return "TRY_AGAIN_LATER" (the node's submission queue was full — this is a real, documented, not-uncommon status, distinct from a hard failure) or "DUPLICATE" (already-submitted). Neither is detected here; the code unconditionally falls through to polling getTransaction for a hash that, in the TRY_AGAIN_LATER case, may never actually have been accepted — producing a confusing hang or an opaque NOT_FOUND-forever loop rather than surfacing the real "the node asked you to retry" signal and actually retrying. Given this script is documented as the deploy fallback for exactly the kind of flaky-network environment where TRY_AGAIN_LATER is likeliest to occur, handling it explicitly (retry with backoff) would meaningfully improve reliability.
submitAndWaitinscripts/deploy.mjsonly special-casessendResult.status === "ERROR":Soroban RPC's
sendTransactioncan also return"TRY_AGAIN_LATER"(the node's submission queue was full — this is a real, documented, not-uncommon status, distinct from a hard failure) or"DUPLICATE"(already-submitted). Neither is detected here; the code unconditionally falls through to pollinggetTransactionfor a hash that, in theTRY_AGAIN_LATERcase, may never actually have been accepted — producing a confusing hang or an opaqueNOT_FOUND-forever loop rather than surfacing the real "the node asked you to retry" signal and actually retrying. Given this script is documented as the deploy fallback for exactly the kind of flaky-network environment whereTRY_AGAIN_LATERis likeliest to occur, handling it explicitly (retry with backoff) would meaningfully improve reliability.