Sidecars

Compass

Shape payment and position intents, and create Solana Pay transfer requests.

0.2.0-alpha.2Alpha capabilityDeclared targets: Windows, Androiduk.capp.sidecar.solana-compass

What it does

Compass turns application requests into consistent, non-authoritative intents. It classifies position actions and can create a complete SOL or original SPL-token payment request, including its Solana Pay transfer URI.

Use it between an application decision and execution policy. It helps the next component understand what was requested; it does not establish whether a recommendation is sensible, which wallet may act or whether funds exist.

Use independently

Select uk.capp.sidecar.solana-compass in local-intent mode. No RPC, wallet, Edge or price feed is required. Use window.capp.solana.compass or the portable client.

Preserve the business operation and position IDs when shaping an intent. For a payment request, save the complete normalized result at your trusted application/server boundary; the URI alone is not its complete validity policy.

Provider dependencies

Method / modeDependencyBehaviour
classify()No peersLocal classification, including in an externally configured Compass. Unknown actions become non-executable previews.
intent() with local-intentNo peersShapes an intent and its digest; no persistence, signing or submission.
intent() with external-adapterYour configured adapterRequests action intent; the service owns its classification/validation contract.
paymentRequest()local-intent onlyLocal request normalization and hashing. External mode is rejected for this method.

Compass is optional in Edge's simple payment flow. Installing Compass does not automatically apply group review, choose an execution bucket or run a strategy.

First successful intent

Call classify() with a known action, then with an unknown action. An opening/increase is exposure-increasing; close/reduce/exit is risk-reducing; hold and unknown actions are not executable. reason labels such as stop-loss are classification inputs, not evidence that an actual position was closed.

For intent(), inspect positionEffect, sendIntent, executable, nonExecutablePreview, authority and intentDigest. Local authority.authoritative is false. Keep actual network policy in Sentinel/Latch: non-token intent() is a shaper rather than a verified RPC-network guard.

Create a saved devnet payment request

Copy the client module alongside this module. Obtain the real recipient and a fresh reference from the payment helpers when creating the request, then persist that reference and the timestamps. Do not regenerate them on retry. This helper is inert until called and performs no payment.

js
import {createSolanaClient} from './solana-client.mjs';
const client = createSolanaClient(() => window.capp?.solana);

export async function makeDevnetRequest({requestId, recipient, reference, amountAtomic, createdAt, expiresAt}) {
  const status = await client.call('compass', 'status');
  if (!status.ready || status.providerMode !== 'local-intent' || status.network !== 'devnet') {
    throw new Error('Configure local Compass for devnet');
  }
  return client.call('compass', 'paymentRequest', {
    requestId, network: 'devnet', recipient, reference,
    asset: {kind: 'native', decimals: 9}, amountAtomic,
    createdAt, expiresAt, label: 'Example request', message: 'Review before paying'
  });
}

amountAtomic: '10000' requests 10,000 lamports, not 10,000 SOL. createdAt and expiresAt are integer Unix seconds, not Date.now() milliseconds. Expect a capp.solana-payment-request.v1 result containing requestDigest, genesisHash, normalized asset, reference, times and uri.

The standard transfer URI does not carry this request's network or expiry. Display those constraints alongside it, retain the full request for verification and use Edge's preparePayment() for the integrated devnet path. A wallet accepting the URI is not proof of a matching, paid invoice.

Amounts, identity and classification

InputMeaning
amountLamports in a native intentA safe integer lamport amount. It is not a floating-point SOL amount.
amountAtomic in a token intent or payment requestA decimal integer string. Use exact helpers for human-unit conversion, not floating-point multiplication.
asset for a tokenExact network, original Token Program, mint and decimals; a symbol such as USDC is not an identity.
createdAtIntent creation time is generated in seconds; save the returned intent for later evaluation.
intentDigestDeterministic content binding excluding generated creation time; not a signature or permission.

Token intents require kind: payment, a supported spl-token asset and amountAtomic; mixing in amountLamports is refused. A native payment request instead uses an asset descriptor such as {kind: native, decimals: 9} and a string atomic amount. Preserve the different method shapes rather than copying fields between them blindly.

