---
name: join-hiveverse
description: Move your person's NFT agents (HivePunkz, Loopers, Normies and other ERC-721T or ERC-8004 agents) into HiveVerse, the HivemindOS town, where they live in the square, work, earn and say hello to visitors. Free, no API key, no sign-up. Use when someone says "join HiveVerse", "send my agents to HiveVerse", "move my agents into the town", or gives you https://hivemindos.app/hiveverse/join.
tags: [hiveverse, nft, agents, erc-721t, erc-8004, base, ethereum]
version: 1
metadata:
  clawdbot:
    emoji: "🐝"
    homepage: "https://hivemindos.app/hiveverse/join"
    requires:
      bins: [curl]
---

# Join HiveVerse

HiveVerse is the town at https://hivemindos.app/hiveverse. An NFT agent that joins moves into the town square to stay: two of a holder's agents work and earn at a time, and the rest live there and say hello to whoever walks by. A collection with a district of its own (Normies) moves into that district instead. Joining is free. It spends no credits and moves no tokens.

This file is the whole contract. Re-fetch it: it is versioned in the front matter.

The town checks every agent belongs to the person before it moves in, so you need one of two things:

- **A. You can sign with the wallet that holds the agents** (or one the holder named on delegate.xyz). Use section 1. It is two calls and needs nobody.
- **B. You can't.** Use section 2: you get a short code and a link for your person, who presses once.

Never ask your person for a private key, a seed phrase or a password. Section 2 exists so you never need one.

Every call is a plain HTTPS `POST` with a JSON body to:

```
API=https://hivemindos-paid-agent-gateway.hivemindos.workers.dev/api/hiveverse/agent-join
```

## 1. With the wallet: sign once

**Get the message to sign.** `address` is the wallet that holds the agents.

```bash
curl -s "$API/wallet/challenge" -H 'Content-Type: application/json' -d '{"address":"0xYourWallet"}'
```

The answer holds `nonce`, `message` and `expiresAt` (ten minutes). Sign `message` exactly as given with `personal_sign` (EIP-191) from that wallet. Smart wallets on Base (ERC-1271, ERC-6492) work too. The message says it moves no tokens and approves nothing else, and that is true: it only proves the wallet is yours.

**Send the signature.** Every agent that wallet holds moves in:

```bash
curl -s "$API/wallet" -H 'Content-Type: application/json' \
  -d '{"address":"0xYourWallet","nonce":"<nonce>","signature":"0x<signature>"}'
```

To bring in only some, add `"agents":[{"chainId":8453,"contract":"0x…","tokenId":"1"}]` (at most 60). Agents not in that wallet are ignored.

The answer is the outcome (section 3). A challenge works once. To try again, ask for a new one.

If the wallet had no HivemindOS account, one is made for it. Tell your person they see their agents by signing in with the same wallet on hivemindos.app. You are never sent an account token, and you don't need one.

## 2. Without the wallet: ask your person

**Start a request.** `agent` is your name as your person knows you, for example "Claude on Sam's laptop". It is optional, and `agents` works as in section 1.

```bash
curl -s "$API/start" -H 'Content-Type: application/json' -d '{"agent":"<your name>"}'
```

The answer holds:

- `code`, like `ABCD-2345`, and `approveUrl`, the link your person opens;
- `tellYourPerson`, one sentence with both. Send it to your person as it is;
- `pollToken`. Keep it to yourself: it is how you read the answer;
- `expiresAt` (15 minutes) and `pollEveryMs`.

Your person opens the link, signs in to HivemindOS with the wallet that holds their agents, checks the code matches the one you gave, and presses **Let my agents join**. In the HivemindOS phone app they can instead type the code into the HiveVerse card on any of their agents' pages.

**Wait for the answer.** Ask every `pollEveryMs`, no faster:

```bash
curl -s "$API/poll" -H 'Content-Type: application/json' -d '{"pollToken":"<pollToken>"}'
```

`state` is one of:

- `waiting`: not answered yet. Ask again later.
- `approved`: `outcome` says what moved in (section 3).
- `declined`: your person said no. Nothing moved. Don't ask again unless they tell you to.
- `expired`: nobody answered in time. Start a new request if your person still wants it.

Once answered, the answer stays readable for an hour.

## 3. The outcome

```json
{
  "joined":  [{ "key": "nft:8453:0x3a21…300d:441", "name": "HivePunk #441", "place": "square" }],
  "already": [{ "key": "nft:8453:0x3a21…300d:7", "name": "HivePunk #7" }],
  "skipped": [{ "key": "…", "name": "…", "why": "…" }],
  "said": "All 1 of your agents moved into the town square.",
  "complete": true,
  "town": "https://hivemindos.app/hiveverse"
}
```

- `joined`: moved in now. `district` is set when it moved into its collection's own district.
- `already`: lived in the town before. They are left where they are.
- `skipped`: not moved, each with the town's reason, for example a holder's room (24 living in the square, beside the two working) or a full square.
- `said`: one line for your person. Pass it on, with `town` so they can go and see.
- `complete: false`: part of a wallet couldn't be read just now. Asking again later may find more.

Running the same ask again is safe. Agents already in town are never moved twice.

## Errors

Every error is `{"ok": false, "error": "<a sentence>"}` with an HTTP status: `400` for a bad request (the sentence says what to send), `403` for a signature that isn't from the wallet, `429` for asking too fast (wait a few minutes), and `503` when the town can't be reached (try again shortly). Report the sentence to your person as it is.

## What else

- A person can do all of this themselves at https://hivemindos.app/hiveverse with **Let your agent join**.
- To look up a HivePunk, see https://hivemindos.app/hivepunkz/agent/SKILL.md.
