Detect before Connect
detectWallet() (or wallet.detect()) tells you what the page can offer before any click. It needs no initialize(), answers in about 300 ms and never shows a browser prompt.
unknown-until-connectmeans Chrome would ask for local network access before any page can reach 0xio Desktop. Asking would show that prompt to every visitor, so the SDK waits for a click. Show a Connect button.blockedmeans the visitor denied local network access for your site.not-allowedcoversdesktop: false, a page that is not a secure context, another wallet’s adapter and phones.isMobileBrowser()is the checkdetect()uses; iPads that report a Mac count as mobile.
Which wallet answered
Afterinitialize(), wallet.walletInfo describes the wallet behind the transport:
kind is extension, desktop, app-expo, app-ios or app-android. The 0xio app’s browser speaks the extension channel, so wallet.transport still reads extension there; walletInfo.kind tells them apart. The SDK switches features on capabilities, never on version.
Opening your site in the 0xio app
On a phone without a wallet, offer a link into the 0xio app:null. The SDK never navigates by itself: put the link on a button. The app shows your site’s origin and asks before it opens it, and your site still has to call connect().
Request ids
The SDK makes a request id for every call that opens a review or signs. Make your own withnewRequestId() when you want to store it before the call:
- A request id is 32 lowercase hex characters. Anything else is refused with
INVALID_PARAMS. - Calling again with the same id never opens a second review. It joins the call in flight or returns the stored outcome.
- The same id with another method, other params or another network is refused with
REQUEST_ID_REUSED. - A failed, rejected or expired request never runs again under its id. A new id is a new review the user sees.
{ requestId, timeoutMs, onStatus }. Writes also take wait.
Following a request
Statuses
- A final status never changes.
- A site that is not connected never learns the wallet is locked: its reads answer the same, its review requests get
NOT_CONNECTEDwith no prompt, and its connect readsreview_openwith no update at unlock. It sees no address or network. - Connect from a connected site and a switch to the current network go
pendingtocompletedwith no review. - A page that closes before the user answers closes its review. A request the user already approved finishes, and the reloaded page can read the outcome.
Waiting for the chain
wait: 'submitted' (the default) resolves when the node accepted the transaction, as before. wait: 'confirmed' resolves when the chain executed it:
- Writes resolve with
requestIdandrequestStatuson top of their usual result. The wallet’s ownstatusfield is left as it sent it. - Contract calls and deploys carry
receipt:success,eventsanderror. Octra’s receipt has no return value, so a contract that needs to report a result should emit it as an event. receiptisnullwithreceiptUnavailable: 'refused'when the wallet’s node refuses receipts (the public scanner does), or'error'when the read failed.- A chain rejection or drop rejects with
EXECUTION_FAILED, withdetails.hashanddetails.reason. - Protocol 2 wallets watch the chain for you. With an older wallet the SDK reads
octra_transactionthrough the wallet’s read relay, every 4 seconds for a minute and then every 10 seconds, for at most 10 minutes. If the wallet refuses those reads, the call rejects withUNSUPPORTED_METHODand the hash.
Timeouts
A timeout ends only the SDK’s wait. It never cancels the review and never sends anything again.- A review call whose wait runs out rejects with
STATUS_UNKNOWN, withdetails.requestIdanddetails.lastStatus. The user may still approve it. AskrequestStatus()orwaitForRequest(); never treat it as a failure to retry. - With a protocol 2 wallet the wait restarts on every status change, so a user who reads the review for several minutes does not time your site out.
NETWORK_ERRORmeans the link to the wallet failed. On a review call it carries the request id anddetails.status: 'unknown', because the wallet may still finish the request.timeoutMson a call sets its wait. The default is 3 minutes, 10 minutes for private transfers and on 0xio Desktop.
Errors
Every error of a review call carries
error.requestId. RATE_LIMIT_EXCEEDED names its cause in details.reason:
Pre-signed transactions
submitTransaction(signedTx) broadcasts a transaction from signTransaction() without a second review: the signTransaction review already showed exactly what was signed. It goes pending to submitted. A transaction not signed by the connected wallet is refused with INVALID_PARAMS.
Registering a private receive key
registerPrivateViewKey({ address }) makes the connected wallet able to receive private transfers (its view key on chain) and claim them (a confirmed private key).
There is no free registration. The node derives the view key from the public key a transaction carries, so a fresh account that never sent anything needs that one transaction.
Which wallets speak protocol 2
Older wallets keep working through the SDK’s fallbacks:
walletInfo.protocol reads 1, requestStatus() answers from the SDK’s own record until a reload, and wait: 'confirmed' reads the chain through the wallet.
Building a wallet? See Wallet protocol 2.