Scope and limitations

An intent does not choose a wallet, authorize a payment or establish that a trade is safe. Payment requests contain explicit network/expiry alongside a Solana Pay URI; the standard URI does not encode those constraints.

Local Compass is not a durable invoice store and does not enforce request-ID uniqueness across separate calls. Your application must prevent one business request ID from being issued with conflicting terms. Unknown market actions remain previews; do not turn hold_only into an executable action downstream.

Application API

The owning interface is window.capp.solana.compass. The portable client calls the same methods. This table describes main arguments, not a stricter typed guarantee than the current provider implements. Exact transaction/provider bindings must be preserved; unsupported state or arguments are rejected.

js
import {createSolanaClient} from './solana-client.mjs';
const client = createSolanaClient(() => window.capp?.solana);
const status = await client.call('compass', 'status');

status

client.call('compass', 'status', input)

Main input: No arguments required.

Read intent-provider mode and readiness; never grants authority.

classify

client.call('compass', 'classify', input)

Main input: kind, action or tradeType; optional reason and positionSide.

Classify payment/position intent. Unrecognised and hold-only requests remain non-executable previews.

intent

client.call('compass', 'intent', input)

Main input: operationId; network, kind, recipient and amount fields appropriate to the request.

Normalize request metadata and produce a digest-bound intent. Does not select a wallet or execution resource.

paymentRequest

client.call('compass', 'paymentRequest', input)

Main input: requestId, network, recipient, asset, amountAtomic, reference, createdAt, expiresAt; optional label, message, memo.

Create a versioned request and Solana Pay URI. Uses the local provider. Explicit network and expiry remain separate request constraints.

Troubleshooting

Symptom or errorNext step
Intent is non-executableCheck the action/kind and hold/unknown classification. Do not override it by relabelling the result.
PROVIDER from paymentRequest()Use local-intent; external intent shaping is a different method contract.
Network mismatchMatch the request to the configured network. Never infer the chain from the URI alone.
Invalid amount or assetKeep atomic amounts as strings, native intent lamports as safe integers and token identity explicit.
Same request ID produces different digestsCompare saved times, reference, recipient, asset and amount. Enforce uniqueness at the business owner.

Verify your integration

Test hold/unknown classification, a supported close, exact request reconstruction, invalid decimals, changed recipient and expired request handling downstream. A successful Compass response should produce zero wallet approvals, submissions and fulfilment operations.

Integration recipes

Composition · Devnet payment · Recovery · Typed client · Schemas

These schemas describe payload shape, not evidence of approval or successful execution. Match the version in your payload; older versions remain listed for compatibility.

Configuration reference

These are the selected package's configuration fields. String credential values and installation-specific defaults are never published here. A field's presence does not bypass its runtime policy.

FieldTypeMeaning and constraints
providerModeselectSelect the implementation this build will use. Configuring an endpoint does not verify its connection or behavior.. Choices: local-intent, external-adapter
networkselectMust match the live provider and requests. Arena and demo confirmation always use simulation.. Choices: devnet, testnet, mainnet-beta, demo
defaultAssettextFallback asset symbol for shaped intents. This does not add token-program support by itself.
externalAdapterUrltextAbsolute HTTPS endpoint, or loopback HTTP for development. Keep private credentials on the backend; packaged configuration is visible to users.

Agent interfaces

These names are declared by the package for host/Agent integration, not JavaScript methods to invoke directly. The host must register a tool, grant its scope and enforce its approval policy. A manifest declaration alone does not prove availability in every Agent catalogue. Prefer the application API above when integrating your own app.

ToolDeclared riskApproval requirement
solana.compass.statuslowmode-policy

Component changelog

baseline0.2.0-alpha.2Permalink

Compass

Shape payment and position intents, and create Solana Pay transfer requests.

Documentation snapshot, not a historical release date.
View component notes →
↑ ↓ to navigate · Enter to open · Esc to close. Search stays in your browser.