> ## Documentation Index
> Fetch the complete documentation index at: https://docs.peaq.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# ROS 2 machine runtime

> Run peaqOS machine onboarding, MCR, events, smart accounts, and Machine NFT bridge flows from ROS 2.

This guide is for teams that use ROS 2 as the robot control plane and want peaqOS as the machine identity, credit, and asset layer.

The ROS 2 node wraps the same peaqOS capabilities documented in the [JavaScript SDK](/peaqos/sdk-reference/sdk-js) and [Python SDK](/peaqos/sdk-reference/sdk-python), but changes the security boundary: callers pass EVM addresses over ROS, while signing keys stay in a local registry file.

## Prerequisites

* ROS 2 Jazzy on a native host, or the repository Docker image with ROS 2 Humble
* A peaq EVM RPC endpoint
* `https://mcr.peaq.xyz` for MCR reads
* `https://depinstation.peaq.network` for Gas Station flows
* A funded peaq EVM signer for registration, minting, events, smart accounts, and bridge transactions
* Base ETH on the signer only if you need Base to peaq bridge operations

## Configure

Create a local config:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
cp peaq_ros2_examples/config/peaq_robot.example.yaml \
   peaq_ros2_examples/config/peaq_robot.yaml
```

Set the peaqOS section:

```yaml theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
peaq_os:
  enabled: true
  rpc_url: "https://quicknode1.peaq.xyz"
  api_url: "https://mcr.peaq.xyz"

  faucet:
    base_url: "https://depinstation.peaq.network"
    qr_format: "svg"

  wallet_registry:
    path: "~/.peaq_robot/peaqos_wallets.json"
```

<Warning>
  Do not commit `peaq_robot.yaml` after adding real addresses, local registry paths, or operational credentials.
</Warning>

## Build and start

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
source /opt/ros/jazzy/setup.bash
# In the Docker image, use: source /opt/ros/humble/setup.bash
python3 -m pip install -r requirements.txt

colcon build --packages-select peaq_ros2_interfaces peaq_ros2_peaqos peaq_ros2_examples
source install/setup.bash

ros2 run peaq_ros2_peaqos peaqos_node --ros-args \
  -p config.yaml_path:=peaq_ros2_examples/config/peaq_robot.yaml
```

Open another terminal, source the same ROS environment, then call services.

## 1. Create a local machine wallet

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/wallet/create \
  peaq_ros2_interfaces/srv/PeaqosCreateWallet \
  "{label: 'robot-001'}"
```

Save the returned address. The private key is stored in the local registry and is not returned.

You can inspect or remove local wallet metadata without exposing keys:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/wallet/list \
  peaq_ros2_interfaces/srv/PeaqosListWallets \
  "{}"

ros2 service call /peaqos_node/wallet/get \
  peaq_ros2_interfaces/srv/PeaqosGetWallet \
  "{address: '<MACHINE_EVM_ADDRESS>'}"
```

The returned wallet JSON includes public peaq EVM account metadata:
`address`, `account_id`, `chain_id`, `network`, `label`, and `created_at`.

## 2. Fund the machine wallet

Registration signs from the machine wallet and requires enough native peaq for gas plus the IdentityRegistry registration bond. Fund the returned `<MACHINE_EVM_ADDRESS>` before calling `register`.

You can use the Gas Station flow with owner 2FA:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/faucet/setup_2fa \
  peaq_ros2_interfaces/srv/PeaqosSetupFaucet2FA \
  "{owner_address: '<OWNER_EVM_ADDRESS>', qr_format: 'svg'}"

ros2 service call /peaqos_node/faucet/confirm_2fa \
  peaq_ros2_interfaces/srv/PeaqosConfirmFaucet2FA \
  "{owner_address: '<OWNER_EVM_ADDRESS>', two_factor_code: '123456'}"

ros2 service call /peaqos_node/wallet/fund \
  peaq_ros2_interfaces/srv/PeaqosFundWallet \
  "{owner_address: '<OWNER_EVM_ADDRESS>', target_address: '<MACHINE_EVM_ADDRESS>', chain_id: '3338', two_factor_code: '123456', request_id: ''}"
```

Or transfer native peaq directly to `<MACHINE_EVM_ADDRESS>` from an already funded wallet. Wait for the balance to be available before registration.

## 3. Register the machine

For a self-managed machine, the node looks up `<MACHINE_EVM_ADDRESS>` in the local registry and signs the registration transaction with that wallet.

For a self-managed machine:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/machine/register \
  peaq_ros2_interfaces/srv/PeaqosRegisterMachine \
  "{address: '<MACHINE_EVM_ADDRESS>'}"
```

For a proxy operator:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/machine/register_for \
  peaq_ros2_interfaces/srv/PeaqosRegisterFor \
  "{proxy_address: '<PROXY_EVM_ADDRESS>', machine_address: '<MACHINE_EVM_ADDRESS>'}"
