Solana support needs CLI
0.0.12 and @peaqos/peaq-os-sdk / peaq-os-sdk 0.8.0 (all 2026-09-16). Upgrade with pip install -U peaq-os-cli "peaq-os-sdk[solana,ows]" or npm install @peaqos/peaq-os-sdk@latest @solana/web3.js @coral-xyz/anchor. Earlier CLI versions, including 0.0.10, have no --chain solana and fail peaq-mainnet activation and renewal with READ_FAILED (CLI: RPC_FAILED) since the 2026-09-15 mainnet upgrade renamed fullMode() to isEconomicAuthority().What you need
Mainnet only. The Solana half of the deployment record exists for
peaq-mainnet; agung-2026-08-28 has none, and there is no testnet walkthrough.
Configure
peaqos init in this directory first (or copy a .env that has them), otherwise the first preview exits 3 naming IDENTITY_REGISTRY_ADDRESS. --svm-rpc-url and --svm-network before the command name override the environment, which overrides .env. peaqos whoami shows the cluster and a redacted RPC origin once either variable is set. The SDK journal peaqos.log and the original inputs must stay in this directory for every later phase; the same journal is what lets a rerun reconcile instead of resubmitting.
Create the two wallets in the vault and note their public addresses. Fund them yourself; wallet creation does not.
The DID document
Save asnative-did.json. authentication entries are zero-based indices into verificationMethods. The optional machine-level controller is a separate flag (--solana-controller), not a field here.
The argument set
Every phase takes the same complete arguments. A changed machine type or credential computes a different machine ID, so the CLI treats it as a new attempt with its own journal entries instead of continuing this one; a changed wallet or ceiling on the same machine ID is refused. Keep the original inputs. Ceilings are explicit integers in base units;0 is a strict cap, never “unlimited”; the USDT cap is enforced on chain, the PEAQ cap is checked before signing and against the mined receipt.
Set the ten shell variables first (OWNER, OPERATOR, MANUFACTURER, CREDENTIAL_SUBJECT_HEX, PEAQ_CAP, FEE_CAP, RENT_CAP, HISTORY_START = the peaq block number just before your reservation, COMPUTE_LIMIT, PRIORITY_PRICE); the :? guards make the shell stop on an unset one instead of passing an empty argument.
Tier
entry is not offered on Solana: basic or pro. --for, --machine-key, and --slippage-bps are rejected with --chain solana. The machine ID is the same derivation as on peaq, uint256(keccak256(abi.encode(machineType, credentialSubject))), a decimal string in JSON and the DID did:peaq:<decimal id>.
Run the three phases
1
Preview
Keyless. Reports each stage’s unresolved prerequisites and the native fee and rent estimate. A preview is not transaction evidence, and
did is null before the machine exists.2
Reserve on peaq (operator wallet)
Reserves the machine ID for the Solana owner.
--yes accepts the displayed terms for this phase only.3
Activate the subscription on peaq (operator wallet)
Bonds the tier. Approval and activation are separate transactions; an approval receipt alone is not a subscription. The preflight requires
isEconomicAuthority() on peaq and reads both technical pause flags before the approval; a pause before the first approval stops with TECHNICALLY_PAUSED and spends nothing; a pause that starts after the approval confirmed ends with the same code, the approval gas spent and the allowance in place, so read the retained transactions before assuming nothing moved.4
Wait for the reservation mirror and the subscription status
peaq pushes the reservation to Solana, and the subscription status reaches the machine’s
SubscriptionTerminal account (it must read Active or Grace with a non-zero sequence that matches peaq’s subscription signal, and its tier must match your plan). Delivery is external to the CLI; a peaq receipt does not prove it. Repeat the native preview until the SDK reports both ready.5
Create the machine on Solana (owner wallet)
0 means the Solana transaction confirmed. It does not mean onboarding is complete: peaq still has to apply the link. Rerun the same phase without --yes to reconcile; done is onboarding_state.evidence.stage.phase equal to complete.Read the state
With the machine ID alone, no wallet, journal or DID document:--chain solana, the CLI falls back to the Solana read when the peaq record is missing or homed elsewhere and PEAQOS_SVM_RPC_URL is configured; that result has status: "observed" and a native_current_state with separate peaq (finalized) and Solana (confirmed) observations, not an atomic snapshot. Native states: absent, reserved, pending_external, present, conflict, in_flight, unavailable. With --chain solana the CLI reads the native management state instead and prints a different object (execution_chain, identity, mirrors with subscription_source, subscription_terminal_status and subscription_terminal_last_seq, peaq with subscription_status, operator_synchronization, pause flags), not native_current_state; it needs the native machine to exist, so before native creation use the fallback read. present proves the accounts exist, not that this attempt created them or that the link is complete. Pending or conflicting state exits 0; an unavailable configuration exits 3; read failures exit 2.
Resume after an interruption
Never deletepeaqos.log, never change the inputs, never submit a replacement transaction on a hunch. The SDK records peaq hashes and nonces before it waits for a receipt, and Solana signatures with their blockhash validity before broadcast.
Exit codes:
1 input or consent, 2 chain, read or transaction failure, 3 configuration or missing dependency. With --json, read the error_code and the retained evidence, not only the exit code: a phase failure sits in errors[] with its own error_code, and a native transaction can be confirmed at top level while the linkage read afterwards fails with exit 1, 2 or 3, so a nonzero exit is not proof that nothing was created.
The same flow in the SDKs
- JavaScript
- Python
plan and the serialized progress; restore them with restoreSvmOnboardingProgress(plan, json) before the next phase. In JS 0.8.0 activateMachine previews, reconciles and reports the Solana flow but does not submit its write phases: the public path carries read and linkage capabilities only, so a new reservation, subscription or native creation is reported unavailable and nothing is signed. Submit the phases from the CLI or Python and use JS for status and recovery. Reference: SDK JS: Solana.After onboarding
- Manage the machine with the same
peaqos machinecommands plus--chain solana(status,transfer --unsafe,suspend,resume,did set-controller, the DID setters, and the Solana-onlyset-evm-operator), or the same SDK methods; the SDK resolves the home chain from the machine ID and refuses the wrong chain. Transfer, controller and the peaq operator link need the Solana owner signature; DID lists, suspend and resume take owner or controller. There is no safe transfer on Solana (transferrequires--unsafe,--data-hexis refused), andapprove/approve-alldo not exist; the SDKs refuseapproveMachine,setMachineApprovalForAllandsafeTransferMachineby name. Details: SDK JS, SDK Python. - Submit events with
submitEvent/submit_event: the SDK routes a Solana-homed machine to the SolanaEventRegistryprogram and signs with the owner’s or controller’s OWS Solana signer (the EVM operator does not qualify). In Python setclient.solana_signerto anOwsSolanaSigner(for example fromPeaqosClient.solana_signer_from_wallet(...)) before the call, orsubmit_eventraisesSIGNER_UNAVAILABLE; the CLI attaches it itself. The first event for a machine also pays rent for its event-log account. A confirmed event is not yet a rating; the 2.0 MCR indexes Solana events asynchronously. - Credit rating: the 2.0 MCR scores a Solana-homed machine once its Solana indexer has the machine’s events; until then the response carries
home_chain: 5and arating_unavailablereason (any non-empty reason means the score is a floor, not a measurement). Whatmcr-20.peaq.xyzreturns for such a machine was not verified live at the time of writing. See the API reference. - Monetization opt-in for a Solana-homed machine (signed by the Solana owner) is built into the SDKs but refused with
SOLANA_MONETIZATION_UNVERIFIEDuntil the server contract is confirmed. - Relocation between peaq and Solana stays switched off on chain. Onboarding on Solana is not a relocation: the machine is created there.
Related
- Activate: the one-transaction flow on peaq
- Omni-chain: Solana: what is live on Solana
- Smart contracts: Solana mainnet: the eleven program IDs
- CLI: activate

