Concepts
Cross-device Flow
Order states, events, and device responsibilities.
An order is the shared record between the initiating device, the approving device, and your proof adapter. The order lets both devices coordinate without sharing the same bearer token.
Overview
| Stage | Initiating device | Approving device | Server |
|---|---|---|---|
| Start | Creates the order and displays claimUrl. | Not involved yet. | Stores a short-lived created order. |
| Claim | Subscribes to events with eventToken. | Opens the claim URL with claimToken. | Issues challengeToken. |
| Challenge | Waits for an event. | Reads the challenge and asks the user to approve. | Builds the adapter challenge envelope. |
| Approve | Receives approved. | Submits proof with challengeToken. | Verifies the proof through your adapter. |
| Finalize | Uses desktopToken to consume the result. | Done. | Marks the order finalized and returns session or proof data. |
Tokens are role-specific. The approving device never gets the
desktopToken, and the initiating device never uses the challengeToken.States
| State | Meaning |
|---|---|
created | The initiating device created an order and can show the claim URL. |
claimed | The approving device exchanged the claim token for a challenge token. |
waiting_user | The approving device is showing the challenge to the user. |
approved | The adapter verified the proof. |
rejected | The approving device rejected the order. |
expired | The order passed its TTL. |
cancelled | The initiating device cancelled the order. |
finalized | The initiating device consumed the approved result. |
approved is not terminal. It means the proof passed verification, but the initiating device still needs to finalize the order.
Events
The event stream emits claimed, waiting_user, approved, rejected, expired, cancelled, and finalized.
follow-order.ts
authClient.crossDevice.subscribe({
orderId,
eventToken,
onEvent(event, payload) {
console.log(event, payload.status, payload.redirectTo)
},
})
Terminal events are rejected, expired, cancelled, and finalized. Close the stream after one of those events.
Tokens
| Token | Held by | Purpose |
|---|---|---|
claimToken | Approving device via claim URL | Claim an order. |
challengeToken | Approving device | Read and answer the challenge. |
desktopToken | Initiating device | Cancel or finalize the order. |
eventToken | Initiating device | Subscribe to status changes. |
Failure paths
| Failure | Result |
|---|---|
| Claim token is wrong or expired | Claim fails and no challenge token is issued. |
| Proof is invalid | Adapter throws CrossDeviceProofError; order remains protected from finalization. |
| Order passes its TTL | The next lifecycle read marks it expired. |
| Initiating device cancels | The order becomes cancelled and cannot be approved. |
| Finalize is called twice | The second call is rejected after the finalized result is consumed. |
Next Steps
- Server setup: implement the proof adapter
- Client setup: wire the initiating and approving devices
- Security: review TTLs, origins, and token separation