```

Registration returns `machine_id`. This is the IdentityRegistry machine ID. It is not necessarily the Machine NFT token ID.

## 4. Mint the Machine NFT and write DID attributes

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/nft/mint \
  peaq_ros2_interfaces/srv/PeaqosMintNft \
  "{signer_address: '<SIGNER_EVM_ADDRESS>', machine_id: 1, recipient: '<MACHINE_EVM_ADDRESS>'}"
```

Read the Machine NFT token ID:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/nft/token_id_of \
  peaq_ros2_interfaces/srv/PeaqosTokenIdOf \
  "{signer_address: '<SIGNER_EVM_ADDRESS>', machine_id: 1}"
```

Link the machine's DID to its Machine NFT and metadata endpoints:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/did/write_machine_attributes \
  peaq_ros2_interfaces/srv/PeaqosWriteMachineDidAttributes \
  "{signer_address: '<SIGNER_EVM_ADDRESS>', machine_id: 1, nft_token_id: 1, operator_did: 'did:peaq:<OPERATOR_EVM_ADDRESS>', documentation_url: 'https://docs.example/robot-001', data_api: 'https://api.example/robot-001', data_visibility: 'onchain'}"
```

Verify a single attribute:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/did/read_attribute \
  peaq_ros2_interfaces/srv/PeaqosReadDidAttribute \
  "{signer_address: '<SIGNER_EVM_ADDRESS>', did_address: '<MACHINE_EVM_ADDRESS>', name: 'machineId'}"
```

## 5. Query MCR and machine profile

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/mcr/query \
  peaq_ros2_interfaces/srv/PeaqosQueryMcr \
  "{did: 'did:peaq:<MACHINE_EVM_ADDRESS>'}"
```

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/mcr/machine \
  peaq_ros2_interfaces/srv/PeaqosQueryMachine \
  "{did: 'did:peaq:<MACHINE_EVM_ADDRESS>'}"
```

Newly registered machines can return `Provisioned` until enough event history exists.

## 6. Validate and submit events

Validate before broadcasting:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/events/validate \
  peaq_ros2_interfaces/srv/PeaqosValidateEvent \
  "{machine_id: 1, event_type: 1, value: 1, timestamp: 1770000000, raw_data_hex: '0x73656e736f723a6f6b', trust_level: 0, source_chain_id: 3338, source_tx_hash: '', metadata_hex: '0x7b7d'}"
```

Submit one event:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/events/submit \
  peaq_ros2_interfaces/srv/PeaqosSubmitEvent \
  "{signer_address: '<MACHINE_EVM_ADDRESS>', machine_id: 1, event_type: 1, value: 1, timestamp: 1770000000, raw_data_hex: '0x73656e736f723a6f6b', trust_level: 0, source_chain_id: 3338, source_tx_hash: '', metadata_hex: '0x7b7d'}"
```

Batch submission uses `events_json`, a JSON array using the same event field names.

## 7. Predict or deploy a machine smart account

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/smart_account/address \
  peaq_ros2_interfaces/srv/PeaqosGetSmartAccountAddress \
  "{signer_address: '<SIGNER_EVM_ADDRESS>', owner: '<OWNER_EVM_ADDRESS>', machine: '<MACHINE_EVM_ADDRESS>', daily_limit: '', salt: '0'}"
```

Deploy with the same parameters:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/smart_account/deploy \
  peaq_ros2_interfaces/srv/PeaqosDeploySmartAccount \
  "{signer_address: '<SIGNER_EVM_ADDRESS>', owner: '<OWNER_EVM_ADDRESS>', machine: '<MACHINE_EVM_ADDRESS>', daily_limit: '', salt: '0'}"
```

## 8. Bridge Machine NFT from peaq to Base

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/bridge/nft \
  peaq_ros2_interfaces/srv/PeaqosBridgeNft \
  "{signer_address: '<OWNER_EVM_ADDRESS>', token_id: 1, source: 'peaq', destination: 'base', recipient: '<RECIPIENT_EVM_ADDRESS>', base_rpc_url: '', base_nft_address: '', options_hex: ''}"
```

Wait for the NFT to appear on Base:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaqos_node/bridge/wait_arrival \
  peaq_ros2_interfaces/srv/PeaqosWaitForBridgeArrival \
  "{dst_rpc_url: 'https://mainnet.base.org', dst_nft_address: '0xee8A521eA434b11F956E2402beC5eBfa753Babfa', token_id: 1, timeout: 900}"
```

## Production checklist

* Keep `peaq_os.wallet_registry.path` local to the robot or machine.
* Keep the wallet registry file permissioned as `0600`.
* Quote all EVM addresses in ROS YAML service payloads.
* Record pre and post balances for production bridge or payment tests.
* Confirm contract addresses before release if peaqOS publishes a new deployment.
* Fund Base ETH before attempting Base to peaq bridge operations.

## References

* [ROS 2 service catalog](/peaqos/sdk-reference/ros2/services)
* [ROS 2 configuration](/peaqos/sdk-reference/ros2/configuration)
* [Machine NFT concept](/peaqos/concepts/machine-nft)
* [Events concept](/peaqos/concepts/events)
* [Python SDK reference](/peaqos/sdk-reference/sdk-python)
* [JavaScript SDK reference](/peaqos/sdk-reference/sdk-js)
