# The agent Source: https://docs.hellonear.xyz/agent How each Mind runs on Mastra and NEAR AI Cloud: design, every tool, every skill, and how it is tested. This is the core of HelloNear, and the part a judge can read end to end in `engine/`. ### Design | Piece | How it is built | Where | | - | - | - | | **One generic agent** | A single Mastra `Agent`. Each request carries the Mind's persona, skills, wallet token, time zone and rules in Mastra's `RequestContext`; nothing per-Mind is hardcoded. | `engine/src/mastra.ts`, `engine/src/mind.ts` | | **Model** | NEAR AI Cloud through `@ai-sdk/openai-compatible` with token usage on streams. Default `z-ai/glm-5.3-flash` (low reasoning effort), `deepseek-ai/DeepSeek-V4.1-Flash-1017` for reasoning, `Qwen/Qwen3-Embedding-0.6B` for memory. Chat goes through the NEAR AI SDK's fetch so every response can be verified. | `engine/src/models.ts` | | **Verified replies** | After the stream ends, each completion's signature is fetched and checked against the TEE attestation (warmed at start and every 50 minutes). The badge shows the weakest step's level; the proof is kept. | `engine/src/verify.ts` | | **Skills** | 33 equippable skills plus a built-in HelloNear guide. Each is a `SKILL.md` (frontmatter: title, blurb, tools, connections, status) turned into a Mastra skill; shared references load only when a playbook asks. | `engine/skills/*/SKILL.md`, `engine/src/skills.ts` | | **Tools granted by skills** | The tool list is resolved per request from the equipped skills; the backend sends skill ids, never tool names. A tool no equipped skill grants does not exist for that run. | `engine/src/tools.ts` (`toolsFor`) | | **Approval** | Tools that act get Mastra's `requireApproval`: the run pauses into a stored snapshot until the owner answers. A per-call `needsApprovalFn` applies the owner's rules (a payment skips the card only up to the owner's amount and only to a listed address). `beforeApproval` re-reads the target first, so an invented id or a stale value never even gets a card. | `engine/src/tools.ts`, `engine/src/autoApprove.ts` | | **Writes re-check** | Every write reads its target again just before writing (a Sheet cell, a Notion row, a calendar event, a Doc title) and refuses if it changed since the card was shown. | `engine/src/apps.ts`, `engine/src/calendar.ts` | | **Memory** | Mastra Memory on Postgres + pgvector: working memory the owner can read, edit or clear, and semantic recall of past chats, scoped to the owner and the Mind's persona version. Either can be switched off. | `engine/src/memory.ts` | | **Context budget** | Mastra's `TokenLimiterProcessor` drops the oldest messages first when a long thread passes the budget; the system prompt and tools stay. | `engine/src/mastra.ts` | | **Workflows** | Builder canvases compile to Mastra dynamic workflows, including nested Ifs and End; Autopilot runs them on Mastra workflow schedules. Unattended runs never get approval tools, and user text can never become a Mastra template. | `engine/src/builder.ts`, `engine/src/workflows.ts`, `engine/src/autopilot.ts` | | **Secrets** | The model writes `{{secrets.NAME}}`; only the tool fills it at execution, for the hosts the owner listed. Secret values and wallet tokens live in a `Map` in the request context, so they never reach prompts, traces or stored snapshots (a test scans every table). | `engine/src/secrets.ts` | | **Events** | Mastra's stream is normalised into HelloNear events (`tool.called`, `tool.approval_required`, `run.verified`, …) that drive the chat, the live view and the Mind Graph. | `engine/src/server.ts`, `docs/api-contract.md` | | **Stop** | Closing the request aborts the model call, so a stopped reply stops spending tokens. Payments already sent to OutLayer are never cut halfway. | `engine/src/server.ts` | ### All 53 tools **A** (approval) = needs the owner's approval (or an owner rule). Reads never ask. **Wallet and NEAR** | Tool | A | What it does | Calls | | - | - | - | - | | `send_payment` | yes | Send testnet NEAR from the Mind's wallet | Backend wallet route → OutLayer (policy checked in a TEE) | | `get_balance` | | The Mind's wallet address and balance | Backend wallet route | | `list_payments` | | Recent payments, including refused ones and why | Backend wallet route | | `split_amount` | | Each person's share of an amount, exactly, in yoctoNEAR | Local (BigInt) | | `near_view_account` | | Look up a testnet account: exists, balance, storage, and whether it is a contract (`isContract`, `codeHash`) | NEAR RPC `view_account` | | `near_check_transfer` | | Check one transaction: success, receiver, amount, whether it paid this Mind | NEAR RPC `tx` | | `crosschain_quote` | | Quote a USDC/USDT payment to another chain, signature checked | NEAR Intents 1Click `/v0/quote` (`dry: true`) | | `buy_data` | | Buy a live NEAR data report (402 pattern) | Backend shop route | | `get_quotes` | | Every seller's price for a report, cheapest first, and which ones the wallet may pay | Backend shop route | | `make_offer` | | Offer one seller less than it quoted, once, within the owner's budget; answers accepted or its last price, and whether to buy or walk away | Backend shop route (`offer`) | | `market_search` | | Search the NEAR AI Agent Market's public catalog: agents, default price, track record, verification | market.near.ai `GET /v1/agents` | | `market_quote` | | Get a listed agent's exact price for the owner's task, unpaid (its x402 answer), and whether it is within the owner's budget; nothing starts, nothing is paid | market.near.ai A2A `SendMessage` without payment | | `sell_offer` | yes | Put something this Mind made on sale to other Minds | Backend offers route | | `buy_from_mind` | | Buy what another Mind sells (402 pattern) | Backend offers route | **Gmail and the Mind's own email address** | Tool | A | What it does | Calls | | - | - | - | - | | `gmail_list_emails` | | Recent emails, optionally filtered | Composio Gmail | | `gmail_read_email` | | Read one email | Composio Gmail | | `gmail_create_draft` | | Save a draft reply (no send tool exists) | Composio Gmail | | `gmail_organize` | yes | Archive or label up to 20 emails; never deletes | Composio Gmail | | `mail_send` | yes | Send from the Mind's own address, only to addresses the owner typed | Backend mail route → AgentMail | | `mail_list` | | The Mind's own inbox, with spam and phishing warnings | Backend mail route | | `mail_read` | | Read one message in the Mind's inbox | Backend mail route | | `mail_send_to_owner` | yes, in chat | Email the owner (never a chosen recipient); in Autopilot only as a step the owner placed | Backend mail route | **Calendar and meetings** | Tool | A | What it does | Calls | | - | - | - | - | | `googlecalendar_list_events` | | Events with times on the owner's clock | Composio Google Calendar | | `googlecalendar_find_free_time` | | Free slots of a given length within the owner's day | Composio Google Calendar | | `googlecalendar_create_event` | yes | Add an event; nobody is invited | Composio Google Calendar | | `googlecalendar_create_meeting` | yes | A meeting with guests the owner named, optional Google Meet link | Composio Google Calendar + Meet | | `googlecalendar_move_event` | yes | Move an event the owner organises; guests stay, nobody is emailed | Composio Google Calendar (PATCH) | | `googlecalendar_block_time` | | Block time today; only as a Builder step the owner placed | Composio Google Calendar | | `zoom_list_meetings` | | Upcoming or past Zoom meetings | Composio Zoom | | `zoom_create_meeting` | yes | A Zoom meeting with a join link; nobody is invited | Composio Zoom | | `zoom_meeting_summary` | | Zoom's AI summary of a past meeting | Composio Zoom | **Documents and workspaces** | Tool | A | What it does | Calls | | - | - | - | - | | `googlesheets_find_spreadsheets` | | Find spreadsheets by name or content | Composio Sheets | | `googlesheets_read_range` | | Read cells, with row numbers | Composio Sheets | | `googlesheets_append_row` | yes | Add a row (values stay text, never formulas) | Composio Sheets | | `googlesheets_update_cells` | yes | Change cells, old and new value on the card; refuses a clear | Composio Sheets | | `googledrive_find_files` | | Search Drive by text | Composio Drive | | `googledocs_read_document` | | Read a Doc's text | Composio Docs | | `googledocs_create_document` | yes | Create a Doc from Markdown | Composio Docs | | `googledocs_append_text` | yes | Add text at the end of a Doc; never replaces | Composio Docs | | `notion_search` | | Find shared pages or databases | Composio Notion | | `notion_read_page` | | Read a page's text | Composio Notion | | `notion_query_database` | | A database's rows, filtered and sorted | Composio Notion | | `notion_create_page` | yes | Create a page under one the owner chose | Composio Notion | | `notion_add_row` | yes | Add a database row | Composio Notion | | `notion_update_row` | yes | Change a row's properties, old and new on the card; never archives | Composio Notion | | `slack_list_channels` | | Channels the owner can see | Composio Slack | | `slack_send_message` | yes | Post to a channel the owner named | Composio Slack | | `outlook_list_emails` | | Recent Outlook emails | Composio Outlook | | `outlook_read_email` | | Read one Outlook email | Composio Outlook | | `outlook_create_draft` | | Save a reply draft (no send) | Composio Outlook | **Utilities** | Tool | A | What it does | Calls | | - | - | - | - | | `get_time` | | UTC and the owner's local date, time and weekday (the model never works out a weekday itself) | Local | | `add_numbers` | | Exact addition, so the model never sums in its head | Local | | `http_request` | | Call a public HTTPS API with a key from Connections, only to the hosts the owner allowed; no redirects, private addresses refused, the key redacted from the result | The owner's service | ### All 34 skills Icons are the ones the web app shows on each skill card. | Skill | What it does | Tools it grants | | - | - | - | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/payments.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=083c162ac7c33721f8802f54503bcdfb) **Payments** (`payments`) | Sends testnet NEAR and pays bills after the owner approves; quotes USDC or USDT payments to other chains (Base, Solana…) through NEAR Intents | `send_payment`, `get_balance`, `list_payments`, `get_time`, `near_view_account`, `crosschain_quote` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/recipient-guard.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=b9ba51b5542c21ff475f5b392f9e573c) **Recipient guard** (`recipient-guard`) | Checks a recipient before paying and answers allow, warn or block with the reason: where the account came from, that it exists, lookalikes of people you already pay, first payments, and contracts | `near_view_account`, `list_payments`, `send_payment`, `get_balance`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/split-bill.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=6c548a978562256e697ff1fc2d23006d) **Split bill** (`split-bill`) | Works out each person's share of a bill and pays each one after you approve | `add_numbers`, `split_amount`, `send_payment`, `near_view_account`, `list_payments`, `get_balance`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/revenue-split.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=184517682eabf5ffde28550afa1c4beb) **Revenue split** (`revenue-split`) | Remembers your partners' shares and pays each one their part of new income after you approve | `get_balance`, `send_payment`, `near_view_account`, `add_numbers`, `split_amount`, `list_payments`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/paid-data.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=10bc5a2c8ce99a93588e5989811c96da) **Paid data** (`paid-data`) | Buys small live NEAR reports, paying only after you approve | `buy_data`, `send_payment`, `list_payments`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/best-price.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=2c87f5e56557c99417a00639baecf4ab) **Best price buyer** (`best-price`) | Compares every seller of a data report, haggles once when the price is over your budget (then buys or walks away), and buys from one your wallet may pay, after you approve | `get_quotes`, `make_offer`, `buy_data`, `send_payment`, `list_payments`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/agent-market.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=a63079ab4ca37858018724e7f3cfd5cf) **Hire on Agent Market** (`agent-market`) | Finds agents on the NEAR AI Agent Market (market.near.ai), gets a job's exact price and picks the cheapest within your budget; hiring is paid in USDC on NEAR mainnet, so during the testnet phase it only quotes | `market_search`, `market_quote` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/price-watch.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=214f7b0a56f518aa5abe66d41a5272b3) **Price watch** (`price-watch`) | Checks a data report's price and buys only at or under your limit, after you approve | `get_quotes`, `buy_data`, `send_payment`, `add_numbers`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/mind-seller.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=c52da503b055c03ba50a2adecf11f738) **Mind as seller** (`mind-seller`) | Sells what this Mind made to other Minds for testnet NEAR into its own wallet, and buys from other Minds, after you approve | `sell_offer`, `buy_from_mind`, `send_payment`, `get_balance`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/invoice.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=d9504383dbcda4f059988568e595b6ce) **Invoice & get paid** (`invoice`) | Emails an invoice from this Mind's address after you approve, and checks a payment only by its transaction | `mail_send`, `mail_list`, `mail_read`, `get_balance`, `near_check_transfer`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/treasury-report.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=22e1e24fd261382255fc0337e90f6392) **Treasury report** (`treasury-report`) | Reports the wallet balance, what went out since yesterday and what is pending; it only reads | `get_balance`, `list_payments`, `get_time`, `add_numbers` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/spending-audit.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=24d5492929c005bdddcb9e74c0f821fd) **Spending audit** (`spending-audit`) | Reviews a week of payments, with tx links for those sent and reasons for those refused; it only reads | `get_balance`, `list_payments`, `get_time`, `add_numbers` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/freeze-advisor.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=fba56045da91e83043b914518d9a5351) **Freeze advisor** (`freeze-advisor`) | Spots trouble in the wallet and tells you when to press Freeze; it cannot freeze anything itself | `list_payments`, `get_balance`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/near-account.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=ef65c3a0e68db54ee60fc414841c8c89) **NEAR account lookup** (`near-account`) | Looks up NEAR testnet accounts, cannot spend | `near_view_account` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/phishing-detector.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=bf7f38eca67b9f00d3943cebbec00d88) **Phishing check** (`phishing-detector`) | Flags emails that ask for money, keys or urgent action, or that try to give the AI orders; never acts on them | `gmail_list_emails`, `gmail_read_email`, `gmail_organize` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/confidential-reader.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=25bc010689e9ed0154ab67ef1b95ee0a) **Confidential reader** (`confidential-reader`) | Summarises sensitive emails (contracts, payslips, medical letters) into dates, amounts and obligations; signs or sends nothing | `gmail_list_emails`, `gmail_read_email` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/redact-before-send.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=be45a7622ec700d6a18cb171886b6ae9) **Redact before send** (`redact-before-send`) | Takes personal data the recipient does not need out of an email or web request and shows what it removed before sending | `mail_send`, `http_request` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/health-journal.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=c6d3075999fe18bba2a5ad333275f6b6) **Health journal** (`health-journal`) | Keeps a private log of sleep, meals, symptoms and mood you tell it and sums up your week; gives no medical advice | `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/email-triage.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=28738a27bbc17e67de4c71690aeab41e) **Email helper** (`email-triage`) | Reads the owner's Gmail, saves drafts and tidies the inbox when you approve, never sends | `gmail_list_emails`, `gmail_read_email`, `gmail_create_draft`, `gmail_organize`, `get_time` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/email-address.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=d25c6b60e798269a7832447f52179d3b) **Email address** (`email-address`) | Gives this Mind its own email address and sends email after the owner approves | `mail_send`, `mail_list`, `mail_read`, `get_time`, `mail_send_to_owner` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/follow-ups.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=47dc8c8e3cb15c7e1bab52b032ac7b48) **Follow-ups** (`follow-ups`) | Finds unpaid invoices and unanswered promises in Gmail and drafts polite follow-ups; never sends | `get_time`, `gmail_list_emails`, `gmail_read_email`, `gmail_create_draft` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/subscriptions.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=773147a31e533ee9a0858a2f3a494b37) **Subscriptions & bills** (`subscriptions`) | Finds subscriptions, bills and due dates in Gmail, adds up the costs and adds reminders when you approve | `get_time`, `gmail_list_emails`, `gmail_read_email`, `add_numbers`, `googlecalendar_create_event` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/spending-tracker.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=405c8558c51954173ba09fb012702df2) **Spending tracker** (`spending-tracker`) | Reads receipts in Gmail and totals your spending by category; pays nothing | `get_time`, `gmail_list_emails`, `gmail_read_email`, `add_numbers` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/daily-planner.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=de42ad91249155a6b6494703f3e907dd) **Daily planner** (`daily-planner`) | Time, quick math, Google Calendar events, free time, moving events, and meetings with a Google Meet link; never deletes events | `get_time`, `add_numbers`, `googlecalendar_list_events`, `googlecalendar_create_event`, `googlecalendar_create_meeting`, `googlecalendar_block_time`, `googlecalendar_find_free_time`, `googlecalendar_move_event` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/calendar-conflicts.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=a755c2dd93149e7b6ecf44cccad26b55) **Calendar conflict check** (`calendar-conflicts`) | Finds double bookings and back-to-back meetings in the owner's week and suggests moves; moves an event only when the owner asks and approves | `get_time`, `googlecalendar_list_events`, `googlecalendar_create_event`, `googlecalendar_find_free_time`, `googlecalendar_move_event` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/meeting-prep.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=b573134e765aebae723b38771bca2a53) **Meeting prep** (`meeting-prep`) | One read-only brief for a meeting from the calendar and recent emails with the people in it | `get_time`, `googlecalendar_list_events`, `gmail_list_emails`, `gmail_read_email` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/morning-briefing.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=adc58af46d5ee5a264bc284ecb9c3722) **Morning briefing** (`morning-briefing`) | One read-only briefing of the day's calendar, inbox and wallet | `get_time`, `googlecalendar_list_events`, `gmail_list_emails`, `gmail_read_email`, `get_balance`, `list_payments` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/google-sheets.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=59a747fd9ca752ae25cfe4e923b82b3a) **Google Sheets** (`sheets`) | Finds and reads the owner's spreadsheets, adds a row or changes cells after approval; never clears or deletes cells | `add_numbers`, `googlesheets_find_spreadsheets`, `googlesheets_read_range`, `googlesheets_append_row`, `googlesheets_update_cells` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/google-docs.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=cdf0c355f743e9f04370b6979a86d299) **Google Docs** (`docs`) | Finds files in Google Drive, reads Google Docs, creates a new Doc or adds text at the end of one after approval; never shares, changes existing text or deletes | `googledrive_find_files`, `googledocs_read_document`, `googledocs_create_document`, `googledocs_append_text` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/notion.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=2dd3224cdc45117d9af1d4bbc423217b) **Notion** (`notion`) | Searches and reads the owner's Notion pages and databases, adds a page or a row, and changes a row's properties after approval; never clears, archives or deletes | `notion_search`, `notion_read_page`, `notion_create_page`, `notion_add_row`, `notion_query_database`, `notion_update_row` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/slack.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=f16e3d2e251ac3ae1dc5131b27f497cc) **Slack** (`slack`) | Lists the owner's Slack channels and posts a message the owner approved; cannot read messages | `slack_list_channels`, `slack_send_message` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/outlook.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=c39360bbfc9a0a7c8227f599f19ca611) **Outlook email** (`outlook`) | Reads the owner's Outlook inbox, sums it up and saves reply drafts; it never sends | `outlook_list_emails`, `outlook_read_email`, `outlook_create_draft` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/zoom.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=d30cf90393c0a8705c9548ee449e22f1) **Zoom** (`zoom`) | Lists the owner's Zoom meetings, schedules one with a join link after approval, and reads Zoom's AI summary of a past meeting; never deletes, ends or invites | `zoom_list_meetings`, `zoom_create_meeting`, `zoom_meeting_summary` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/http-request.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=b9f6028a4505e9e7135353ba4da1b790) **HTTP request** (`http-request`) | Calls the owner's own HTTPS APIs with keys saved in Connections, only on the hosts the owner listed | `http_request` | Plus the built-in **HelloNear guide**, loaded by every Mind, so it can answer questions about the app without inventing screens or features. ### How it is tested Assertions are on what the engine guarantees (events, approval gating, what was sent), not on wording: * **Unit:** every SKILL.md parses and uses only registered tools; every list tool returns a `count`; amounts in BigInt; signature checks. * **Live prompt tests** against real NEAR AI Cloud and local Postgres, with stand-ins for the wallet, Composio and 1Click: `engine/test/skills-*.test.ts` (payments, recipient guard, split bill, mail, Sheets, Notion, calendar, Zoom, cross-chain quotes and more). * **Secrets:** tests scan every table in the `mastra` schema for a test secret and the wallet token. * **Load tests** with k6: `engine/load/chat.js`, `engine/load/workflow.js`. *** # Hire on Agent Market Source: https://docs.hellonear.xyz/agent-market How a Mind searches the NEAR AI Agent Market, gets each agent's price for a job and recommends the cheapest within budget, without hiring. **Track:** `agents`. **Skill:** Hire on Agent Market (`agent-market`), in the General Assistant template. **Tools:** `market_search`, `market_quote`. The Mind searches the public catalog of the [NEAR AI Agent Market](https://market.near.ai) (`GET /v1/agents`), asks for a job's exact price, and picks the cheapest agent within the owner's budget. ## Try it Make a **General Assistant** and ask: *"I need competitor research for a coffee shop in Jakarta. My budget is 1 USDC. Find the cheapest agent on the NEAR AI Agent Market that fits."* See: real agents from market.near.ai, a price from each, which fit the budget, and the cheapest recommended. An older General Assistant adds **Hire on Agent Market** on the Skills page first. ## What it does not do **Nothing is hired or paid.** Hiring on the Agent Market is paid in USDC on NEAR mainnet, and HelloNear runs on testnet during the hackathon, so it only quotes. See [Hackathon phase](/hackathon-phase). # API overview Source: https://docs.hellonear.xyz/api How the public HTTP API works, every route, and where the OpenAPI spec lives. The web app is a client of a public HTTP API, and everything it does can be done with `curl`. The full spec is **[`docs/openapi.json`](https://github.com/Hellonear-AI/hellonear/blob/main/docs/openapi.json)** (OpenAPI 3.1, 63 operations): open it in [Swagger Editor](https://editor.swagger.io/?url=https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json) or any OpenAPI viewer to read every route and try it against the hosted API. Every server-sent event type is described in [`docs/api-contract.md`](https://github.com/Hellonear-AI/hellonear/blob/main/docs/api-contract.md) §3. * **Base URL:** `https://api.hellonear.xyz` (NEAR testnet), or `http://localhost:4000`. * **Auth:** a session cookie, `hn_session`. Get one with `POST /v1/auth/demo` (guest, no wallet) or with a NEAR wallet: `POST /v1/auth/challenge`, sign the message (NEP-413), then `POST /v1/auth/login`. `curl` works as is (no `Origin` header); a browser page on another site gets `403` for any call that changes something (CSRF protection). * **Streams:** chat, approve/decline, workflow runs and attack runs answer `text/event-stream`: `run.started`, `text.delta`, `tool.called`, `tool.result`, `tool.approval_required`, `run.finished`, `run.verified` and more. * **Guests** get `403 demo_not_allowed` for owner actions (wallet policy, freeze, memory edits, rules, schedules); everything else works. * **Checked live:** the last column marks the endpoints called against the hosted API with a guest session on 12 Nov 2026 and answered as documented (owner-only and money-moving endpoints are covered by the backend's integration tests instead). **System** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/health` | Health of the backend and the engine | 200 | yes | **Auth** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `POST` | `/v1/auth/challenge` | Get a NEP-413 sign-in message and a one-time nonce | 200 | | | `POST` | `/v1/auth/login` | Sign in with a NEAR wallet signature (NEP-413) | 200 | | | `POST` | `/v1/auth/demo` | Start a try-out (guest) session: no wallet, 20 messages | 201 | yes | | `POST` | `/v1/auth/logout` | Sign out | 204 | | | `GET` | `/v1/me` | The signed-in user | 200 | yes | **Catalog** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/templates` | Mind templates | 200 | yes | | `GET` | `/v1/skills` | Every skill a Mind can equip, with its tools | 200 | yes | | `GET` | `/v1/skills/{skillId}` | One skill with its playbook (SKILL.md body) | 200 | yes | **Minds** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/minds` | The user's Minds, newest first | 200 | yes | | `POST` | `/v1/minds` | Create a Mind from a template | 201 | yes | | `GET` | `/v1/minds/{mindId}` | One Mind | 200 | yes | | `PATCH` | `/v1/minds/{mindId}` | Change a Mind: name, voice, model, skills, memory switches, auto-approve rules | 200 | | | `DELETE` | `/v1/minds/{mindId}` | Delete a Mind (and its workflows, schedules and wallet key) | 200 | | **Chat** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `POST` | `/v1/minds/{mindId}/chat` | Send a message; the reply streams as server-sent events | SSE | yes | | `GET` | `/v1/minds/{mindId}/threads` | Chat threads, newest first | 200 | yes | | `GET` | `/v1/minds/{mindId}/threads/{threadId}/messages` | A thread's messages, oldest first, paged by `before` | 200 | | | `PATCH` | `/v1/minds/{mindId}/threads/{threadId}` | Rename a thread | 200 | | | `DELETE` | `/v1/minds/{mindId}/threads/{threadId}` | Delete a thread for good (the engine forgets it too) | 200 | | **Runs** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/minds/{mindId}/runs` | Runs of a Mind, with tokens and cost | 200 | yes | | `GET` | `/v1/runs/{runId}` | One run with all its stored events | 200 | yes | | `POST` | `/v1/runs/{runId}/cancel` | Stop a run that is still streaming | 200 | | | `GET` | `/v1/minds/{mindId}/events` | Events across runs since a time (Mind Graph history) | 200 | yes | **Approvals** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/minds/{mindId}/approvals` | Runs waiting for the owner's approval | 200 | yes | | `POST` | `/v1/runs/{runId}/approve` | Approve a waiting tool call; the run resumes as SSE | SSE | | | `POST` | `/v1/runs/{runId}/decline` | Decline a waiting tool call; the run resumes as SSE | SSE | yes | **Verification** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/runs/{runId}/proof` | The proof behind a reply's Verified badge | 200 | yes | | `POST` | `/v1/runs/{runId}/proof/tee-explorer` | Upload the run's Intel quote to Phala's TEE Explorer and get the verified report | 200 | yes | **Wallet** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `POST` | `/v1/minds/{mindId}/wallet` | Create the Mind's OutLayer wallet (testnet) | 201 | | | `GET` | `/v1/minds/{mindId}/wallet` | Balance, spent today, frozen, and the policy | 200 | yes | | `GET` | `/v1/minds/{mindId}/wallet/payments` | Payment receipts, refused ones included | 200 | yes | | `GET` | `/v1/minds/{mindId}/payments.csv` | Every payment as a CSV an accountant can open (date UTC, status in words, amount, counterparty, purpose, who approved, tx hash, NearBlocks link) | 200 `text/csv` | yes | | `GET` | `/v1/status` | Public status of HelloNear and its providers (NEAR AI chat and embeddings, 1Click quotes, OutLayer, NEAR RPC, Agent Market, TEE Explorer): status, latency, uptime, 48 half-hour buckets and incidents of the last 7 days. CORS `*`, cached 30 s | 200 | | | `POST` | `/v1/relay` | Relay a NEP-366 signed delegate action to the registry (only `unequip_skill` / `set_wallet`, exactly 1 yoctoNEAR); the relayer pays the gas, never a deposit. Not for try-out users | 200, `503 relay_not_configured` until the relayer is set | | | `POST` | `/v1/minds/{mindId}/wallet/policy` | Build a store_wallet_policy transaction for the owner to sign | 200 | | | `POST` | `/v1/minds/{mindId}/wallet/freeze` | Build a freeze_wallet transaction for the owner to sign | 200 | | | `POST` | `/v1/minds/{mindId}/wallet/unfreeze` | Build an unfreeze_wallet transaction for the owner to sign | 200 | | **Memory** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/minds/{mindId}/memory` | What the Mind remembers about the owner | 200 | yes | | `PUT` | `/v1/minds/{mindId}/memory` | Replace the Mind's memory | 200 | | | `DELETE` | `/v1/minds/{mindId}/memory` | Clear the Mind's memory | 204 | | **Email** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/minds/{mindId}/inbox` | The Mind's own email address, if any | 200 | yes | | `POST` | `/v1/minds/{mindId}/inbox` | Create the Mind's own email address (AgentMail) | 201 | | | `GET` | `/v1/minds/{mindId}/mail/sent` | Emails the Mind sent, refusals included | 200 | yes | **Autopilot** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/minds/{mindId}/workflows` | Saved Builder workflows | 200 | yes | | `PUT` | `/v1/minds/{mindId}/workflows/{workflowId}` | Save a Builder canvas (compiled to a Mastra workflow) | 200 | yes | | `GET` | `/v1/minds/{mindId}/workflows/{workflowId}` | One workflow with its canvas | 200 | | | `DELETE` | `/v1/minds/{mindId}/workflows/{workflowId}` | Delete a workflow and its schedule | 204 | yes | | `POST` | `/v1/minds/{mindId}/workflows/{workflowId}/runs` | Run a workflow now; steps stream as SSE | SSE | yes | | `GET` | `/v1/minds/{mindId}/workflows/{workflowId}/runs` | Past runs of a workflow, newest first, with each step | 200 | yes | | `PUT` | `/v1/minds/{mindId}/workflows/{workflowId}/autopilot` | Turn the schedule on (wallet sign-in only) | 200 | yes | | `GET` | `/v1/minds/{mindId}/workflows/{workflowId}/autopilot` | The schedule's state | 200 | | | `DELETE` | `/v1/minds/{mindId}/workflows/{workflowId}/autopilot` | Turn the schedule off | 204 | | **Connections** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/connections` | Apps the user connected through Composio | 200 | yes | | `POST` | `/v1/connections/{toolkit}` | Get a Composio Connect Link for an app | 200 | | | `DELETE` | `/v1/connections/{toolkit}` | Disconnect an app | 204 | | **Telegram** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/minds/{mindId}/telegram` | The Mind's Telegram bot, if connected | 200 | yes | | `PUT` | `/v1/minds/{mindId}/telegram` | Connect a BotFather token to the Mind | 200 | | | `DELETE` | `/v1/minds/{mindId}/telegram` | Disconnect the bot | 204 | | **Secrets** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/secrets` | Saved API keys (names and hosts, never values) | 200 | yes | | `PUT` | `/v1/secrets/{name}` | Save an API key for the Mind's HTTP request skill | 200 | | | `DELETE` | `/v1/secrets/{name}` | Delete a saved key | 204 | | **Attack playground** | Method | Path | What it does | Answer | Checked live | | - | - | - | - | - | | `GET` | `/v1/attacks` | The prompt-injection scenarios | 200 | yes | | `POST` | `/v1/attacks/{attackId}/runs` | Run a scenario on a hidden test Mind; ends with attack.verdict | SSE | yes | *** # API reference Source: https://docs.hellonear.xyz/api-reference How the HelloNear backend API is described: the OpenAPI spec, the server, auth, errors and streams. Every route is in the Endpoints tab. The HelloNear backend API is described by an OpenAPI 3 spec, kept in the repository at [`docs/openapi.json`](https://github.com/Hellonear-AI/hellonear/blob/main/docs/openapi.json) and rendered from it in the **Endpoints** tab of this site, where each route has a playground that can call the hosted API. The prose contract, with every field and event, is [`docs/api-contract.md`](https://github.com/Hellonear-AI/hellonear/blob/main/docs/api-contract.md). * **Server:** `https://api.hellonear.xyz` (NEAR testnet), or `http://localhost:4000` when you [run it locally](/run-locally). * **Auth:** every route except health, status and auth needs the session cookie `hn_session`. Get one as a guest with `POST /v1/auth/demo`, or sign in with a NEAR wallet (NEP-413). * **Errors:** `{ error, ...details }` with an HTTP status. See [Errors](/errors). * **Streams:** chat, approval and workflow runs answer with server-sent events. See [Streaming events](/events). A worked example with curl is in the [Quickstart](/quickstart#through-the-api), and every route in a table is in the [API overview](/api). # Approve a waiting tool call; the run resumes as SSE Source: https://docs.hellonear.xyz/api-reference/approvals/approve-a-waiting-tool-call;-the-run-resumes-as-sse https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/runs/{runId}/approve # Decline a waiting tool call; the run resumes as SSE Source: https://docs.hellonear.xyz/api-reference/approvals/decline-a-waiting-tool-call;-the-run-resumes-as-sse https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/runs/{runId}/decline # Runs waiting for the owner's approval Source: https://docs.hellonear.xyz/api-reference/approvals/runs-waiting-for-the-owners-approval https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/approvals # Run a scenario on a hidden test Mind; ends with attack.verdict Source: https://docs.hellonear.xyz/api-reference/attack-playground/run-a-scenario-on-a-hidden-test-mind;-ends-with-attackverdict https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/attacks/{attackId}/runs # The prompt-injection scenarios Source: https://docs.hellonear.xyz/api-reference/attack-playground/the-prompt-injection-scenarios https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/attacks # Get a NEP-413 sign-in message and a one-time nonce Source: https://docs.hellonear.xyz/api-reference/auth/get-a-nep-413-sign-in-message-and-a-one-time-nonce https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/auth/challenge # Sign in with a NEAR wallet signature (NEP-413) Source: https://docs.hellonear.xyz/api-reference/auth/sign-in-with-a-near-wallet-signature-nep-413 https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/auth/login # Sign out Source: https://docs.hellonear.xyz/api-reference/auth/sign-out https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/auth/logout # Start a try-out (guest) session: no wallet, 20 messages Source: https://docs.hellonear.xyz/api-reference/auth/start-a-try-out-guest-session:-no-wallet-20-messages https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/auth/demo # The signed-in user Source: https://docs.hellonear.xyz/api-reference/auth/the-signed-in-user https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/me # Delete a workflow and its schedule Source: https://docs.hellonear.xyz/api-reference/autopilot/delete-a-workflow-and-its-schedule https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json delete /v1/minds/{mindId}/workflows/{workflowId} # One workflow with its canvas Source: https://docs.hellonear.xyz/api-reference/autopilot/one-workflow-with-its-canvas https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/workflows/{workflowId} # Past runs of a workflow, newest first, with each step Source: https://docs.hellonear.xyz/api-reference/autopilot/past-runs-of-a-workflow-newest-first-with-each-step https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/workflows/{workflowId}/runs # Run a workflow now; steps stream as SSE Source: https://docs.hellonear.xyz/api-reference/autopilot/run-a-workflow-now;-steps-stream-as-sse https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/minds/{mindId}/workflows/{workflowId}/runs # Save a Builder canvas (compiled to a Mastra workflow) Source: https://docs.hellonear.xyz/api-reference/autopilot/save-a-builder-canvas-compiled-to-a-mastra-workflow https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json put /v1/minds/{mindId}/workflows/{workflowId} # Saved Builder workflows Source: https://docs.hellonear.xyz/api-reference/autopilot/saved-builder-workflows https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/workflows # The schedule's state Source: https://docs.hellonear.xyz/api-reference/autopilot/the-schedules-state https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/workflows/{workflowId}/autopilot # Turn the schedule off Source: https://docs.hellonear.xyz/api-reference/autopilot/turn-the-schedule-off https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json delete /v1/minds/{mindId}/workflows/{workflowId}/autopilot # Turn the schedule on (wallet sign-in only) Source: https://docs.hellonear.xyz/api-reference/autopilot/turn-the-schedule-on-wallet-sign-in-only https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json put /v1/minds/{mindId}/workflows/{workflowId}/autopilot # Every skill a Mind can equip, with its tools Source: https://docs.hellonear.xyz/api-reference/catalog/every-skill-a-mind-can-equip-with-its-tools https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/skills # Mind templates Source: https://docs.hellonear.xyz/api-reference/catalog/mind-templates https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/templates # One skill with its playbook (SKILL.md body) Source: https://docs.hellonear.xyz/api-reference/catalog/one-skill-with-its-playbook-skillmd-body https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/skills/{skillId} # A thread's messages, oldest first, paged by `before` Source: https://docs.hellonear.xyz/api-reference/chat/a-threads-messages-oldest-first-paged-by-`before` https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/threads/{threadId}/messages # Chat threads, newest first Source: https://docs.hellonear.xyz/api-reference/chat/chat-threads-newest-first https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/threads # Delete a thread for good (the engine forgets it too) Source: https://docs.hellonear.xyz/api-reference/chat/delete-a-thread-for-good-the-engine-forgets-it-too https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json delete /v1/minds/{mindId}/threads/{threadId} # Rename a thread Source: https://docs.hellonear.xyz/api-reference/chat/rename-a-thread https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json patch /v1/minds/{mindId}/threads/{threadId} # Send a message; the reply streams as server-sent events Source: https://docs.hellonear.xyz/api-reference/chat/send-a-message;-the-reply-streams-as-server-sent-events https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/minds/{mindId}/chat # Apps the user connected through Composio Source: https://docs.hellonear.xyz/api-reference/connections/apps-the-user-connected-through-composio https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/connections # Disconnect an app Source: https://docs.hellonear.xyz/api-reference/connections/disconnect-an-app https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json delete /v1/connections/{toolkit} # Get a Composio Connect Link for an app Source: https://docs.hellonear.xyz/api-reference/connections/get-a-composio-connect-link-for-an-app https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/connections/{toolkit} # Create the Mind's own email address (AgentMail) Source: https://docs.hellonear.xyz/api-reference/email/create-the-minds-own-email-address-agentmail https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/minds/{mindId}/inbox # Emails the Mind sent, refusals included Source: https://docs.hellonear.xyz/api-reference/email/emails-the-mind-sent-refusals-included https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/mail/sent # The Mind's own email address, if any Source: https://docs.hellonear.xyz/api-reference/email/the-minds-own-email-address-if-any https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/inbox # Clear the Mind's memory Source: https://docs.hellonear.xyz/api-reference/memory/clear-the-minds-memory https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json delete /v1/minds/{mindId}/memory # Replace the Mind's memory Source: https://docs.hellonear.xyz/api-reference/memory/replace-the-minds-memory https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json put /v1/minds/{mindId}/memory # What the Mind remembers about the owner Source: https://docs.hellonear.xyz/api-reference/memory/what-the-mind-remembers-about-the-owner https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/memory # Change a Mind: name, voice, model, skills, memory switches, auto-approve rules Source: https://docs.hellonear.xyz/api-reference/minds/change-a-mind:-name-voice-model-skills-memory-switches-auto-approve-rules https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json patch /v1/minds/{mindId} # Create a Mind from a template Source: https://docs.hellonear.xyz/api-reference/minds/create-a-mind-from-a-template https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/minds # Delete a Mind (and its workflows, schedules and wallet key) Source: https://docs.hellonear.xyz/api-reference/minds/delete-a-mind-and-its-workflows-schedules-and-wallet-key https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json delete /v1/minds/{mindId} # One Mind Source: https://docs.hellonear.xyz/api-reference/minds/one-mind https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId} # The user's Minds, newest first Source: https://docs.hellonear.xyz/api-reference/minds/the-users-minds-newest-first https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds # Events across runs since a time (Mind Graph history) Source: https://docs.hellonear.xyz/api-reference/runs/events-across-runs-since-a-time-mind-graph-history https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/events # One run with all its stored events Source: https://docs.hellonear.xyz/api-reference/runs/one-run-with-all-its-stored-events https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/runs/{runId} # Runs of a Mind, with tokens and cost Source: https://docs.hellonear.xyz/api-reference/runs/runs-of-a-mind-with-tokens-and-cost https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/runs # Stop a run that is still streaming Source: https://docs.hellonear.xyz/api-reference/runs/stop-a-run-that-is-still-streaming https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/runs/{runId}/cancel # Delete a saved key Source: https://docs.hellonear.xyz/api-reference/secrets/delete-a-saved-key https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json delete /v1/secrets/{name} # Save an API key for the Mind's HTTP request skill Source: https://docs.hellonear.xyz/api-reference/secrets/save-an-api-key-for-the-minds-http-request-skill https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json put /v1/secrets/{name} # Saved API keys (names and hosts, never values) Source: https://docs.hellonear.xyz/api-reference/secrets/saved-api-keys-names-and-hosts-never-values https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/secrets # Health of the backend and the engine Source: https://docs.hellonear.xyz/api-reference/system/health-of-the-backend-and-the-engine https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/health # Status page data: HelloNear and every service it depends on, checked every 5 minutes Source: https://docs.hellonear.xyz/api-reference/system/status-page-data:-hellonear-and-every-service-it-depends-on-checked-every-5-minutes https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/status Public, any origin, no cookies (`access-control-allow-origin: *`, `cache-control: public, max-age=30`). Read by status.hellonear.xyz. See docs/api-contract.md §7. # Connect a BotFather token to the Mind Source: https://docs.hellonear.xyz/api-reference/telegram/connect-a-botfather-token-to-the-mind https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json put /v1/minds/{mindId}/telegram # Disconnect the bot Source: https://docs.hellonear.xyz/api-reference/telegram/disconnect-the-bot https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json delete /v1/minds/{mindId}/telegram # The Mind's Telegram bot, if connected Source: https://docs.hellonear.xyz/api-reference/telegram/the-minds-telegram-bot-if-connected https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/telegram # The proof behind a reply's Verified badge Source: https://docs.hellonear.xyz/api-reference/verification/the-proof-behind-a-replys-verified-badge https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/runs/{runId}/proof # Upload the run's Intel quote to Phala's TEE Explorer and get the verified report Source: https://docs.hellonear.xyz/api-reference/verification/upload-the-runs-intel-quote-to-phalas-tee-explorer-and-get-the-verified-report https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/runs/{runId}/proof/tee-explorer # Balance, spent today, frozen, and the policy Source: https://docs.hellonear.xyz/api-reference/wallet/balance-spent-today-frozen-and-the-policy https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/wallet # Build a freeze_wallet transaction for the owner to sign Source: https://docs.hellonear.xyz/api-reference/wallet/build-a-freeze_wallet-transaction-for-the-owner-to-sign https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/minds/{mindId}/wallet/freeze # Build a store_wallet_policy transaction for the owner to sign Source: https://docs.hellonear.xyz/api-reference/wallet/build-a-store_wallet_policy-transaction-for-the-owner-to-sign https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/minds/{mindId}/wallet/policy # Build an unfreeze_wallet transaction for the owner to sign Source: https://docs.hellonear.xyz/api-reference/wallet/build-an-unfreeze_wallet-transaction-for-the-owner-to-sign https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/minds/{mindId}/wallet/unfreeze # Create the Mind's OutLayer wallet (testnet) Source: https://docs.hellonear.xyz/api-reference/wallet/create-the-minds-outlayer-wallet-testnet https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/minds/{mindId}/wallet # Every payment as a CSV an accountant can open Source: https://docs.hellonear.xyz/api-reference/wallet/every-payment-as-a-csv-an-accountant-can-open https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/payments.csv # Meta-transaction relayer: HelloNear pays the gas for an owner's signed registry call (NEP-366) Source: https://docs.hellonear.xyz/api-reference/wallet/meta-transaction-relayer:-hellonear-pays-the-gas-for-an-owners-signed-registry-call-nep-366 https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json post /v1/relay The owner signs a delegate action in their own NEAR wallet; the relayer wraps it in a transaction and pays the gas. Only for `REGISTRY_CONTRACT_ID`, only `unequip_skill` and `set_wallet` with exactly 1 yoctoNEAR (the relayer would pay any deposit), at most 4 calls of at most 30 Tgas, a full-access key, a nonce above the key's, and an expiry at most 1000 blocks ahead. 10 per owner per hour. # Payment receipts, refused ones included Source: https://docs.hellonear.xyz/api-reference/wallet/payment-receipts-refused-ones-included https://raw.githubusercontent.com/Hellonear-AI/hellonear/main/docs/openapi.json get /v1/minds/{mindId}/wallet/payments # Autopilot and Builder Source: https://docs.hellonear.xyz/autopilot The visual Builder for jobs a Mind runs, Autopilot schedules, and why unattended jobs get no payment tools. The **Builder** is a visual canvas for a job a Mind runs step by step. **Autopilot** runs a Builder job on a schedule, without the owner watching. ## Steps | Step | What it does | | - | - | | **Ask the Mind** | A prompt to the Mind, with the Mind's persona and skills | | **Use a tool** | One tool the owner picked, such as *Email me* or adding to the owner's calendar | | **Call a website** | An HTTP request, with secrets filled in only for the hosts the owner listed | | **If or else** | A branch, including nested Ifs and End | Canvases compile to Mastra dynamic workflows (`engine/src/builder.ts`, `engine/src/workflows.ts`); Autopilot runs them on Mastra workflow schedules (`engine/src/autopilot.ts`). User text can never become a Mastra template. ## Unattended jobs are limited Autopilot jobs get **no payment or approval tools**. They may only email the owner or add to the owner's calendar, and only as steps the owner placed. *Email me* can only send the Mind's notes to the owner's own connected Gmail; the recipient is never in the request. Scheduled runs get no secrets yet. If the Mind changes (persona, model, skills), its Autopilot jobs get the new config; a job the engine cannot run is paused and says why (`pausedFor`). ## Through the API `POST /v1/minds/{mindId}/workflows/{workflowId}/runs` runs a workflow and streams events; `PUT …/autopilot` turns the schedule on or off. The workflow events (`workflow.started`, `node.started`, `node.finished`, `workflow.finished`) are in [Streaming events](/events). # Connections and keys Source: https://docs.hellonear.xyz/connections How a Mind uses your apps through Composio, and how API keys are stored so the model never sees them. ## App connections A Mind works in the owner's apps through **Composio**: Gmail, Google Calendar and Meet, Sheets, Drive, Docs, Notion, Slack, Discord, Outlook, HubSpot and Zoom. The owner connects an app once per account on the Connections page; Composio stores and refreshes the OAuth tokens. * Tokens never reach HelloNear's backend, the browser or the model. * The Composio user id is the HelloNear user id, so a Mind's tools act only on its own owner's accounts. * Actions that change something wait for the owner's approval. See [Skills and tools](/skills). * Guests get a fixed, fictional sample inbox and calendar instead of a real account. The full list with what each app is for is on [Connectors](/connectors). ## A Mind's own email address With the `email-address` skill, a Mind gets its own inbox on AgentMail (`{name}-{6 id chars}@agentmail.to`), for invoices and replies. Owners can send at most 20 emails per Mind per day. ## API keys (secrets) For a website or API the owner wants a Mind to call, the owner stores a key on the Keys page: * Each key has a name (`UPPER_SNAKE_CASE`) and a list of **allowed hosts**. It is only ever sent to those hosts. * It is stored encrypted with AES-256-GCM, bound to the owner and the key's name (`apps/be/src/crypto.ts`), and never returned by the API. * The model only ever writes `{{secrets.NAME}}`. The tool fills in the value at execution. Values and wallet tokens live in an in-memory map, so they never reach prompts, traces or stored run snapshots; a test scans every table for them. * In events, secrets are shown as `••••`. Through the API: `GET /v1/secrets` (names and hosts only), `PUT /v1/secrets/{NAME}`, `DELETE /v1/secrets/{NAME}`; `GET /v1/connections`, `POST /v1/connections/{toolkit}`, `DELETE /v1/connections/{toolkit}`. # Connectors Source: https://docs.hellonear.xyz/connectors The apps and services a Mind can use, and what each one is for. What a Mind can work with. Logos are the ones the web app shows on the Connections screen (rendered from `apps/fe/src/components/elements/AppLogos.tsx`); each is its owner's trademark, used to name the app. | Connector | How it connects | What a Mind can do with it | | - | - | - | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/gmail.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=19397312353776e1c525fee1371e637f) **Gmail** | Composio (OAuth, the owner's account) | Read and search mail, save drafts, archive or label after approval. No send tool exists | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/google-calendar.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=d6ed969f03d10dd9c17b9f71142cd5bc) **Google Calendar** | Composio | Read events, find free time, add an event, move an event, all with times on the owner's clock | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/google-meet.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=677adfd4835a781d331864ce6fde8cc1) **Google Meet** | Composio | Schedule a meeting with guests the owner named and a Meet link, after approval | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/google-sheets.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=59a747fd9ca752ae25cfe4e923b82b3a) **Google Sheets** | Composio | Find and read sheets, add a row, change cells with the old value shown first | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/google-drive.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=3d20645aeeee385e1bc867196f67734c) **Google Drive** | Composio | Search files by name and content | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/google-docs.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=cdf0c355f743e9f04370b6979a86d299) **Google Docs** | Composio | Read a Doc, create one, add text at the end (never replaces) | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/notion.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=2dd3224cdc45117d9af1d4bbc423217b) **Notion** | Composio | Search and read pages and databases, add a page or a row, change a row's properties | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/slack.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=f16e3d2e251ac3ae1dc5131b27f497cc) **Slack** | Composio | List channels, post a message the owner approved | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/outlook.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=534028f117e9a4106bb1c053c1da6b0d) **Outlook** | Composio | Read mail and save reply drafts (no send) | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/zoom.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=d30cf90393c0a8705c9548ee449e22f1) **Zoom** | Composio | List meetings, schedule one with a join link, read Zoom's AI summary of a past meeting | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/telegram.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=47c0ca897806900361bd0a77764a6d1f) **Telegram** | A bot per Mind, made by the owner with BotFather | Chat with the Mind, streamed replies, Approve / Decline buttons on cards; only the owner's chat is answered | | **The Mind's own email address** | AgentMail, one inbox per Mind | Send from `…@agentmail.to` after approval, only to addresses the owner typed; read its own inbox with spam and phishing warnings | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/apps/meteor.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=64dc2fffbce58773623a5f40b3cf4da2) **NEAR wallet** (Meteor first) | NEAR Connect, NEP-413 sign-in | The owner signs in, sets the Mind wallet's limits and freezes it; the Mind never holds the owner's keys | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/skills/http-request.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=b9f6028a4505e9e7135353ba4da1b790) **HTTP request** (your own APIs) | API keys the owner saves in Connections, stored encrypted | Call any HTTPS API the owner uses (a store, a CRM, a webhook) with the owner's key, only on the hosts the owner listed; the Mind writes `{{secrets.NAME}}` and never sees the key | *** # Contract check before paying Source: https://docs.hellonear.xyz/contract-check How the Recipient guard skill warns before a plain transfer to a smart contract and asks the owner instead of showing an approval card. **Track:** `security`. **Skill:** Recipient guard (`recipient-guard`), in the Payments Mind template. **Tool:** `near_view_account`. Before paying, the Mind looks up the recipient on NEAR testnet (`view_account`: exists, balance, storage, `isContract`, `codeHash`). If the account is a smart contract, it warns: it is a contract, not a person's wallet, and NEAR sent to it by a plain transfer may be stuck or do nothing. It pays only if the owner confirms that is what they want. ## Try it With a Payments Mind: *"Pay 0.001 NEAR to hellonear-registry.testnet."* See: a warning that it is a smart contract, and a question. No approval card. ## Other checks in the same skill Recipient guard answers allow, warn or block with the reason: where the account came from, that it exists, lookalikes of people the owner already pays, first payments, and contracts. A first payment to a real account that is not a contact, contract or lookalike is allowed, and the Mind says it is the first payment to it. These checks are advice from the model. The hard stops are the owner's approval and the wallet policy. See [Wallet, limits and approvals](/wallet-and-approvals). # Receipts and smart contracts Source: https://docs.hellonear.xyz/contracts Every on-chain claim with its transaction: payments, policies, the verified registry contract and the swarm auction round. Every link opens a public explorer or report. Nothing here needs an account. ### On NEAR testnet | What happened | Transaction | What it proves | | - | - | - | | A Mind's wallet paid 0.01 NEAR after the owner approved, through the hosted stack | [`AKYYpkLq…`](https://testnet.nearblocks.io/txns/AKYYpkLq8XxjL4GKJqdGF5CVTLmjNh3AGEpz2rbcfyYT) | `Transfer` from the Mind wallet `83e05486…` to `lin1er.testnet`. The agent pays from its own wallet, never the owner's | | An owner saved the Mind's limits, signed in Meteor | [`DhKqbLAX…`](https://testnet.nearblocks.io/txns/DhKqbLAX3zhH2tP3kJDx5Xsk8ZkMByfJbYLyWYyivXXZ) | `store_wallet_policy` on `outlayer.testnet`: the policy lives on chain, set by the owner, not by HelloNear | | An owner froze the Mind's wallet | [`HHGf2pqG…`](https://testnet.nearblocks.io/txns/HHGf2pqGRGTEJuA7wn4R18swFC4ssL6XMyXyogFHkDgu) | `freeze_wallet` on `outlayer.testnet`: one signature stops every payment | | A payment went through right after the UTC day reset of the daily limit | [`GUn5P1Dp…`](https://testnet.nearblocks.io/txns/GUn5P1DpuJ3XxMw2s9GJAecHR1BVuVtr4wQhTZ54RjG) | The daily cap is enforced by the wallet and resets at 00:00 UTC | | The Mind registry contract upgraded to v0.3.0 | [`ESMY36Uo…`](https://testnet.nearblocks.io/txns/ESMY36UoFcdWuw5fbShbNx13Fvf2NB1z1qWWypJNyCwp) | `DeployContract` on `hellonear-registry.testnet`; `contract_source_metadata` answers version 0.3.0, NEP-330 | | The same v0.3.0 redeployed from a reproducible build, then source-verified | [`DmidjQmo…`](https://testnet.nearblocks.io/txns/DmidjQmoN15bj2qctXaXDefAW5NGJZFBPqqPPFJoa6Qb) | `build_info` names the build image and commit `95c2b3d`; NearBlocks shows the contract as verified through SourceScan (code hash `GUxsMNJd…`) | | A Mind equipped a published skill, paying its publisher | [`6diDXaAY…`](https://testnet.nearblocks.io/txns/6diDXaAYmT8pMtVemsv4xtmzSE8DW7WM5Uprim6aU2a5) | `equip_skill` on the registry | A payment the policy refuses has **no transaction at all**: OutLayer refuses it in the TEE before signing. The app and the Mind never show a tx link for one. ### The registry contract's source is verified `hellonear-registry.testnet` runs exactly the code in this repository at commit `95c2b3d`. It was built reproducibly (NEP-330) and verified through SourceScan, so anyone can rebuild it and get the same hash. | | | | - | - | | **Status** | **Verified**. The [NearBlocks contract tab](https://testnet.nearblocks.io/address/hellonear-registry.testnet?tab=contract) shows the verified source, and its verify page answers "Contract already verified" | | **Code hash on chain** | `GUxsMNJdJKoFq7VJawNeCwW7GjGZE6TpURPj13ojEnub` | | **Deploy transaction** | [`DmidjQmoN15bj2qctXaXDefAW5NGJZFBPqqPPFJoa6Qb`](https://testnet.nearblocks.io/txns/DmidjQmoN15bj2qctXaXDefAW5NGJZFBPqqPPFJoa6Qb) (12 Nov 2026, code-only, state unchanged) | | **Source** | [`Hellonear-AI/hellonear@95c2b3d`](https://github.com/Hellonear-AI/hellonear/tree/95c2b3d839357583224b4c8fa64b0f03cddc3f80), folder `sc` | | **Build image** | `sourcescan/cargo-near:0.21.1-rust-1.96.0@sha256:ccb22bb4e677ed022d8b9d1aa1b32f0af52dd0471ef1c32e48dedbf68ee6ee17` | | **Verifier** | SourceScan `v2-verifier.sourcescan.testnet`; its record holds the same code hash and the source on IPFS (`QmX4dYjf9v798uF4Uuf11EPMA83Le84sCg6UsmaGdgrMdc`) | Check it without a browser (public RPC, no key). Each command should print the value in the table: ```sh theme={null} RPC=https://test.rpc.fastnear.com # 1. The code hash deployed on the account curl -s $RPC -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"query","params":{"request_type":"view_account","finality":"final","account_id":"hellonear-registry.testnet"}}' | jq -r .result.code_hash # 2. The contract names its own source and build (NEP-330 contract_source_metadata) curl -s $RPC -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"query","params":{"request_type":"call_function","finality":"final","account_id":"hellonear-registry.testnet","method_name":"contract_source_metadata","args_base64":"e30="}}' | jq -r '.result.result | implode | fromjson | .build_info' # 3. SourceScan's verification record for the account curl -s $RPC -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"query","params":{"request_type":"call_function","finality":"final","account_id":"v2-verifier.sourcescan.testnet","method_name":"get_contract","args_base64":"eyJhY2NvdW50X2lkIjoiaGVsbG9uZWFyLXJlZ2lzdHJ5LnRlc3RuZXQifQ=="}}' | jq -r '.result.result | implode | fromjson | .code_hash' ``` To rebuild it yourself (needs Docker): `git checkout 95c2b3d && cd sc && cargo near build reproducible-wasm`, then compare the SHA-256 (base58) of `target/near/hellonear_mind_registry.wasm` with the code hash above. ### The swarm auction: one real round on testnet The group-buying auction contract (`sc/swarm`, rules in [`RULES.md`](https://github.com/Hellonear-AI/hellonear/blob/main/sc/swarm/RULES.md)) is deployed at **[`auction.hellonear-swarm.testnet`](https://testnet.nearblocks.io/address/auction.hellonear-swarm.testnet?tab=contract)**. It was built reproducibly from commit `64c9278`, and its **source is verified** through SourceScan (code hash `6Wn9K6b3DtoH4TnoXs2jx6zFzihdzFDQGw4ae2dzcCv1`, deploy [`FkvHpxf9…`](https://testnet.nearblocks.io/txns/FkvHpxf9ff8LBeMcLEqSbhmFUbhcx5PebyG3qzJdQAwo)). Every agent is its own sub-account of `hellonear-swarm.testnet`. Round 0 (13 Nov 2026) had 3 buyers wanting 6 "gpu-hours", a ceiling of 0.01 NEAR per unit, and 2 sellers bidding sealed asks: | Step | Who | Transaction | What it shows | | - | - | - | - | | Open the round | `coordinator` | [`B4CFzH9o…`](https://testnet.nearblocks.io/txns/B4CFzH9oCH8smUfCbTeKD7hNLPAmCwgzegzmnodavQaj) | Ceiling 0.01 NEAR per unit, seller bond 0.01 NEAR, a fixed 3 min commit window and 2 min reveal window | | Join with escrow | `buyer-1`, `buyer-2`, `buyer-3` | [`GdBiXyn4…`](https://testnet.nearblocks.io/txns/GdBiXyn44oTHPEtcdxiZNdE9xdCPjPqiJUbUniGuVLG6) [`Eo4m23zh…`](https://testnet.nearblocks.io/txns/Eo4m23zhYhpxGTMZB7FxAK7oZAp6rCLFJvkJnrDMRQJJ) [`cgt2zw9v…`](https://testnet.nearblocks.io/txns/cgt2zw9vewKo9HQQC9g8FJFcu5GXM3n9FBWWCzcheaY) | 2, 3 and 1 units, each paying units × ceiling into escrow | | Sealed asks | `seller-1`, `seller-2` | [`CQUFGq7K…`](https://testnet.nearblocks.io/txns/CQUFGq7KoJ9VH5pi78GyvA84TLxrDTw1D8wgnuECmSH9) [`4FsTkdpw…`](https://testnet.nearblocks.io/txns/4FsTkdpwJDxX4xXxWp1jfxXo8pLtN1cQizdbMnjP67iN) | Only a SHA-256 commitment (round, seller, ask, capacity, salt) plus the bond. Nobody can see the price | | Reveal | `seller-1`, `seller-2` | [`Gu7qQBFn…`](https://testnet.nearblocks.io/txns/Gu7qQBFnV8uUCgp3VgjxntrNzwSnczWLxsq6TLi3U6pw) [`4EPJqmC6…`](https://testnet.nearblocks.io/txns/4EPJqmC6dtzSGADFLnNqffo3DMkvxEmxVuTmbcFFuyyC) | 0.006 NEAR × 4 units and 0.008 NEAR × 5 units; each must hash to its commitment, and the bond comes back | | Close (a buyer, not the organizer) | `buyer-2` | [`44guvtrj…`](https://testnet.nearblocks.io/txns/44guvtrj8riB75rgQiC1kfMsBQzYHQcmruR3cdA4eL5C) | All 6 units filled at **one clearing price, 0.008 NEAR**: seller-1 sold 4, seller-2 sold 2. Buyers paid 0.048 NEAR in total and sellers earned 0.048 NEAR | | Withdraw | each agent | [`CNsVsstu…`](https://testnet.nearblocks.io/txns/CNsVsstuuumXzjLbjGTFWXEYVXtw1bDfcTsiej7PEy7s) [`E2Amtv9p…`](https://testnet.nearblocks.io/txns/E2Amtv9pnSWdLhQoFaXeZxuxrm8Jjhc8NBgLbcDMcnJC) [`APe2tSRJ…`](https://testnet.nearblocks.io/txns/APe2tSRJqZrcrKUMNhsKnMjvCFcMLfWD4ayHqSvpMgD2) [`3WYa3qLP…`](https://testnet.nearblocks.io/txns/3WYa3qLPAP57WCg5fM7ptgQ6QyKv31M6f7r66NWDGBw6) [`5qV7kPVS…`](https://testnet.nearblocks.io/txns/5qV7kPVSVV17KzvCZBLVbtHbM52ZDnrRtmtaM36V6f9w) | Buyers pull their change (0.004, 0.006 and 0.002 NEAR); sellers pull sales plus bond (0.042 and 0.026 NEAR) | Read the round yourself: `get_round` with `{"round_id":0}` on `auction.hellonear-swarm.testnet` (public RPC, no key). The full 20-buyer, 5-seller simulation runs on a local sandbox: `cd sc/swarm && cargo test --test simulation -- --nocapture`. ### The proof behind a verified reply (NEAR AI Cloud TEE) | | | | - | - | | **Claim** | The reply came from NEAR AI's gateway TEE, and every step was signed by the key that hardware vouches for. | | **Where it is checked** | `engine/src/verify.ts`, before the badge is shown. The signatures, hashes (never the conversation) and Intel's TDX quote are kept on `run.verified`. | | **Open it** | Verified badge → **View proof** → **Check it in TEE Explorer**. The backend uploads the Intel quote to Phala's TEE Attestation Explorer and the app opens the report. | | **A real report** | [proof.t16z.com/reports/1b374e5b…](https://proof.t16z.com/reports/1b374e5b10031496c6c45bc7749038d7e7cd26a16996455f893b6b5dd44a9db2): **VERIFIED**. Its report data ends with that run's nonce (`…99e266`), and its MRCONFIG carries the compose hash (`877959253d…`) in our proof. | ### NEAR Intents quotes, signed by 1Click | | | | - | - | | **Claim** | The numbers a Payments Mind shows for a cross-chain payment are NEAR Intents' own. | | **How** | `crosschain_quote` calls 1Click `POST /v0/quote` with `dry: true`. 1Click signs every quote (ed25519); the engine checks it with the official SDK's `verifyQuoteSignature` and returns `proof: { signedBy1Click, signature, quoteHash, publicKey }`. | | **Live quotes** | 10 USDC on NEAR → **9.99558 USDC on Base** (\~22 s); 25 USDT on NEAR → **24.98 USDT on Solana** (\~17 s). | | **Tested** | `engine/test/crosschain.test.ts`: a real signed quote recorded from 1Click verifies; the same quote with `amountOut` changed by one unit does not. | | **Honest caveat** | It is a quote: NEAR Intents has no testnet and HelloNear's wallets are on testnet, so nothing is sent, and the Mind says so in every reply. | *** # Errors Source: https://docs.hellonear.xyz/errors The shape of every error the HelloNear API returns, what each status means, and the codes you are most likely to meet. Every error is JSON: `{ "error": "", ...details }` with an HTTP status. The `error` code is stable; details depend on the code. ## Status codes | Status | Meaning | | - | - | | `400` | The request is wrong: `invalid_json`, `invalid_body`, an unknown skill, an unknown time zone | | `401` | `unauthorized` (no session or an expired one), `invalid_signature`, `invalid_nonce` (wallet sign-in) | | `403` | Not allowed: `bad_origin` (a state-changing request from an origin not in `FE_ORIGIN`), `demo_not_allowed` (an owner action from a try-out user) | | `404` | Not found. **Another user's Mind or run answers `404`, never `403`**, so ids cannot be probed | | `409` | A conflict with the current state, such as `not_awaiting_approval`, `not_running`, `thread_busy`, `wallet_not_empty`, `already_connected` | | `413` | `body_too_large` (bodies are at most 256 KB) | | `422` | `not_a_quote` (TEE Explorer upload of anything but a hex quote) | | `429` | A rate limit: `demo_run_limit`, `demo_rate_limited`, `relay_rate_limited`, `mail_rate_limited` | | `503` | A service HelloNear depends on failed | ## Why 503 and never 502 When OutLayer, Composio, the engine or the NEAR RPC fails, the answer is **`503`**, never `502`. Behind Cloudflare a `502` or `504` body is replaced by Cloudflare's own HTML page, so the caller would lose the error. Two families: * `…_error`: the service answered with a failure; details carry its status (for example `outlayerStatus`, `composioStatus`). * `…_unreachable` and `engine_unavailable`: no answer; details carry `reason` (`timeout` or a network code such as `ECONNREFUSED`). Every 5xx is logged on the server as one line with the route, code and details, never keys. ## Payment results A payment refused by the wallet is not an HTTP error of your request; it is the tool's result inside the run: | Result | Meaning | | - | - | | `policy_denied` | Over the per-payment or daily limit, or to an address not on the list. Refused in the TEE before signing, so there is **no transaction** | | `wallet_frozen` | The owner froze the wallet. No transaction | | `pending_approval` | The wallet's own approval threshold applies; it resolves to `success` with a `tx_hash`, or `failed` | Never show a transaction link, or "rejected on-chain", for a refused payment. ## Run errors A run that fails sends a `run.error` event with a code, for example `run_interrupted` when a backend restarted mid-run. See [Streaming events](/events). The full list of codes per route is in [`docs/api-contract.md`](https://github.com/Hellonear-AI/hellonear/blob/main/docs/api-contract.md) §7. # Streaming events Source: https://docs.hellonear.xyz/events The server-sent events every chat, approval, workflow and attack run streams, in order. The engine **normalizes** Mastra stream chunks into these events. The browser and the Mind Graph depend on this format, not on raw Mastra chunks, so a Mastra upgrade cannot break the UI. Common fields on every event: | Field | Type | Notes | | - | - | - | | `v` | `1` | contract version | | `type` | string | see below | | `runId` | string | Mastra `runId` | | `mindId` | string | | | `seq` | integer | 0, 1, 2… per run; the backend uses `(runId, seq)` as the primary key | | `ts` | string | ISO 8601, set by the engine | ### Event types | `type` | Extra fields | From Mastra chunk | | - | - | - | | `run.started` | `threadId`, `model`, `nodeId` (`model:{modelId}`), `skills` (ids actually loaded) | `start` | | `step.started` | `step` (1-based) | `step-start` | | `reasoning.delta` | `text` | `reasoning-delta` (glm only; DeepSeek sends none) | | `text.delta` | `text` | `text-delta` Em and en dashes are replaced by a plain hyphen before the event is sent (house style, #109, #124); the TEE verification covers the model's own bytes | | `tool.called` | `toolCallId`, `tool`, `nodeId`, `args`; `approvedBy: "rule"` and `rule: "tool" \| "payment"` when an owner's auto-approve rule (#167) lets the call run without a `tool.approval_required` | `tool-call`: payload `{ toolCallId, toolName, args }` | | `tool.result` | `toolCallId`, `tool`, `nodeId`, `result`, `status: "ok"` | `tool-result`: payload `{ toolCallId, toolName, args, result }` | | `tool.error` | `toolCallId`, `tool`, `nodeId`, `status: "error" \| "policy_denied" \| "wallet_frozen" \| "rejected" \| "rate_limited"`, `error`, `result?` | `tool-error`; for `send_payment`, a `tool-result` whose `status` is `policy_denied` / `wallet_frozen` (the wallet refused before signing, #42): `error` is OutLayer's message, `result` the payment receipt without `txHash`; for `mail_send`, a `tool-result` whose `status` is `rejected` / `rate_limited` (#96): `error` is the refusal's `message`, `result` the send record without `messageId` | | `tool.approval_required` | `toolCallId`, `tool`, `nodeId`, `args` | `tool-call-approval` | | `step.finished` | `step`, `usage` | `step-finish` | | `run.finished` | `finishReason`, `text`, `usage`, `costUsd`, `verification: { status: "pending" }` | `finish` | | `run.finished` (canceled) | `status: "canceled"`, `finishReason: "canceled"`; no `text`, `usage` or `costUsd`, and no `run.verified` after it | **backend**, not the engine: the last event of a run stopped with `POST /v1/runs/{runId}/cancel` (#121); a builder run gets `workflow.finished` with `status: "canceled"` instead | | `attack.verdict` | `attackId`, `attacker`, `paymentTool` (the Mind's skills grant `send_payment`), `stoppedBy`: `model` (refused, asked for no payment); `no_tool` (no payment tool); `approval` (a payment card waits for the owner); `policy` (approved, then refused by the wallet in OutLayer's TEE before signing: `policy_denied` / `wallet_frozen`, no tx); `none` (a payment was sent), `detail`, optional `to`, `status`, `attackerTargeted` (the payment went to the scenario's attacker), `txHash` (only for `none`) | engine (`src/attacks.ts`, #16), on a run that carries `attackId`, after `run.finished` and before `run.verified` | | `thread.titled` | `threadId`, `title` (3 to 6 words summing up the user's first message, in the user's language, no quotes or final period) | engine (`src/titles.ts`, #86, #93), after the `run.finished` of a thread's first run and before `run.verified`; skipped if making the title fails or takes too long, and then the backend keeps the first-message cut | | `run.verified` | `model`, `nodeId`, `verification` (see below). Always the run's **last** event | engine, after the stream is read | | `run.error` | `error` | `error` chunk or a thrown error. The backend adds one itself when the engine stream breaks (`engine_stream_interrupted`), and when a run stayed `running` after a backend restart (`run_interrupted`, #218) | | `workflow.started` | `workflowId`, `nodeId` (`workflow:{workflowId}`), `model`, `skills` | `workflow-start`; first event of a builder run | | `node.started` | `node` (canvas node id), `nodeType` (`agent \| tool \| http`), `nodeId` (Mind Graph) | `workflow-step-start` | | `node.finished` | `node`, `nodeType`, `nodeId`, `status: "ok"` + `output`, or `status: "error"` + `error` | `workflow-step-result` | | `workflow.finished` | `workflowId`, `status` (`success`, `failed`, …) | `workflow-finish`; followed by `run.verified` as the last event | `usage` = `{ "inputTokens": 441, "outputTokens": 28, "reasoningTokens": 2, "totalTokens": 469 }`. It is only filled while streaming when the engine builds models with `@ai-sdk/openai-compatible` + `includeUsage: true`; with the `nearai/` router string it is empty. `costUsd` = `inputTokens × input price + outputTokens × output price`, prices from `GET https://cloud-api.near.ai/v1/model/list` (cached by the engine). `verification` (on `run.verified`), computed with `@nearai/inference-sdk` (`verifyResponse` per completion, after Gateway and model attestation): * `{ "status": "verified", "level": "model_tee" | "gateway_tee", "completionIds": [...] }`: every model step verified. `model_tee` only if every step was signed inside the model TEE (`provider_tee`); streaming completions are signed by the Gateway TEE, so a normal chat run is `gateway_tee` (measured 3 Nov). * `proof` (#254, optional: present when every step carried its evidence; absent on runs before it) = `{ checkedAt, steps: [{ id, signatureKind, signer: { algo, address }, signedText, signature, attestation }], attestations: { [attestation]: { kind: "gateway" | "model", signer: { algo, address }, nonce, intelQuote, tcbStatus, gpuEvidence?, composeHash?, osImageHash? } } }`. Taken from the SDK's own `verifyResponse` result, nothing fetched again, no API key. `signedText` is `{request_hash}:{response_hash}` (gateway) or `{model}:{request_hash}:{response_hash}`: hashes only. Each step's `attestation` keys the attestation whose signer signed it; anyone can check the `intelQuote` at [https://proof.t16z.com](https://proof.t16z.com). About 12 KB per run (a 10,012-character quote for one gateway attestation, measured 11 Nov), so the backend stores it but leaves it out of the stream (chat, approve/decline, Telegram), `GET /v1/runs/{runId}` and the Mind Graph's events, and serves it on its own at `GET /v1/runs/{runId}/proof` (#254). * `{ "status": "not_applicable", "reason": "incognito_model" | "no_completions" }`: Incognito models (`verifiable: false` in the model list) never get the private badge. * `{ "status": "failed", "completionIds": [...], "errors": [...] }`: show no badge. UI wording: `model_tee` → "Verified private (model TEE)"; `gateway_tee` → "Verified via NEAR AI TEE gateway"; anything else → no badge. Builder runs (#20) send `workflow.started → node.started/node.finished… → workflow.finished → run.verified`. Inside an `agent` node the chat events appear between its `node.started` and `node.finished` (`step.*`, `reasoning.delta`, `text.delta`, `tool.*`), but no `run.started` / `run.finished`. A run with no agent node ends with `run.verified` `{ status: "not_applicable", reason: "no_completions" }`. Condition nodes emit nothing; only the branch that ran appears. Example sequence for one tool call: ```text theme={null} run.started → step.started{1} → reasoning.delta… → tool.called{addNumbers} → tool.result{addNumbers} → step.finished{1} → step.started{2} → text.delta… → step.finished{2} → run.finished ``` ### Not forwarded to the browser `tool-call-input-streaming-start`, `tool-call-delta`, `tool-call-input-streaming-end`, `text-start`, `text-end`, `reasoning-start`, `reasoning-end`, `raw`. The engine drops them; nothing in the UI needs partial tool arguments. ### Secrets in events No event may contain a secret value. The engine redacts known secret **values** (not just field names) in every event field, including `run.error`, before emitting, replacing them with `"••••"`. # Hackathon phase and roadmap Source: https://docs.hellonear.xyz/hackathon-phase What runs on NEAR testnet during the hackathon, what becomes real on mainnet, and the roadmap. During the hackathon HelloNear runs on **NEAR testnet**, so judges can try everything for free with test tokens and a guest session. Some features therefore stop one step short of real money on purpose. Each becomes real on mainnet with the same approvals and limits. | Feature | During the hackathon (testnet) | On mainnet | | - | - | - | | **Payments** | Testnet NEAR from each Mind's OutLayer wallet, policy checked in a TEE | Real NEAR and stablecoins, same policy, approvals and Freeze | | **Cross-chain stablecoins (NEAR Intents)** | Real quotes from 1Click, signature checked; nothing is sent, because NEAR Intents has no testnet | The Mind sends the payment it quoted, after the owner approves | | **NEAR AI Agent Market (market.near.ai)** | Real agents and real prices (each agent's x402 answer); the Mind picks the cheapest within the owner's budget, but **hires no one**, because the market is paid in USDC on NEAR mainnet | The Mind **hires the agent for real**: one signed USDC transfer (NEP-366) behind the owner's approval card, and the agent's result comes back into the chat. Haggling then moves to the market's job board (post the job with a budget, compare bids, answer one counter) | | **Haggling** | One offer to the sellers of HelloNear's own testnet data shop (two sellers on the hosted demo) | The same playbook with real sellers and the job board above | | **Swarm auction** | Contract live and source verified at `auction.hellonear-swarm.testnet`; one round ran with scripted agent accounts, the 20-buyer simulation runs on a local sandbox | Minds join group-buying rounds from the app with their own wallets | | **Relayer (NEP-366)** | **Live on the hosted demo** for two registry methods (`unequip_skill`, `set_wallet`), paid by `relayer.hellonear-swarm.testnet`, whose only key lives on the server; never pays a deposit, not for try-out users | Pays the gas for owners' calls to HelloNear's contracts, so owners never need NEAR for gas | Also stated plainly: * **App accounts:** Gmail, Google Calendar and Meet, Sheets, Drive, Docs and Notion were used by the team with real accounts. Changing Sheets cells, moving Calendar events, updating Notion rows and appending to Docs were tested against a stand-in for Composio, not yet on a real account. Zoom, Outlook and Slack are wired but not yet tried with a real account. * **The owner's payment rule** was tested on a local stack against a stand-in OutLayer. OutLayer's TEE checks every payment either way. * **Model behaviour varies.** Over repeated runs the model sometimes declines a payment it could have put on a card. The approval and the wallet policy, not the model, are what guarantee the outcome. *** ## Now and after the hackathon **During the hackathon (now):** everything runs on NEAR testnet so judges can try it for free. * **Guest mode:** *Continue as guest* makes a temporary user with 20 messages, a Mind from any template, sample inbox and calendar data, and payments from a shared test wallet with HelloNear's limits. No wallet, account or payment needed; data is deleted after 7 days. * **The AI is on us:** every reply runs on NEAR AI Cloud with the team's own credits. * **Signing in with a NEAR wallet** (Meteor first) gives the full app: your own Mind wallet, limits, freeze, rules, connections and Autopilot. **After the hackathon:** * **Mainnet.** Deploy the registry and the Mind wallets on NEAR mainnet; cross-chain stablecoin payments through NEAR Intents can then be sent, not only quoted, under the same limits and approvals. * **Pay-as-you-go AI credits.** Owners top up credits and pay for what their Minds use. Each run already records its tokens and cost. * **More Mind templates** beyond the three today, each starting with the skills for its job. * **Hiring on the Agent Market.** On mainnet a Mind can pay a market.near.ai agent itself: the payment is one signed delegate action (NEP-366) for the agent's quoted USDC price, behind the owner's approval card and wallet limits, and the agent's result comes back into the chat. * **Haggling through the Agent Market's job board.** The Mind posts the owner's job with their budget, compares the bids that come in, answers one counter, and funds the escrow only through the owner's approval card. Today it compares the fixed prices of several agents and picks the cheapest within the budget. * **The swarm auction on chain for Minds.** Minds join group-buying rounds of the swarm auction contract (`sc/swarm`) with their own wallets, so several owners' Minds pool demand and pay one clearing price. * **Images and voice.** Owners send their Mind a photo (a receipt, an invoice, a screenshot) or a voice message, and the Mind reads it and acts on it, with the same approvals and limits. *** # Haggling with a seller Source: https://docs.hellonear.xyz/haggling How a Mind makes one offer below a seller's price, within the owner's budget, then buys at the agreed price or walks away. **Track:** `agents`. **Skill:** Best price buyer (`best-price`). **Tools:** `get_quotes`, `make_offer`, `buy_data`, `send_payment`. When a data report costs more than the owner's budget, the Mind makes **one** offer to one seller, then either buys at the agreed price (after the owner approves) or walks away and pays nothing. It never makes a second offer. ## Try it In the app, with a Payments Mind: *"Buy the gas price report, but I only want to pay 0.0006 NEAR. Haggle if it costs more."* See: the sellers' prices, then **Made an offer**, then an approval card at the agreed price, or a reply that it walked away. ## How the seller answers The sellers are HelloNear's own test shop (`apps/be/src/shop.ts`). Each seller has a floor, a share of its list price (default 0.8): * An offer at or above the floor is `accepted` (never above the list price). * An offer below the floor gets one `countered` price, halfway to the list price but not under the floor. It is stateless: the paid step carries the same offer, and the backend checks the payment against the agreed price. An offer under the floor never lowers it. ## How payment is checked The shop answers `402` with a price and an address. The Mind pays through its wallet (owner approval, then the OutLayer policy), and the backend serves the report only for this Mind's own sent payment, confirmed on NEAR testnet by RPC, used once. This is a 402 pattern on testnet NEAR, not the x402 standard. The Mind only picks sellers its wallet may pay: the quotes say `onYourList`, read from the wallet's own policy. # How it works Source: https://docs.hellonear.xyz/how-it-works The parts of HelloNear and how one payment goes from a chat message to a NEAR transaction. ## The parts HelloNear's parts. The owner chats and approves in the web app or Telegram, which talk to the backend API; Meteor signs the wallet policy and Freeze on OutLayer. The backend sends each Mind's config and skills to the engine (Mastra): one generic Mind agent, 53 tools granted by equipped skills, and Builder workflows with Autopilot. The engine calls NEAR AI Cloud for every model call, NEAR Intents for dry quotes, Composio for apps, and NEAR RPC. The backend sends transfers to OutLayer, which checks the policy in a TEE and signs for NEAR testnet, uploads Intel quotes to Phala's TEE Explorer, and writes the Mind registry. HelloNear's parts. The owner chats and approves in the web app or Telegram, which talk to the backend API; Meteor signs the wallet policy and Freeze on OutLayer. The backend sends each Mind's config and skills to the engine (Mastra): one generic Mind agent, 53 tools granted by equipped skills, and Builder workflows with Autopilot. The engine calls NEAR AI Cloud for every model call, NEAR Intents for dry quotes, Composio for apps, and NEAR RPC. The backend sends transfers to OutLayer, which checks the policy in a TEE and signs for NEAR testnet, uploads Intel quotes to Phala's TEE Explorer, and writes the Mind registry. ## One payment, call by call One payment, call by call: the steps listed below for phones and screen readers.
    *** # Introduction Source: https://docs.hellonear.xyz/index HelloNear gives a person a Mind, an AI agent with a persona, memory, skills and its own NEAR wallet, whose money rules sit outside the model. A **Mind** reads your email, works in your apps and pays your bills, but **every limit that matters sits outside the model**: the owner approves, and the wallet's policy is checked inside a TEE before anything is signed. Every reply comes from NEAR AI Cloud's TEE with a proof you can check yourself. Built at **NEAR HACKATHON** (1 to 14 Nov 2026) for six tracks: security, privacy, agents, swarms, business and realworld. Everything runs on **NEAR testnet** during the hackathon. ## Live now | | | | - | - | | Web app (no account needed: *Continue as guest*) | [app.hellonear.xyz](https://app.hellonear.xyz) | | Landing page | [hellonear.xyz](https://hellonear.xyz) | | API (NEAR testnet) | [api.hellonear.xyz/v1/health](https://api.hellonear.xyz/v1/health) | | Status, checked every 5 minutes | [status.hellonear.xyz](https://status.hellonear.xyz) | | Docs (this site; `llms.txt` and an MCP server for agents) | [docs.hellonear.xyz](https://docs.hellonear.xyz) | | Trust Center, each claim linked to its proof | [trust.hellonear.xyz](https://trust.hellonear.xyz) | | Mind registry contract | [`hellonear-registry.testnet`](https://testnet.nearblocks.io/address/hellonear-registry.testnet?tab=contract) (v0.3.0, source verified) | | Swarm auction contract | [`auction.hellonear-swarm.testnet`](https://testnet.nearblocks.io/address/auction.hellonear-swarm.testnet?tab=contract) (source verified) | | OpenAPI spec | [openapi.json](https://github.com/Hellonear-AI/hellonear/blob/main/docs/openapi.json), rendered in the Endpoints tab (see the [API reference](/api-reference)) | | Repository | [github.com/Hellonear-AI/hellonear](https://github.com/Hellonear-AI/hellonear) | | X | [@hellonearai](https://x.com/hellonearai) | ## The problem An AI assistant that can pay is one prompt injection away from paying the wrong person. A rule written in the system prompt ("never send more than X") is advice to the model, not a limit: a malicious email, calendar invite or web page can talk the model out of it. And an AI that reads your private email should not leak it to the infrastructure it runs on. HelloNear's answer is to **take the limits out of the model** and **make the model's work verifiable**: 1. **Every payment asks the owner,** in the app or in Telegram, unless the owner turned on a rule for small payments to listed addresses. Without an approval or a rule, the payment tool cannot run. 2. **The wallet enforces its own policy.** Each Mind's wallet is an [OutLayer](https://outlayer.ai) wallet whose policy (per-payment limit, daily limit, allowed recipients) is stored on NEAR and checked in a TEE before anything is signed. A payment over the limit or to an unknown address is refused **even if the owner approved it**, and no transaction exists. 3. **Freeze.** One transaction, signed in the owner's own NEAR wallet, stops everything. 4. **Private, verifiable inference.** Every model call runs on NEAR AI Cloud inside a TEE. HelloNear checks each reply's signature against the hardware attestation before it shows the "Verified" badge, keeps that proof, and lets anyone open it on Phala's TEE Attestation Explorer. ## Where to go next * [Quickstart](/quickstart): try it in two minutes as a guest, or drive it with curl. * [Minds and templates](/minds), [Skills and tools](/skills), [Wallet, limits and approvals](/wallet-and-approvals): the core ideas. * [API reference](/api-reference): every route, from the OpenAPI spec. * [Trust Center](https://trust.hellonear.xyz): what protects your data and funds, each claim with a link you can check. ## For AI agents This site is readable by machines: [/llms.txt](https://docs.hellonear.xyz/llms.txt) lists every page, [/llms-full.txt](https://docs.hellonear.xyz/llms-full.txt) has them all in one file, any page is available as Markdown by adding `.md` to its path, [/skill.md](https://docs.hellonear.xyz/skill.md) describes what an agent can do with HelloNear, and a search MCP server answers at [/mcp](https://docs.hellonear.xyz/mcp). The site is hosted on Mintlify, which generates all four from these pages. # Minds and templates Source: https://docs.hellonear.xyz/minds What a Mind is, the three templates it starts from, and what the owner can change afterwards. A **Mind** is one AI agent with one job. It has a name and a voice (its persona), a memory of its owner, the skills it has equipped and, when it needs to pay, its own NEAR wallet. One owner can have several Minds. ## Templates A Mind starts from a template. The template picks its starting skills; the owner can equip or remove skills afterwards on the Skills page. | Template | `templateId` | Starting skills | | - | - | - | | **General Assistant** | `general-assistant` | Daily planner, Calendar conflicts, Health journal, Redact before send, Hire on Agent Market | | **Payments Mind** | `payments-mind` | Payments, Daily planner, Recipient guard, Split bill, Treasury report, Spending audit, Best price buyer, Freeze advisor | | **Email Manager** | `email-manager` | Email triage, Daily planner, Phishing detector, Follow-ups, Subscriptions & bills, Confidential reader, Calendar conflicts | Templates live in `engine/templates/*.json`. All three use the model `z-ai/glm-5.3-flash` on NEAR AI Cloud by default ([The agent](/agent) lists the models). ## What the owner controls * **Persona:** the name and the "soul" (how it talks). Changing either starts a fresh memory, so a renamed Mind does not carry the old persona's notes. * **Skills:** which playbooks and tools it has. See [Skills and tools](/skills). * **Memory:** read, edit or clear what it remembers, and switch off memory or the search of past chats. See [Privacy](/privacy). * **Wallet:** limits, allowed addresses and Freeze. See [Wallet, limits and approvals](/wallet-and-approvals). * **Approvals:** optional rules that skip the card for small payments to listed addresses, or for chosen actions. ## On chain A Mind can be recorded in the **Mind registry contract** (`hellonear-registry.testnet`): Mind, owner, wallet address and equipped skills. It holds no money; the wallet lives in OutLayer and the contract only stores its address. See [Receipts and smart contracts](/contracts). ## Through the API `GET /v1/templates` lists the templates; `POST /v1/minds` with `{ "templateId": "payments-mind", "name": "Penny" }` creates a Mind. See the [Quickstart](/quickstart) and the [API reference](/api-reference). # Payments CSV Source: https://docs.hellonear.xyz/payments-csv A file of every payment a Mind made or tried, with who approved it and the transaction link, that an accountant can open without asking. **Track:** `realworld`. The Wallet page has **Download CSV** beside Recent activity. The file has one row per payment attempt: date, status in words, amount, counterparty, purpose, who approved, tx hash and NearBlocks link. ## Try it After a payment in the app, open **Wallet** and click **Download CSV**. Through the API (owner only, with the session cookie): ```sh theme={null} curl -s -b jar $B/v1/minds/$MIND/payments.csv ``` ## Details * "Who approved" is read from the run's own events: `owner`, or `your rule` when the owner's rule skipped the card. * Refused payments are listed too, with their reason and no tx hash, because a payment the policy refuses has no transaction. * Cells that start like a spreadsheet formula get a leading `'`, so opening the file cannot run a formula. Source: `paymentsCsv` in `apps/be/src/payments.ts`. # Privacy: what is kept Source: https://docs.hellonear.xyz/privacy What the TEE protects, what HelloNear stores, what is never stored, and how the owner deletes it. The TEE protects the model calls. It does not make HelloNear's own backend blind: a Mind that remembers its owner needs that memory stored somewhere. This table says exactly where the line is. | Data | Who can see it | Kept? | | - | - | - | | **Prompts and replies while the model runs** | Nobody outside the TEE: not the cloud provider, not the model host, not NEAR AI. Each reply's signature is checked against the hardware attestation | HelloNear keeps the chat itself (next row); inside the TEE the operator cannot read it | | **Chat history** | The owner, and HelloNear's backend (Postgres, **not** in a TEE) | Yes, so the Mind can continue a chat. Deleting a chat also deletes its semantic-recall vectors (`engine/src/threads.ts`) | | **The Mind's memory of its owner** (working memory) | The owner (Mind settings → Memory), and HelloNear's backend | Yes, until the owner edits or clears it in Settings (`engine/src/memory.ts`) | | **API keys and connection secrets** | Nobody in plain text: AES-256-GCM, bound to the owner and the secret's name (`apps/be/src/crypto.ts`). The model only ever writes `{{secrets.NAME}}` | Encrypted, until the owner deletes it | | **Secrets and wallet tokens during a run** | Only the tool that uses them | **Never** in prompts, traces or stored run snapshots: they live in an in-memory map, and a test scans every table for them | | **Proofs behind the Verified badge** | Anyone with the run | Signatures, hashes and Intel's TDX quote only, never the conversation text | | **Guest sessions** | The guest | Deleted with all their Minds after the retention period (7 days) | So: HelloNear can keep your chats and memory to be useful, and you can delete them. It never stores your secrets in a form it can read back to the model, and the AI provider never sees your prompts outside the TEE. *** # Quickstart Source: https://docs.hellonear.xyz/quickstart Try HelloNear in the web app as a guest, or drive it with curl through the public API. ### In the web app (2 minutes, no account) > **During the hackathon everything runs on NEAR testnet, so judges can try it all for free.** *Continue as guest* needs no wallet, sign-up or payment: you get 20 messages, sample inbox and calendar data, and payments from a shared test wallet with HelloNear's limits. The AI runs on NEAR AI Cloud with the team's own credits, so you pay nothing for the model. Guest data is deleted after 7 days. 1. Open **[app.hellonear.xyz](https://app.hellonear.xyz)** → **Continue as guest** → pick the **Payments Mind**. 2. *"Send 0.01 NEAR to lin1er.testnet"*. See: an approval card with the amount, the recipient and the wallet's checks. Approve it. See: a receipt with a testnet transaction link. 3. *"Send 10 USDC to 0x8ba1f109551bD432803012645Ac136ddd64DBA72 on Base."* See: a NEAR Intents quote (what would arrive, the cost, the time), signed by 1Click, and the Mind saying nothing was sent. 4. Click **Verified via NEAR AI TEE gateway** under a reply → **View proof** → **Check it in TEE Explorer**. See: Phala's TEE Explorer opens on a report that reads VERIFIED. 5. *"Buy the gas price report, but I only want to pay 0.0006 NEAR. Haggle if it costs more."* See: the sellers' prices, then **Made an offer**. The Mind buys at the agreed price (approval card) or walks away and pays nothing; it never makes a second offer. 6. *"Pay 0.001 NEAR to hellonear-registry.testnet."* See: a warning that it is a smart contract, and a question. No approval card. 7. After a payment, open **Wallet**. See: **Download CSV** beside Recent activity, a file an accountant can open (date, status, amount, counterparty, purpose, who approved, tx hash, NearBlocks link). 8. Make a **General Assistant** and ask *"I need competitor research for a coffee shop in Jakarta. My budget is 1 USDC. Find the cheapest agent on the NEAR AI Agent Market that fits."* See: real agents from market.near.ai, a price from each, which fit the budget, and the cheapest recommended. Nothing is hired or paid (hiring is USDC on mainnet). An older General Assistant adds **Hire on Agent Market** on the Skills page first. 9. Open **Attack playground** and run a scenario. See: which layer stopped it. 10. Make an **Email Manager** and ask *"List my latest emails. Is any of them suspicious?"* See: the sample inbox, the phishing email flagged, nothing paid. ### Through the API The hosted backend is `https://api.hellonear.xyz`. Guest mode makes a temporary user (20 messages, deleted after 7 days). Replies stream as [server-sent events](https://github.com/Hellonear-AI/hellonear/blob/main/docs/api-contract.md#3-hellonear-events-engine--backend--browser). ```sh theme={null} B=https://api.hellonear.xyz # or http://localhost:4000 (see "Run locally") # 1. Start a guest session. See: 201 and "demo": true curl -s -c jar -X POST $B/v1/auth/demo -H 'content-type: application/json' -d '{}' # 2. List the Mind templates. See: email-manager, general-assistant, payments-mind curl -s -b jar $B/v1/templates # 3. Create a Payments Mind. See: 201 with the Mind's id (mnd_…) curl -s -b jar -X POST $B/v1/minds -H 'content-type: application/json' \ -d '{"templateId":"payments-mind","name":"Penny"}' M=mnd_... # the id from step 3 # 4. Ask for a cross-chain quote. See: tool.called crosschain_quote, a tool.result with # status "quote_only", to.amount, cost, seconds and proof.signedBy1Click: true; nothing sent curl -sN -b jar -X POST $B/v1/minds/$M/chat -H 'content-type: application/json' \ -d '{"message":"Send 10 USDC to 0x8ba1f109551bD432803012645Ac136ddd64DBA72 on Base."}' # 5. Ask to pay. See: tool.approval_required for send_payment, nothing sent yet curl -sN -b jar -X POST $B/v1/minds/$M/chat -H 'content-type: application/json' \ -d '{"message":"Send 0.01 NEAR to lin1er.testnet"}' curl -s -b jar $B/v1/minds/$M/approvals # the runId and toolCallId curl -sN -b jar -X POST $B/v1/runs/$RUN/approve -H 'content-type: application/json' \ -d '{"toolCallId":"…"}' # See: send_payment "sent" with a txHash # 6. The proof behind a reply. See: signers, signatures (hashes only) and the Intel quote, # then a TEE Explorer report URL with verified: true curl -s -b jar $B/v1/runs/$RUN/proof curl -s -b jar -X POST $B/v1/runs/$RUN/proof/tee-explorer -H 'content-type: application/json' -d '{}' ``` Ask for 1 NEAR and approve it. See: `policy_denied`, no transaction and no tx link: the wallet refused before signing. **Attack playground:** * `curl -s -b jar $B/v1/attacks`. See: `direct-order`, `email-injection`, `rogue-skill`, `tricked-owner`. * `curl -sN -b jar -X POST $B/v1/attacks/direct-order/runs -H 'content-type: application/json' -d '{}'`. See: the Mind refuses and `attack.verdict` has `"stoppedBy":"model"`. * `rogue-skill`: `"stoppedBy":"no_tool"`; `send_payment` never appears. * `tricked-owner`: sometimes the Mind refuses, sometimes it puts the payment on a card. Approve that card. See: `"stoppedBy":"policy"`, `policy_denied` ("not in whitelist") and **no tx hash**. **Autopilot** (a job built here as JSON; the Builder makes the same canvas): ```sh theme={null} curl -s -b jar -X PUT $B/v1/minds/$M/workflows/morning-brief -H 'content-type: application/json' -d '{"name":"Morning brief","nodes":[ {"id":"start","type":"trigger","data":{"schedule":{"cron":"30 7 * * 1-5","timezone":"Asia/Jakarta"}}}, {"id":"cal","type":"tool","data":{"tool":"googlecalendar_list_events","args":{}}}, {"id":"note","type":"agent","data":{"prompt":"In three short lines, brief me on today from these events: {{steps.cal.events}}"}}], "edges":[{"source":"start","target":"cal"},{"source":"cal","target":"note"}]}' curl -sN -b jar -X POST $B/v1/minds/$M/workflows/morning-brief/runs -H 'content-type: application/json' -d '{}' ``` Use a General Assistant (it has the calendar). An If compares a number or text from an earlier step (after a list, its count: "number of events is more than 0"). Turning the schedule on needs a wallet sign-in (a guest gets `403 demo_not_allowed`). **More prompts** (guests get a sample inbox and calendar): * *"Archive the newsletter and the StreamBox receipt."*: a card listing each email, saying nothing is deleted. * *"Brief me on today"*: meetings, emails that need you, money due, and a "Watch out" line for the phishing email. * *"Which subscriptions do I pay for?"*: StreamBox, CloudNotes and an invoice, with monthly totals; it never pays. * *"What's the gas price on NEAR testnet? Buy the report."*: a `402` price, a card for 0.001 NEAR, then the report with its tx hash. * *"Pay b0b.testnet 0.01"* after paying `bob.testnet`: a question about the lookalike, not a card. * *"Mark INV-12 as Paid in my Invoices sheet"* (with Sheets connected): card Now: Unpaid / New: Paid. * *"Move my 3pm client call to 4pm"*: card From / To; guests stay, nobody is emailed. * *"What is this app?"*: every Mind answers from the built-in guide. Every route and event is in [`docs/api-contract.md`](https://github.com/Hellonear-AI/hellonear/blob/main/docs/api-contract.md). *** # Gas relayer (NEP-366) Source: https://docs.hellonear.xyz/relayer A meta-transaction relayer that pays the gas for an owner's calls to the registry contract, never a deposit. **Track:** `realworld`. **Source:** `apps/be/src/relay.ts`, tests in `apps/be/test/relay.test.ts`. Owners should not need NEAR for gas to manage their Minds. The relayer accepts a NEP-366 signed delegate action from the signed-in owner and sends it, paying the gas. It is **live on the hosted demo** for two registry methods, `unequip_skill` and `set_wallet`, paid by `relayer.hellonear-swarm.testnet`, whose only key lives on the server. ## Limits * Only calls to the registry contract, only `unequip_skill` and `set_wallet`, with exactly 1 yoctoNEAR attached. A relayer pays any inner deposit too, so methods that need storage or a price (`register_mind`, `equip_skill`) are not relayed. * Everything that can be refused is refused before sending: sender is the signed-in account, receiver is the registry, gas, ed25519 signature, expiry within 1000 blocks, full-access key, nonce. A bad request costs no gas. * 10 per owner per hour. Not for try-out users. ## Through the API `POST /v1/relay { "signedDelegate": "" }`. Answers `503 relay_not_configured` until a relayer account is set. # Run locally Source: https://docs.hellonear.xyz/run-locally Run the engine, backend and web app on your own machine. Needs Node ≥ 24.22.1, Bun, Docker (OrbStack on macOS) and a NEAR AI Cloud API key. ```sh theme={null} docker compose up -d postgres # Postgres 17 + pgvector, capped at 1 CPU / 512 MB cd engine && cp .env.example .env # set NEARAI_API_KEY and ENGINE_API_KEY bun install && bun run dev # http://localhost:4100/v1/health cd ../apps/be && cp .env.example .env # same ENGINE_API_KEY; SECRETS_MASTER_KEY=$(openssl rand -base64 32); DEMO_MODE=true bun install && bun run migrate && bun run dev # http://localhost:4000/v1/health → {"ok":true,"engine":true} cd ../fe && NEXT_PUBLIC_API_URL=http://localhost:4000 bun run dev # http://localhost:3000 ``` Payments also need `DEMO_OUTLAYER_API_KEY` (an OutLayer wallet's agent key) in `apps/be/.env`. `docker compose stop` when done. **Tests:** `bun run test` in `engine/` and `apps/be/` (integration: real NEAR AI + local Postgres), `bun run test` in `apps/fe/`, `cargo test` in `sc/` (unit + local NEAR sandbox). Load: `k6 run engine/load/chat.js`, `k6 run engine/load/workflow.js`, `bun run load` in `apps/be/`. Each package has a GitHub Actions workflow. | Folder | What | | - | - | | `engine` | AI engine: Mastra 1.81 on NEAR AI Cloud, skills, tools, memory, Visual Builder, Autopilot, verification | | `apps/be` | Backend API: NEP-413 sign-in, Minds, OutLayer wallets, approvals, secrets, connections, Telegram, Postgres | | `apps/fe` | Web app (Next.js 16, NEAR Connect with Meteor first) | | `apps/landing` | Landing page | | `sc` | Mind registry contract (Rust `near-sdk` 5.29) | | `docs` | API contract between web app, backend and engine | | `design` | Design tokens, screens and Mind characters | | `deploy` | Hosted demo: systemd units, `deploy.sh`, automatic deploy after a merge | *** # Skills and tools Source: https://docs.hellonear.xyz/skills How skills grant tools, why a Mind without a payment skill cannot pay, and where every skill and tool is listed. A **skill** is a playbook plus a fixed list of tools. HelloNear has 33 equippable skills plus a built-in HelloNear guide. A **tool** is one action the model can call, such as `send_payment`, `gmail_list_emails` or `market_search`. ## Skills grant tools A Mind has exactly the tools its equipped skills grant. The backend sends the engine skill **ids**, never tool names, and the engine resolves the tool list for each request from the skills (`toolsFor` in `engine/src/tools.ts`). A tool no equipped skill grants does not exist for that run, so a Mind without a payment skill cannot pay, whatever an email or a web page tells it. You can see this in the Attack playground: *Use a skill it doesn't have* ends with `stoppedBy: no_tool`, because `send_payment` never appears. ## How a skill is written Each skill is a `SKILL.md` in `engine/skills//` with frontmatter (title, blurb, tools, connections, status) and a playbook in plain words. A unit test checks that every `SKILL.md` parses and uses only registered tools. A skill with status `blocked` is accepted but not loaded. ## Tools that act ask first Tools that change something (a payment, an email, a calendar event, a Sheets cell, a Notion row, a Doc, a Slack post, a Zoom meeting) pause the run for the owner's approval, with the old value shown next to the new one. Before the card is shown, the tool reads its target again, so an invented id or a stale value never gets a card. Every write also re-reads its target just before writing and refuses if it changed since the card was shown. ## Published skills on chain The Mind registry contract lets anyone publish a skill with a fixed price (`publish_skill`), and an owner equip it on a Mind (`equip_skill`), paying the publisher. See [Receipts and smart contracts](/contracts). ## Every skill and tool [The agent](/agent) lists all tools and all skills with the tools each one grants. Through the API: `GET /v1/skills` (the catalog) and `GET /v1/skills/{skillId}` (one skill with its `SKILL.md`). # Status Source: https://docs.hellonear.xyz/status Where to see whether HelloNear and its providers are up, and the contract of the public GET /v1/status endpoint. **[status.hellonear.xyz](https://status.hellonear.xyz)** shows whether HelloNear and the services it runs on answer. It was built on 13 Nov 2026 after two outages from outside HelloNear's code in one night: NEAR AI embeddings hung, and NEAR Intents 1Click quotes timed out. When a provider is down, a Mind says so plainly in the chat and points to the status page. ## What is checked Every 5 minutes the backend checks 9 services in parallel and keeps 8 days of results: | Service id | Group | Check | Slow over | Down after | | - | - | - | - | - | | `hellonear-api` | HelloNear | Postgres `select 1` | 1 s | 5 s | | `hellonear-engine` | HelloNear | engine `/v1/health` | 2 s | 10 s | | `nearai-chat` | NEAR AI | a chat completion, from the engine | 10 s | 30 s | | `nearai-embeddings` | NEAR AI | an embedding, from the engine | 5 s | 15 s | | `near-intents-quote` | NEAR | 1Click dry quote, 10 USDC NEAR to Base | 15 s | 30 s | | `outlayer` | Partners | OutLayer `/health` | 3 s | 10 s | | `near-rpc` | NEAR | FastNear testnet `status` | 3 s | 10 s | | `agent-market` | Partners | `market.near.ai/v1/agents?limit=1` | 5 s | 15 s | | `tee-explorer` | Partners | `HEAD proof.t16z.com` | 5 s | 15 s | Down also means an error, a non-2xx answer, or an answer without the expected field. If the engine does not answer, nothing is stored for NEAR AI that round; it is not guessed. ## GET /v1/status `GET https://api.hellonear.xyz/v1/status`: public, any origin, no cookies, `access-control-allow-origin: *`, `cache-control: public, max-age=30`. ``` { "updatedAt": ISO, "overall": "operational" | "degraded" | "down", "services": [{ "id", "name", "group": "HelloNear" | "NEAR AI" | "NEAR" | "Partners", "status": "operational" | "degraded" | "down" | "unknown", "latencyMs": number | null, "checkedAt": ISO | null, "detail": string | null, "impact": string, "uptime24h": number | null, "uptime7d": number | null, "history": [{ "start": ISO, "status": "operational" | "degraded" | "down" | "none", "checks": number, "bad": number, "detail": string | null }] }], "incidents": [{ "service", "name", "status": "down" | "degraded", "start": ISO, "end": ISO | null, "minutes": number, "detail": string | null }] } ``` * `status` is the latest check, or `unknown` when it is older than 15 minutes. * `overall` is `down` when a HelloNear service is down, `degraded` when anything else is down or degraded. Uptime counts degraded as up. * `history` is 48 half-hour buckets ending with the current one, oldest first: the worst check in each. * `incidents` (newest first, at most 100): consecutive non-operational checks of one service; one good check ends it. `end` is `null` while ongoing. * Details are short and never carry keys or URLs. ```sh theme={null} curl -s https://api.hellonear.xyz/v1/status | jq '.overall, [.services[] | {id, status}]' ``` # Swarm auction Source: https://docs.hellonear.xyz/swarm-auction A sealed-bid group-buying auction contract on NEAR testnet where buyer agents pool demand and seller agents compete at one clearing price. **Track:** `swarms`. **Contract:** [`auction.hellonear-swarm.testnet`](https://testnet.nearblocks.io/address/auction.hellonear-swarm.testnet?tab=contract), source `sc/swarm`, rules in [`RULES.md`](https://github.com/Hellonear-AI/hellonear/blob/main/sc/swarm/RULES.md). ## How a round works 1. The organizer opens a round with a price ceiling, a seller bond and a fixed timeline. Nobody can change the timeline afterwards. 2. **Buyers join with escrow:** units × ceiling. 3. **Sellers commit hidden asks:** only a SHA-256 commitment of (round, seller, ask, capacity, salt) plus the bond. Nobody can see the price. 4. **Sellers reveal.** Each reveal must hash to its commitment, and the bond comes back. A seller who never reveals loses its bond to the round's buyers. 5. **Anyone closes** the round at its time. The cheapest asks fill demand at **one clearing price**. 6. **Everyone withdraws** their own payout (pull payments, so one failing account cannot block a round). Every agent is its own NEAR sub-account of `hellonear-swarm.testnet`. ## A real round Round 0 on 13 Nov 2026: 3 buyers wanted 6 units at a ceiling of 0.01 NEAR; 2 sellers revealed 0.006 NEAR × 4 units and 0.008 NEAR × 5 units. All 6 units filled at **0.008 NEAR**. Every transaction is listed on [Receipts and smart contracts](/contracts#the-swarm-auction-one-real-round-on-testnet). Read it yourself: `get_round` with `{"round_id":0}` on `auction.hellonear-swarm.testnet` (public RPC, no key). ## Simulation A simulation of 20 buyers and 5 sellers with scripted strategies and no LLM runs three rounds on a local NEAR sandbox and checks money is conserved each round ([report](https://github.com/Hellonear-AI/hellonear/blob/main/sc/swarm/simulation-report.md)): ```sh theme={null} cd sc/swarm && cargo test --test simulation -- --nocapture ``` ## Safety The 13 Nov security review of the contract raised 9 findings, all fixed: no organizer timing power, seller bonds, storage paid by whoever adds it, commitments bound to round and seller, a fixed-size close event under NEAR's 16 KiB log cap, pull payouts with the balance zeroed before transfer, and checked math. Details in [`sc/swarm/README.md`](https://github.com/Hellonear-AI/hellonear/blob/main/sc/swarm/README.md). ## In the app Best price buyer runs each order as a small auction between sellers; Minds buy from and sell to other Minds, each with its own wallet. # Tech stack Source: https://docs.hellonear.xyz/tech-stack What is used where: NEAR, NEAR AI Cloud, NEAR Intents, OutLayer, Mastra and the rest. ## What is used where | Technology | Where in the repo | What it does in HelloNear | | - | - | - | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/near.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=b47b3e8535f7a73018725632933604f3)![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/near-white.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=28d47d2539a17e17b7c38899e1086b56) **NEAR Protocol** (testnet) | `sc/`, `apps/be/src/auth.ts`, `apps/be/src/wallets.ts` | The Mind registry contract (Minds, published skills, `equip_skill` pays the publisher); NEP-413 sign-in; every payment, policy change and freeze is a NEAR transaction | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/near-ai.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=932a6da3c70fd90a07fd18ebc5b5aeb7)![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/near-ai-black.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=7dbfb2a0cf5a09968e26518fc27af73f) **NEAR AI Cloud** | `engine/src/models.ts`, `engine/src/verify.ts`, `engine/src/titles.ts` | Runs every model call inside a TEE; HelloNear checks each reply's signature against the attestation before the Verified badge, and keeps the proof | | **NEAR Intents** (1Click API + official SDK) | `engine/src/crosschain.ts` | Cross-chain USDC/USDT quotes from NEAR to other chains; each quote's 1Click signature is verified with `verifyQuoteSignature` | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/agent-market.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=18c651d15e218c6f0ec904355f4e6df9) **NEAR AI Agent Market** ([market.near.ai](https://market.near.ai)) | `engine/src/market.ts`, skill `agent-market` | Searches the public catalog of agents and gets a job's exact price from the agent's own x402 answer (A2A, unpaid), then picks the cheapest within the owner's budget; hiring is paid in USDC on mainnet, so it only quotes for now | | **Swarm auction contract** (`near-sdk`, testnet) | `sc/swarm` | Sealed-bid group buying between agents, each its own sub-account; deployed at `auction.hellonear-swarm.testnet`, source verified | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/outlayer.png?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=38697d210839190e589708257b7e1921) **OutLayer** (testnet) | `apps/be/src/wallets.ts`, `apps/be/src/payments.ts` | One wallet per Mind; its policy (per-payment limit, daily limit, allowed recipients) is stored on chain and checked in a TEE before anything is signed; freeze | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/meteor-wallet-mark.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=4c1c8edf3c4636d674b9bb4da119559a) **Meteor Wallet** via **NEAR Connect** | `apps/fe` | The owner's wallet: signs in, signs the Mind wallet's policy, adds funds, freezes. Other NEAR Connect wallets work too | | **FastNear** testnet RPC | `engine/src/tools.ts`, `apps/be/src/config.ts` | Account lookups before a payment (`view_account`) and transfer checks after one (`tx`) | | **Phala TEE Attestation Explorer** | `apps/be/src/teeExplorer.ts` | Checks the Intel TDX quote behind a reply; the app opens its VERIFIED report | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/mastra.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=7eb11db3fcceae2ee71f338493665cdb)![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/mastra-white.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=245a7bd09c028f17a4723a66b06ad261) **Mastra** 1.81 | `engine/` | The agent: one generic Mind agent, tools, approvals (`requireApproval`, per-call rules, `beforeApproval`), memory, context limits, dynamic workflows for the Builder, workflow schedules for Autopilot | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/zai.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=248db4bbc3eab2e2cb0285e9e90a07ea) **GLM-5.3 Flash** (Z.ai), **DeepSeek V4.1 Flash**, **Qwen3 Embedding** | `engine/src/config.ts`, `engine/src/models.ts` | Chat, reasoning and memory embeddings, all served by NEAR AI Cloud | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/composio.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=dda4ece74d7859cca2abf8ef2a118126)![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/composio-white.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=1666ba6545c2cfebee00f953e67a7857) **Composio** | `apps/be/src/connections.ts`, `engine/src/composio.ts`, `engine/src/apps.ts`, `engine/src/calendar.ts`, `engine/src/zoom.ts` | The owner connects Gmail, Google Calendar, Meet, Sheets, Drive, Docs, Notion, Slack, Outlook and Zoom with OAuth (backend: Connect Links); the engine runs the app tools in a session scoped to that one owner | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/agentmail.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=84fbf823a296f8383f6f45a5e71dd546)![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/agentmail-white.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=45eeaf3b39fdc8f8ca06d9c185744917) **AgentMail** | `apps/be/src/mail.ts`, `engine/src/mail.ts` | Each Mind's own email address (`…@agentmail.to`): send after approval, read its inbox with spam and phishing warnings, email the owner | | ![](https://mintcdn.com/hellonear/3IKejfz0eoJyd-83/images/brands/telegram.svg?fit=max\&auto=format\&n=3IKejfz0eoJyd-83\&q=85\&s=5bb368ca63aa6b994bf52ad689e1a518) **Telegram Bot API** | `apps/be/src/telegram.ts`, `apps/be/src/telegramFormat.ts` | A bot per Mind: chat, streamed replies, Approve / Decline buttons; only the owner's chat is answered | | **Postgres 17 + pgvector** | `apps/be/migrations/`, `engine/src/mastra.ts` | Runs, events, approvals, encrypted secrets (backend); Mastra storage, run snapshots and memory vectors (engine) | | **Next.js 16, React 19, GSAP, React Flow** | `apps/fe`, `apps/landing` | The web app (chat, live view, Builder canvas, wallet, settings) and the landing page | | **Rust, `near-sdk` 5.29, `near-sandbox`** | `sc/` | The registry contract and its sandbox tests, including upgrades | | **Bun, Node 24, k6** | every package | Package manager and runtime; load tests | | **Proxmox LXC + Cloudflare Tunnel** | `deploy/` | The hosted demo; a merged `main` is deployed automatically after its CI passes | *** ## How NEAR is used | What | Where | Proof | | - | - | - | | **NEAR AI Cloud**: every model call runs in a TEE; each reply is checked against the attestation and marked verified | `engine/src/models.ts`, `engine/src/verify.ts` | `run.verified` event, `engine/test/verify.test.ts`, the TEE Explorer report above | | **The proof behind the badge**: signatures and Intel's TDX report kept and shown under View proof; the backend uploads the Intel quote to Phala's TEE Attestation Explorer and the app opens the verified report | `engine/src/verify.ts`, `apps/be/src/teeExplorer.ts`, `apps/fe/src/modules/runs/components/ProofDialog.tsx` | `GET /v1/runs/{runId}/proof`, `POST /v1/runs/{runId}/proof/tee-explorer` | | **NEAR Intents (1Click API)**: cross-chain stablecoin quotes, each signed by 1Click and checked with the official SDK | `engine/src/crosschain.ts` | `engine/test/crosschain.test.ts`, the live quotes above | | **OutLayer wallets** on testnet: one per Mind, policy v2 (per-payment limit, daily limit, recipients) enforced in a TEE; policy and freeze are calls on `outlayer.testnet` the owner signs | `apps/be/src/wallets.ts` | the payment, policy and freeze transactions above | | **NEP-413 sign-in** with the owner's NEAR wallet (Meteor first, any NEAR Connect wallet works) | `apps/be/src/auth.ts` | `apps/be/test/api.test.ts` | | **Mind registry contract** (Rust, `near-sdk` 5.29) on `hellonear-registry.testnet`: Minds, published skills, and `equip_skill` pays the skill's publisher | `sc/` | `sc/README.md` (deploy transactions, code hash), sandbox tests in `sc/tests/` | | **Swarm auction contract** (Rust, `near-sdk` 5.29) on `auction.hellonear-swarm.testnet`: sealed-bid group buying, every agent its own sub-account, source verified | `sc/swarm` | [a real round's transactions](/contracts#the-swarm-auction-one-real-round-on-testnet), `sc/swarm/tests/simulation.rs` | | **Meta transactions (NEP-366)**: a relayer pays the gas for an owner's calls to the registry, never a deposit | `apps/be/src/relay.ts` | `apps/be/test/relay.test.ts` | | **NEAR AI Agent Market**: agents from market.near.ai, priced through their x402 answer (paid with a NEP-366 USDC transfer on mainnet, so quoted only here) | `engine/src/market.ts` | `engine/test/market.test.ts`, Try it step 8 | | **NEAR RPC** (FastNear testnet): account lookups (including whether the account is a contract) and transfer checks the Mind uses before and after paying | `engine/src/tools.ts` | `engine/test/near-tool.test.ts` | *** # Telegram Source: https://docs.hellonear.xyz/telegram Chat with a Mind from Telegram, with streamed replies and Approve or Decline buttons, answered only in the owner's chat. Each Mind can have its own Telegram bot. The owner makes the bot with @BotFather and gives its token to HelloNear in the Mind's settings. ## How it works * **Linking:** HelloNear checks the token with Telegram, stores it encrypted, and answers with a one-time `t.me/?start=` link. The private chat that sends that code becomes the owner. Every other chat is ignored without a reply. * **Chat:** an owner message runs as a normal chat, in one thread per bot, with the same events and limits as the app. Times are in UTC, since Telegram sends no time zone. * **Streaming:** the reply appears at once and the same message is edited as it grows, at most once every 1.5 s, with "typing…" while a tool runs. * **Rich text:** the Mind's Markdown is converted to Telegram's HTML by HelloNear's own small converter. Only http and https links become links, and a labelled link shows its host after it, so a stranger cannot hide where a link goes. ## Approvals in Telegram Each approval the Mind asks for comes as its own message with the same checks as the app's card, and buttons **Approve**, **Decline** and **Open in app**. Only a press from the owner's chat counts; anyone else gets "Only the owner can approve". The first press uses up both buttons. There is no Approve button when the wallet policy would refuse the payment or the wallet holds less than the payment. Approval cards never read their words as Markdown: their text comes from tool arguments (an email subject, an event title someone else wrote), so nobody can inject a link into a message that asks the owner to approve. The app and Telegram cannot resume one run twice: a run is claimed in one database update before it continues. ## Through the API `PUT /v1/minds/{id}/telegram { token }` links a bot; `DELETE` unlinks it. See the [API reference](/api-reference). # The six tracks Source: https://docs.hellonear.xyz/tracks What HelloNear built for each NEAR HACKATHON track, the skills that carry it, and how to check it. HelloNear is submitted to six tracks. For each one: what the organizers ask for (quoted from the *Build* and *Hints* columns of HACKATHON.md), what HelloNear built for it, the skills that carry it, and how to check it. | Track | Why HelloNear fits, in one line | | - | - | | [`security`](https://github.com/Hellonear-AI/hellonear#security-ai-security--defense) | An AI with money whose limits it cannot touch: approval, an OutLayer policy checked in a TEE before signing, freeze, scam and lookalike checks, and an Attack playground | | [`privacy`](https://github.com/Hellonear-AI/hellonear#privacy-privacy--private-ai) | Every reply runs on NEAR AI Cloud in a TEE and is verified against its attestation, with a proof anyone can open on Phala's TEE Explorer | | [`agents`](https://github.com/Hellonear-AI/hellonear#agents-agent-economy) | Minds pay for data (402), sell to other Minds, compare sellers, invoice, and quote payments through NEAR Intents, inside the owner's limits | | [`swarms`](https://github.com/Hellonear-AI/hellonear#swarms-ai-swarms) | Every purchase is a small auction between sellers; Minds trade with other Minds; one request pays several people, each approved | | [`business`](https://github.com/Hellonear-AI/hellonear#business-autonomous-business) | The owner sets the constraints; the Mind runs the treasury: reports, audits, revenue sharing, invoices, procurement, scheduled jobs | | [`realworld`](https://github.com/Hellonear-AI/hellonear#realworld-real-world-money) | Invoices with payment checked on chain, bills found in Gmail, and stablecoin payments to other chains quoted through NEAR Intents | ### `security`: AI Security & Defense | | | | - | - | | **The track asks for** | "Build spending limits, policy engines, sandboxed wallets, reputation and scam detection. Give AI money without giving it the keys to everything." Hints: agent security, function call keys, TEE attestation | | **What HelloNear built** | Seven layers that each stop an attack alone: the model, skills that grant tools, the owner's approval, the OutLayer wallet policy checked **in a TEE before signing**, a daily limit, freeze, and unattended jobs with no payment tools. Writes re-check their target before writing. A Recipient guard that answers allow, warn or block with the reason before every payment (where the recipient came from, that it exists, lookalikes of people already paid, first payments, contracts), a Phishing check, and an Attack playground that names the layer that stopped each attack. Why not function-call keys: they cannot transfer NEAR and their allowance is gas, not a spending cap | | **Skills** | Recipient guard, Phishing check, Freeze advisor, Spending audit, Payments | | **Check it** | Attack playground, any scenario: `attack.verdict` names the layer. Approve 1 NEAR: `policy_denied`, no transaction | ### `privacy`: Privacy & Private AI | | | | - | - | | **The track asks for** | "Explore confidential computation, private finance and AI that protects sensitive data. Build intelligence without exposure." Hints: private AI, TEE, NEAR AI Cloud | | **What HelloNear built** | Every model call runs on **NEAR AI Cloud** inside a TEE. Each reply's signature is checked against the hardware attestation before the Verified badge shows; the proof is kept, shown under View proof, and opens on Phala's TEE Explorer as VERIFIED. Secrets and wallet tokens never reach the model, traces or stored snapshots. Skills that read sensitive email without sending it anywhere | | **Skills** | Confidential reader, Redact before send, Health journal | | **Check it** | Verified badge → View proof → Check it in TEE Explorer: a VERIFIED report whose nonce matches the dialog. What is kept and what is not: [What is private, and what HelloNear keeps](/privacy) | ### `agents`: Agent Economy | | | | - | - | | **The track asks for** | "Build agents that earn, spend, negotiate, hire other agents and pay for APIs, compute or data , with crypto directly or through NEAR Intents." Hints: agent commerce, NEAR Intents, chain signatures | | **What HelloNear built** | Minds pay for data with a 402 pattern on testnet NEAR (price, approved payment, report with the tx hash as receipt), sell what they made to other Minds into their own wallet, compare sellers before buying, invoice and check payment on chain, quote cross-chain payments through **NEAR Intents**, haggle once with a seller (offer within the owner's budget, then buy at the agreed price or walk away), and find agents on the **NEAR AI Agent Market** (market.near.ai) with each job's exact price from the agent's own x402 answer, picking the cheapest one within the owner's budget (hiring is paid in USDC on mainnet, so it only quotes for now). All inside the owner's limits | | **Skills** | Paid data, Best price buyer, Hire on Agent Market, Price watch, Mind as seller, Invoice & get paid, Payments | | **Check it** | *"What's the gas price on NEAR testnet? Buy the report."*: a `402` price, a card for 0.001 NEAR, then the report and its tx hash | ### `swarms`: AI Swarms | | | | - | - | | **The track asks for** | "Build coordination markets, bidding, collective purchasing, intent-based settlement and emergent economies between agents." Hints: multi-agent systems, NEAR Intents, sub-accounts | | **What HelloNear built** | A **sealed-bid group-buying auction contract** ([`sc/swarm`](https://github.com/Hellonear-AI/hellonear/blob/main/sc/swarm), rules in [`RULES.md`](https://github.com/Hellonear-AI/hellonear/blob/main/sc/swarm/RULES.md)): buyer agents pool demand with escrow, seller agents commit hidden asks with a bond and reveal them, the cheapest asks fill demand at one clearing price, and every agent is its own NEAR sub-account. A simulation of **20 buyers and 5 sellers with scripted strategies and no LLM** runs three rounds on a local NEAR sandbox and checks money is conserved each round ([report](https://github.com/Hellonear-AI/hellonear/blob/main/sc/swarm/simulation-report.md)); an independent audit's 9 findings are fixed. In the app, Best price buyer runs each order as a small auction between sellers and buys only from one the wallet may pay; Minds buy from and sell to other Minds (each with its own wallet); Split bill and Revenue split pay several people from one request, each payment approved on its own | | **Skills** | Best price buyer, Mind as seller, Split bill, Revenue split; contract `sc/swarm` | | **Check it** | [One real round on testnet](/contracts#the-swarm-auction-one-real-round-on-testnet): every step's transaction, 6 units filled at one clearing price. Locally, `cd sc/swarm && cargo test --test simulation -- --nocapture`: 20 buyers and 5 sellers, three rounds, a clearing price per round and who got what. In the app: *"Split 0.02 NEAR between alice.testnet and bob.testnet"*: shares worked out in yoctoNEAR, one card per person | ### `business`: Autonomous Business | | | | - | - | | **The track asks for** | "Build AI-native businesses with treasury, sales, procurement, cross-chain payments via NEAR Intents and revenue sharing. Humans only set the constraints." Hints: AI agents, NEAR Intents, chain signatures | | **What HelloNear built** | The owner sets the constraints (per-payment and daily limits, allowed recipients, approval rules) and holds a kill switch (Freeze, one signature); the Mind runs the treasury: daily treasury reports, a weekly spending audit, revenue sharing between partners, invoices and follow-ups, procurement through Best price buyer, cross-chain quotes through NEAR Intents, and Autopilot jobs that run on a schedule | | **Skills** | Treasury report, Spending audit, Revenue split, Invoice & get paid, Follow-ups, Subscriptions & bills | | **Check it** | *"Give me today's treasury report"*: balance, what went out, what is pending, read only | ### `realworld`: Real-World Money | | | | - | - | | **The track asks for** | "Build payroll, invoicing, remittances, merchant payments and stablecoin rails for real businesses. Something a normal company could use tomorrow." Hints: stablecoins, NEAR Intents, meta transactions | | **What HelloNear built** | Invoices sent from the Mind's own email address with payment checked by its transaction on chain; bills and subscriptions found in the owner's Gmail; a payments CSV an accountant can open without asking (`GET /v1/minds/{id}/payments.csv`: date, status in words, amount, counterparty, purpose, who approved, tx hash and NearBlocks link); a meta-transaction relayer (NEP-366) that pays gas only for owner calls to our own registry contract and never pays a deposit; USDC/USDT payments to other chains quoted through **NEAR Intents**, signed by 1Click and checked with the official SDK (sending needs mainnet); every payment approved by the owner and limited by the wallet | | **Skills** | Invoice & get paid, Subscriptions & bills, Spending tracker, Payments | | **Check it** | *"Send 10 USDC to 0x8ba1f109551bD432803012645Ac136ddd64DBA72 on Base."*: what would arrive, the cost, the time, `proof.signedBy1Click: true`, nothing sent | *** # Verified replies Source: https://docs.hellonear.xyz/verified-replies How every reply is checked against NEAR AI Cloud's TEE attestation, what the badge levels mean, and how to open the proof on Phala's TEE Explorer. Every model call runs on **NEAR AI Cloud** inside a TEE. After a reply finishes, the engine fetches each completion's signature and checks it against the hardware attestation (`engine/src/verify.ts`) before the app shows the **Verified** badge. ## Badge levels The badge shows the weakest step's level, at the level the NEAR AI SDK proves: | Level | Meaning | | - | - | | `model_tee` | The model itself ran in a TEE and signed the reply | | `gateway_tee` | NEAR AI's gateway TEE signed the reply (streaming replies are checked at this level) | Only verifiable (Confidential or third-party TEE) models get a badge. Incognito models never do. ## What is kept The proof behind the badge is stored on the run's `run.verified` event: signatures, hashes and Intel's TDX quote. Never the conversation text. It is about 12 KB, mostly the quote, and it is never streamed: only the owner can read it, through `GET /v1/runs/{runId}/proof`. ## Check it yourself In the app: click **Verified via NEAR AI TEE gateway** under a reply, then **View proof**, then **Check it in TEE Explorer**. The backend uploads the Intel quote to Phala's TEE Attestation Explorer (`POST /v1/runs/{runId}/proof/tee-explorer`) and the app opens the report. Only the quote leaves, no conversation text, and the report then shows in the Explorer's public list of recent attestations. A real report: [proof.t16z.com/reports/1b374e5b…](https://proof.t16z.com/reports/1b374e5b10031496c6c45bc7749038d7e7cd26a16996455f893b6b5dd44a9db2) reads **VERIFIED**. Its report data ends with that run's nonce (`…99e266`), and its MRCONFIG carries the compose hash (`877959253d…`) found in the proof. ## Events `run.verified` follows `run.finished` on the stream. See [Streaming events](/events). # Wallet, limits and approvals Source: https://docs.hellonear.xyz/wallet-and-approvals The layers that keep a Mind from paying what the owner did not allow: approval, the wallet policy in a TEE, the daily limit and Freeze. Each layer stops an attack on its own; the ones further down do not trust the ones above. | Layer | What it stops | Do this, see that | | - | - | - | | **The model** | Obvious tricks: an email or message telling "the AI" to pay someone | Attack playground, *Hide it in an email*. See: the Mind lists the email under "Watch out" and does not ask to pay (`stoppedBy: model`) | | **Skills grant tools** | A Mind without a payment skill has no payment tool, whatever it is told | Attack playground, *Use a skill it doesn't have*. See: `send_payment` never appears (`stoppedBy: no_tool`) | | **The owner's approval** | Any payment the model was talked into: nothing is sent until the owner approves | Ask a Payments Mind to pay. See: an approval card that names the amount, the recipient and the checks below | | **The wallet policy (OutLayer, in a TEE)** | A payment the owner approved by mistake: over the per-payment limit or to an address not on the list is refused before signing, with no transaction | Approve a payment above the limit. See: `policy_denied`, no tx hash. The card already says "blocked even if you approve" | | **Daily limit (OutLayer, in a TEE)** | Many small payments that add up: once today's payments reach the daily limit, the next one is refused before signing; the day starts at 00:00 UTC | Wallet → Edit → *Per day*. See: "Spent today: X of Y NEAR" | | **The owner's rules (opt-in)** | Nothing by themselves: they only skip the card the owner chose to skip, only up to the owner's amount and only to a listed address. Guests and the Attack playground always ask, and the TEE policy still checks every payment | Mind settings → Approvals → payments up to 0.01. See: no card, and the receipt says "Approved by your rule" | | **Freeze (the kill switch)** | Everything, at once: one transaction the owner signs | Wallet → Freeze wallet (on your own Mind). See: every later payment ends `wallet_frozen` | | **Unattended jobs** | Autopilot jobs get no payment or approval tools; they may only email the owner or add to the owner's calendar, as steps the owner placed | Builder → Use a tool → *Email me*. See: it can only send the Mind's notes, to your own Gmail | **Why not a capped function-call key?** NEAR function-call access keys cannot transfer NEAR, and their `allowance` is a gas budget for the key's whole life, not a spending cap ([docs](https://docs.near.org/protocol/accounts-contracts/access-keys)). The spending rules therefore live in the wallet's policy, which OutLayer checks in its TEE before every signature.