Submit & Poll Status
After the user signs the order (EIP-712) and the EIP-7702 authorization (see the Signing guide), submit both to the orchestrator and poll until the intent reaches a terminal state.
Submit
POST https://api.sweepster.xyz/intents
Content-Type: application/jsonBody
typescript
interface AuthorizationWire {
address: string; // the per-chain SweepDelegate impl
chainId: number;
nonce: number;
r: string; // "0x..." 32-byte hex
s: string; // "0x..." 32-byte hex
yParity: number;
}
interface SubmitRequestWire {
quoteId: string; // the quote ID from POST /quote
signature: string; // "0x..." — EIP-712 signature of the SweepDelegate order
authorization: AuthorizationWire; // REQUIRED — the user-signed EIP-7702 authorization
}
authorizationis required. The product is EIP-7702-only; a submit without the authorization is rejected with422. There is no Permit2 fallback.
Example
typescript
const submitRes = await fetch("https://api.sweepster.xyz/intents", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
quoteId: quote.id,
signature,
authorization,
}),
});
if (!submitRes.ok) {
const err = await submitRes.json();
throw new Error(`Submit failed: ${err.error}`);
}
const intent = await submitRes.json();
// { id, status: "submitted", txHash?: "0x..." }Response
typescript
interface SubmitResponseWire {
id: string; // intent ID (same as quote ID)
status: IntentStatus; // usually "submitted" on success
txHash?: string; // "0x..." — source tx hash if already broadcast
}Error responses
| Status | Meaning |
|---|---|
| 400 | Invalid quoteId, expired quote, or duplicate submission |
| 422 | Invalid input (bad signature format, or missing authorization) |
| 429 | Rate limit exceeded |
Poll status
Sweep intents go through the following status lifecycle:
quoted → submitted → settled_source → delivered
↘ failed| Status | Meaning |
|---|---|
quoted | Quote created; not yet submitted |
submitted | Signature accepted; source tx broadcast or queued |
settled_source | Source settlement confirmed on-chain; delivery in progress |
delivered | Destination delivery confirmed |
failed | Unrecoverable failure (source revert, bridge failure, etc.) |
Polling loop
typescript
type IntentStatus =
| "quoted" | "submitted" | "settled_source" | "delivered" | "failed";
interface IntentWire {
id: string;
status: IntentStatus;
txHash?: string; // source tx hash
crossChain: boolean;
}
async function pollUntilDone(intentId: string): Promise<IntentWire> {
const TERMINAL: IntentStatus[] = ["delivered", "failed"];
const POLL_INTERVAL_MS = 3000;
const MAX_POLLS = 100; // ~5 minutes
for (let i = 0; i < MAX_POLLS; i++) {
const res = await fetch(`https://api.sweepster.xyz/intents/${intentId}`);
if (!res.ok) {
throw new Error(`GET /intents/${intentId} failed: ${res.status}`);
}
const intent: IntentWire = await res.json();
console.log(`[${i}] status=${intent.status} txHash=${intent.txHash}`);
if (TERMINAL.includes(intent.status)) return intent;
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
}
throw new Error("Intent polling timed out");
}
const finalIntent = await pollUntilDone(intent.id);
if (finalIntent.status === "delivered") {
console.log("Sweep delivered!", finalIntent.txHash);
} else {
console.error("Sweep failed");
}Cross-chain timing
For cross-chain sweeps, the time from submitted to delivered depends on the bridge:
| Bridge | Typical time |
|---|---|
| LI.FI / Across (USDC) | 1–3 minutes |
| Generic bridge | 5–30 minutes |
For same-chain sweeps, delivered is typically confirmed within one block (~2 seconds on Base).
Webhook support (planned)
Push notification webhooks are a planned feature. Until then, polling is the recommended approach.