> ## 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.

# Verifiable Storage

> Cryptographically prove that every ROS 2 data point came from the right robot.

**Verifiable Storage** is more than a storage utility—it is the trust anchor that guarantees on-chain data really originated from your robot. By combining ROS 2 lifecycle management, DID-backed authentication, and IPFS persistence (with optional managed pinning), the bridge turns raw telemetry into signed, auditable evidence.

## Why It Matters

* **Authenticity first** – every ingest request is checked against the robot’s DID and RBAC grants before it ever touches the blockchain.
* **Tamper proof** – payloads are hashed, pinned to IPFS, and referenced on-chain so downstream consumers can verify integrity independently (managed pinning services remain optional).
* **Production ready** – lifecycle nodes, retries, and detailed status topics keep operators informed without leaving ROS tools.

> **Big picture:** ROS 2 fleets can now publish verifiable data streams that regulators, partners, or marketplaces can trust instantly.

## Architecture

| Stage       | What Happens                                                     | Verification Hooks                                                                                          |
| ----------- | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| 1. Ingest   | `StorageIngest` message arrives on `peaq/storage/ingest`         | Bridge loads the robot wallet, derives its DID, and checks it exists on-chain when `require_did` is enabled |
| 2. Encode   | Payload hashed, optional files pinned to IPFS (local or managed) | Hash and DID are logged together; RBAC rules (from the Access module) can gate who triggers ingest          |
| 3. Submit   | Transaction sent via peaq storage pallet                         | Transaction is signed by the robot’s keystore and tracked through `peaq/tx_status`                          |
| 4. Finalize | On-chain record references IPFS CID                              | Any consumer can fetch the CID, recompute the hash, and confirm the signing DID                             |

## Launch the Bridge

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 launch peaq_ros2_core storage_bridge.launch.py \
  config_yaml:=/work/peaq_ros2_examples/config/peaq_robot.yaml \
  log_level:=INFO

ros2 lifecycle set /peaq_storage_bridge configure
ros2 lifecycle set /peaq_storage_bridge activate
```

### Verification-Centric Configuration

```yaml theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
storage_bridge:
  robot:
    require_did: true            # verify robot DID is registered on peaq
  storage:
    mode: both                   # local_ipfs | pinata | both
    pinata:                       # placeholder name used by the default config
      jwt: "<IPFS_GATEWAY_JWT>"   # works with any compatible managed gateway
      gateway_url: "https://your-gateway.example.com/ipfs"
    local_ipfs:
      api_url: "http://127.0.0.1:5001"
      gateway_url: "http://127.0.0.1:8080/ipfs"
  retry:
    max_attempts: 3
    delay_seconds: 5.0

signature:
  algorithm: sr25519             # bridge signs payloads with the robot wallet
```

Secrets for managed gateways (JWT/API keys) and wallet passwords must stay out of source control—load them via environment variables before launch.

## IPFS Setup

### Local IPFS (Kubo)

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
# Install Kubo
wget https://dist.ipfs.tech/kubo/v0.38.1/kubo_v0.38.1_linux-amd64.tar.gz
 tar -xzf kubo_v0.38.1_linux-amd64.tar.gz
 sudo bash kubo/install.sh

# Initialize and start
ipfs init
ipfs daemon
```

Update the config YAML to point at your node:

```yaml theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
storage_bridge:
  storage:
    mode: local_ipfs
    local_ipfs:
      api_url: http://127.0.0.1:5001
      gateway_url: http://127.0.0.1:8080/ipfs
```

Optional quality-of-life settings:

* `local_ipfs.save_dir`: cache directory for downloaded blobs
* `local_ipfs.pin_results=true`: keep data pinned locally for quick replays

### Managed Gateway (Optional)

Use a third-party IPFS pinning/gateway provider (e.g., Pinata, web3.storage, NFT.storage) only if you need off-device persistence or public access. Example environment variables:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
export PEAQ_ROBOT_IPFS_JWT="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
export PEAQ_ROBOT_IPFS_GATEWAY="https://your-gateway.example.com/ipfs"
```

Reference them in the YAML (the `pinata` block name is historical—you can still point it at any managed gateway):

```yaml theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
storage_bridge:
  storage:
    mode: pinata
    pinata:
      jwt: "${PEAQ_ROBOT_IPFS_JWT}"
      gateway_url: "${PEAQ_ROBOT_IPFS_GATEWAY}"
      pin: true
      mode: upload
```

Using both local IPFS and a managed gateway provides redundancy—set `mode: both` to mirror uploads.

### Access Control & Wallets

* Ensure the wallet referenced in `wallet.path` has enough balance on the target network (fund via faucet for Agung).
* Combine with RBAC by allow-listing roles under `storage_bridge.robot.allowlist_roles` when you want to restrict which robots can publish telemetry.

## Publishing Verifiable Data

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 topic pub --once /peaq/storage/ingest \
  peaq_ros2_interfaces/msg/StorageIngest \
  '{key: "robot:telemetry", content: "{\"battery\": 0.87}", is_file: false}'

ros2 topic echo /peaq/storage/status
```

The storage status stream surfaces the CID, IPFS URL, transaction hash, and success state for each submission. Combine it with `peaq/tx_status` to see the confirmation phases tied back to the robot DID in logs.

## Reading & Verifying Downstream

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
ros2 service call /peaq_core_node/storage/read \
  peaq_ros2_interfaces/srv/StoreReadData \
  '{key: "robot:telemetry"}'
```

The response includes the payload, IPFS CID, and the originating DID. Consumers can recompute the hash against the IPFS artifact and ensure it matches the on-chain record.

### Manual Verification Checklist

1. Fetch the CID from the service response.
2. Retrieve the payload: `ipfs cat <CID>` or `curl <gateway>/<CID>`.
3. Recompute the hash and compare with the value logged in storage bridge outputs.
4. Confirm DID ownership using `/peaq_core_node/identity/read`.

## Automated Attestation

* Attach mission metadata via the `metadata_json` field in `StorageIngest` so every record includes firmware versions or profile IDs.
* Pair with the [Access Control](/peaqchain/sdk-reference/robotics-sdk/ros2/core-services/access) guides to revoke publishing rights instantly.
* Leverage `/tmp/storage_bridge_failures.jsonl` and the replay scripts to prove that no data was dropped—even during outages.

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark"}}
python3 scripts/check_storage_failures.py --details
python3 scripts/retry_failed_storage.py --key robot:telemetry
```

## Observability & Audit

* Switch to JSON logs (`PEAQ_ROBOT_LOG_FORMAT=json`) for ingestion into SIEM or compliance tooling.
* Track wallet-derived DID and CID pairs in your log pipeline to detect impersonation attempts.
* Use `ros2 lifecycle get /peaq_storage_bridge` in your health probes; the node exports ready/active states so Kubernetes or fleet managers can react quickly.

### Dashboard Pointers

* `peaq/storage/status`: success vs failure counts
* `/tmp/storage_bridge_failures.jsonl`: monitor size/age to detect backlogs
* `peaq/tx_status`: confirmation latency per network

With verifiable telemetry in place, your ROS 2 fleet can supply zero-trust data to marketplaces, regulators, or partners. Continue with [Event Streams](/peaqchain/sdk-reference/robotics-sdk/ros2/messaging/event-streams) to surface confirmations to autonomy stacks.
