Overview
Migrating to confidential intents requires changes in four areas:
The core quoting logic and AMM pricing remain unchanged — the same
token_diff intent structure works for both public and confidential swaps.
Configuration
Environment variables
Add the confidential intents configuration to your environment file:PRIVATE_RELAY_WS_URL, PRIVATE_INTENTS_CONTRACT, PRIVATE_INTENTS_CONTRACT_SALT, PRIVATE_TREASURY_ACCOUNT_ID, and ONE_CLICK_BASE_URL are production constants shared by all solver operators. Only SOLVER_INSTANCE_ID and PARTNER_JWT are solver-specific.Solver mode
Create a mode toggle to switch between public and confidential:Token identifiers
Converting public to private asset IDs
Confidential assets wrap the public token ID with the treasury account:- Subscribing to quote requests
- Checking token pair support
- Building
token_diffintents
For 1Click API balance queries, use the public asset identifiers (without the
imt: prefix). The API strips the prefix from response keys. See the Balance queries section for details.Token configuration
Update the tokens configuration to conditionally use private identifiers:Nonce generation
Versioned nonces
Confidential intents require nonces that encode the contract salt and deadline. UseVersionedNonceBuilder from the intents SDK:
Choosing the nonce strategy
In the quoter service, select the nonce based on the solver mode:Intent signing
Recipient contract
Confidential intents sign against a different contract ID:recipient field in the signed payload uses this active contract:
Intent structure
Thetoken_diff intent structure is identical for both modes — only the asset identifiers and recipient change:
WebSocket connection
Private relay URL
Configure the WebSocket to connect to the private relay with an instance ID for guaranteed delivery:Authentication
Both relays require a Partner JWT in the connection headers:Guaranteed delivery
Quote status acknowledgements
The private relay uses an acknowledgement mechanism to guarantee delivery of quote status updates. When subscribing toquote_status_extended, pass a third parameter to enable acknowledgements:
Processing with acknowledgements
Eachquote_status event includes a sequence number. The solver must acknowledge receipt before processing:
Balance queries
1Click API integration
Confidential balances are not visible on the public NEAR chain. Query them through the 1Click API instead.Authentication
The 1Click API requires an authenticated user token. Generate one by signing an intent:Unified balance method
Switch between on-chain and 1Click queries based on mode. Note that for confidential mode, you need to convert IMT-wrapped token IDs back to public format for the API call:Solver response format
When responding to confidential quote requests, solvers must return their signed intents in theprivate_signed_data bundle. This structure contains up to three signed intents:
SignedData is the same signed-payload shape used everywhere else in the protocol (see publish_intent):
For the full rules on when each of
shield/swap/recover is required (not just their types), see Confidential Intents → Solver response format.shield, swap, and recover is signed the same way, by the solver’s own NEAR key, using the same near-api-js signing flow the Example Solver uses for public token_diff intents (build the message, sign it, bs58-encode the result into public_key/signature). The only thing that changes per intent is the message content, swap signs a token_diff, shield/recover sign whatever transfer/burn intent your Treasury integration expects.
Here’s what a fully populated private_signed_data bundle looks like on the wire, shielding public liquidity before the swap:
shieldsigns atransferintent on the public contract (recipient: "intents.near"), moving your liquidity into the Treasury account.memocarries the encrypted recipient the Private PoA Bridge needs to mint the matching IMT on FAR.swapsigns against the private contract (recipient: "intents.far") and bundles two intents together: thetoken_diff(the actual swap) plus animt_burnthat unshields the received funds immediately instead of leaving them shielded. Itsnoncemust exactly matchrecover’s.recoveralso signs againstintents.far, a singleimt_burnfor the amount that was shielded, using the samenonceasswapso only one of the two can ever execute.
Building the response
When quoting, construct theprivate_signed_data bundle with your signed swap intent:
Depositing liquidity
Before quoting confidential swaps, deposit liquidity from public Intents into your confidential balance.Using the deposit script
The example solver includes a script for shielding liquidity:Withdrawing liquidity
To move liquidity back to public Intents:Running the solver
With liquidity deposited, start the solver in confidential mode:- Connect to the private relay with your instance ID
- Subscribe to confidential quote requests
- Query balances from the 1Click API
- Respond with signed quotes using versioned nonces
- Acknowledge quote status events for guaranteed delivery
Quick reference
Next steps
Confidential Overview
Learn more about the confidential intents architecture
Guaranteed Delivery
Deep dive into the acknowledgement protocol