A carved pumpkin with a glowing Nirium N
🎃 Niriumtober · Oct 22 to Nov 2🏆 Champion wins a Niriumtober hoodie

Ship your first agent receipt on Stellar this Halloween

Copy one snippet, run it on testnet in 5 minutes, earn a 3D badge. Free, no funds needed.

10K+ package downloads on npm and PyPI · 2 SCF Instawards · Open source

No cash prizes. The Champion gets a hoodie.

Watch in 60 seconds

English voiceover with captions.

Your badge in 3 steps

Everything runs on testnet. Your key, your receipt.

A cauldron with coins and a receipt floating out of it
  1. 1

    Install

    npm i nirium @stellar/stellar-sdk@16
  2. 2

    Anchor a receipt

    More nodes →
    import { Agent } from 'nirium';
    import { Keypair } from '@stellar/stellar-sdk';
    import { createHash } from 'node:crypto';
    
    const kp = Keypair.random(); // a new testnet key, no funds needed. Save kp.secret() to reuse it
    const sha = createHash('sha256').update('my first Niriumtober receipt').digest('hex');
    const signature = Buffer.from(kp.sign(Buffer.from(`nirium-audit-v1:${sha}`))).toString('base64');
    
    const agent = new Agent({ baseUrl: 'https://nirium-agent.fly.dev' });
    const { cid } = await agent.anchorAuditRecord({ hash: sha, tag: 'niriumtober', agent: { key: kp.publicKey(), signature } });
    console.log('CID:', cid);
    console.log('Your public key:', kp.publicKey());

    Save it as receipt.mjs and run node receipt.mjs. It prints your CID and your public key. No account and no funds needed.

    Using Claude or Cursor? Give it the Nirium skill and let it build this for you
  3. 3

    Send your proof

    Open the form, paste your CID and your public key. It is public, so never paste your secret key.A repo is optional for Builder. Mainnet Builder and Champion need a public repo.

    Send your proof

That's it: you just earned Builder 🔨

Collect all 4

Builder badge, teal medal with a hammer
Builder
Anchor a receipt on testnet from your project.
Contributor badge, copper medal with a wrench
Contributor
Get a PR merged from the issue list.
Mainnet Builder badge, gold medal with a trophy
Mainnet Builder
Use Audit Trail or x402 Market on mainnet with your key. Needs a public repo.
Champion badge, gold and purple medal with a crown
Champion
The best project wins it. One only. Needs a public repo.

Champion

The recognition for the best project or contribution of all Niriumtober. One only.

How it is chosen

The Nirium team picks it at the close, on Nov 2, among every project and contribution with valid evidence. If none deserves it, it is not awarded.

Public criteria
  • Real use with your own key, above all on mainnet with Audit Trail or x402 Market.
  • Quality, and a real integration in your product.
  • What it gives the community: code, docs, useful feedback.
What it gets
Niriumtober Champion hoodie
Render. Final hoodie may vary slightly.

🎃 An official Niriumtober hoodie, shipped to you.

  • Featured first in Built with Nirium on nirium.xyz.
  • A dedicated post from @Niriumstellar.
  • A 30-minute call with the team to review your integration.
  • The same perks as everyone, first in line.

One hoodie, for the Champion only. Chosen by the Nirium team on Nov 2 on the public criteria above. No chance involved, and no purchase or payment of any kind is needed to compete: Audit Trail on testnet is free.

Free shipping within Mexico. Outside Mexico, the Champion chooses: cover international shipping, or get a one-of-one 3D Champion badge with their project's name, made by the team.

Champion adds no points: it is awarded apart from the points table. Its badge uses the same issuer key and tag niriumtober-2026, with badge: "champion".

A gold Nirium trophy for the Mainnet Builder badge

Level up: go mainnet

  1. Audit Trail: anchor a receipt on mainnet with agent signed by your key. Free during the beta.
  2. x402 Market: one paid call (0.05 USDC) from your own account.

Optional, with your own funds and at your own risk. We never fund or refund mainnet transactions.

Show the mainnet code

1 · Audit Trail (free in beta)

Use your own mainnet key in STELLAR_SECRET. Never paste your secret key anywhere.

import { Agent } from 'nirium';
import { Keypair } from '@stellar/stellar-sdk';
import { createHash } from 'node:crypto';

const kp = Keypair.fromSecret(process.env.STELLAR_SECRET); // your own key
const sha = createHash('sha256').update('my evidence').digest('hex');
const signature = Buffer.from(kp.sign(Buffer.from(`nirium-audit-v1:${sha}`))).toString('base64');
const agent = new Agent({ baseUrl: 'https://nirium-agent-mainnet.fly.dev' });
const { cid } = await agent.anchorAuditRecord({ hash: sha, tag: 'niriumtober', agent: { key: kp.publicKey(), signature } });
console.log('CID:', cid);

2 · x402 Market (0.05 USDC)

Use your own mainnet key in STELLAR_SECRET. Never paste your secret key anywhere. Your account needs a USDC trustline and a USDC balance on mainnet.

import { Agent } from 'nirium';

const agent = new Agent({ baseUrl: 'https://nirium-agent-mainnet.fly.dev' });
agent.initX402({ secretKey: process.env.STELLAR_SECRET, network: 'stellar:pubnet' }); // your own key, with USDC
const res = await agent.x402Fetch('https://nirium-agent-mainnet.fly.dev/api/v1/premium/market'); // 0.05 USDC
console.log(res.status, JSON.parse(atob(res.headers.get('payment-response'))).transaction); // tx hash
Send your mainnet proof

Mainnet Builder needs a public repo.

Come back tomorrow

Anchor again on mainnet on a second day: +2 points.

Share it

Post on X

Bring a teammate. Teams are welcome.

Why join

  • Priority for issues in future GrantFox campaigns. Each campaign sets its own reward.
  • First invite to our next hackathons, events and workshops.
  • A spot in Built with Nirium, if your project uses Nirium.
  • A shoutout from @Niriumstellar.
  • Early access to new nodes on testnet.

Priorities, not promises.

Get testnet tokens

Testnet tokens are free and have no real value. This page only ever asks for your public key, never your secret key.

XLM

Get testnet XLM (Friendbot)

USDC

  1. Add the USDC trustline first (the script below does it).
  2. In the Circle faucet, choose Stellar.
  3. Paste your address and request it.
Get testnet USDC (Circle faucet)

CETES has no faucet: it comes from the DEX, in the script.

Set up your account

One run: it creates a key, funds it with Friendbot, adds the USDC and CETES trustlines and swaps 20 XLM into each on the testnet DEX. If the DEX has no USDC route, it adds the trustline and sends you to the Circle faucet.

import { Keypair, Horizon, TransactionBuilder, Operation, Asset, Networks } from '@stellar/stellar-sdk';
import { existsSync, readFileSync, writeFileSync } from 'node:fs';

const FILE = 'niriumtober-testnet.key';
const horizon = new Horizon.Server('https://horizon-testnet.stellar.org');
const USDC = new Asset('USDC', 'GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5'); // Circle
const CETES = new Asset('CETES', 'GC3CW7EDYRTWQ635VDIGY6S4ZUF5L6TQ7AA4MWS7LEQDBLUSZXV7UPS4');

// 1. A new testnet key, saved next to this script (run it again and it reuses the same key)
if (!existsSync(FILE)) writeFileSync(FILE, Keypair.random().secret(), { mode: 0o600 });
const kp = Keypair.fromSecret(readFileSync(FILE, 'utf8').trim());

// 2. Testnet XLM from Friendbot
const funded = await horizon.loadAccount(kp.publicKey()).then(() => true, () => false);
if (!funded) await fetch(`https://friendbot.stellar.org?addr=${kp.publicKey()}`);

// 3. Trustlines for USDC and CETES, and 4. swap 20 XLM into each on the testnet DEX
const tx = new TransactionBuilder(await horizon.loadAccount(kp.publicKey()), { fee: '1000', networkPassphrase: Networks.TESTNET })
    .addOperation(Operation.changeTrust({ asset: USDC }))
    .addOperation(Operation.changeTrust({ asset: CETES }));
const toAsset = (a) => (a.asset_type === 'native' ? Asset.native() : new Asset(a.asset_code, a.asset_issuer));
for (const asset of [USDC, CETES]) {
    const [route] = (await horizon.strictSendPaths(Asset.native(), '20', [asset]).call()).records;
    if (!route) {
        console.log(asset === USDC ? 'No DEX route to USDC: now ask for USDC at https://faucet.circle.com' : 'No DEX route to CETES right now, try again later');
        continue;
    }
    tx.addOperation(Operation.pathPaymentStrictSend({
        sendAsset: Asset.native(), sendAmount: '20', destination: kp.publicKey(), destAsset: asset,
        destMin: (Number(route.destination_amount) * 0.9).toFixed(7), path: route.path.map(toAsset),
    }));
}
const built = tx.setTimeout(60).build();
built.sign(kp);
console.log('Transaction:', (await horizon.submitTransaction(built)).hash);

// 5. What you have now
console.log('Public key:', kp.publicKey());
for (const b of (await horizon.loadAccount(kp.publicKey())).balances) console.log(`  ${b.asset_code ?? 'XLM'}: ${b.balance}`);
console.log(`Secret key saved in ./${FILE}. Keep it out of git and never share it.`);

Save it as setup.mjs and run node setup.mjs (same install as step 1). It prints your public key and balances, and keeps the secret key in niriumtober-testnet.key, out of git.

Explore every node

Any node on testnet earns you Builder. Use several: Champion is decided by real use.

Same install as step 1: npm i nirium @stellar/stellar-sdk@16. Every snippet below was run on testnet.

Audit Trail

TestnetMainnet

Anchor a signed receipt of anything your agent did. Anyone can verify it.

FreeBuilder · +3 on mainnet
import { Agent } from 'nirium';
import { Keypair } from '@stellar/stellar-sdk';
import { createHash } from 'node:crypto';

const kp = Keypair.random(); // a new testnet key, no funds needed. Save kp.secret() to reuse it
const sha = createHash('sha256').update('my first Niriumtober receipt').digest('hex');
const signature = Buffer.from(kp.sign(Buffer.from(`nirium-audit-v1:${sha}`))).toString('base64');

const agent = new Agent({ baseUrl: 'https://nirium-agent.fly.dev' });
const { cid } = await agent.anchorAuditRecord({ hash: sha, tag: 'niriumtober', agent: { key: kp.publicKey(), signature } });
console.log('CID:', cid);
console.log('Your public key:', kp.publicKey());

node receipt.mjs

x402 Market

TestnetMainnet

Pay per request for market data, from your own key.

Needs testnet USDCBuilder · +3 on mainnet
import { Agent } from 'nirium';

const agent = new Agent({ baseUrl: 'https://nirium-agent.fly.dev' });
agent.initX402({ secretKey: process.env.STELLAR_SECRET, network: 'stellar:testnet' }); // a testnet key holding testnet USDC
const res = await agent.x402Fetch('https://nirium-agent.fly.dev/api/v1/premium/market'); // 0.05 testnet USDC
console.log(res.status, JSON.parse(atob(res.headers.get('payment-response'))).transaction); // tx hash

STELLAR_SECRET=S... node pay.mjs

Payouts

Testnet

Pay several people in one run. You sign it, Nirium never does.

Needs testnet USDC and a free API keyBuilder
Get your free API key
import { Agent } from 'nirium';
import { Keypair, TransactionBuilder, Networks } from '@stellar/stellar-sdk';

const kp = Keypair.fromSecret(process.env.STELLAR_SECRET); // pays: needs testnet USDC
const agent = new Agent({ apiKey: process.env.NIRIUM_API_KEY, baseUrl: 'https://nirium-agent.fly.dev' }); // free key: nirium.xyz/keys
const run = await agent.createPayoutRun({ treasury: kp.publicKey(), acknowledgeTerms: true,
  recipients: [{ wallet: process.env.TO_1, amount: '0.5' }, { wallet: process.env.TO_2, amount: '0.5' }] }); // each needs a USDC trustline
const tx = TransactionBuilder.fromXDR(run.xdr, Networks.TESTNET); tx.sign(kp); // you sign, Nirium never does
const done = await agent.submitPayout(run.runId, tx.toXDR());
console.log(done.txHash, done.cid);

STELLAR_SECRET=S... NIRIUM_API_KEY=sk_... TO_1=G... TO_2=G... node payouts.mjs

Packages and keys

Add payments, receipts and payouts to your app or agent in TypeScript.

npm i nirium @stellar/stellar-sdk@16
nirium
PyPI

The same, from Python.

pip install nirium

Let Claude, Cursor or any MCP assistant use Nirium for you.

npx nirium-mcp

Set the environment variables from its README. The free tools work without them.

Give it to Claude, Cursor or your AI assistant and it builds a paid x402 API for you, in one command.

mkdir -p ~/.claude/skills/nirium-agentic-payments && curl -fsSL https://raw.githubusercontent.com/nirium-protocol/nirium/main/skills/nirium-agentic-payments/SKILL.md -o ~/.claude/skills/nirium-agentic-payments/SKILL.md

The command above installs it for Claude Code. With other assistants, paste the link to the skill.

Start a project and check your agent from the terminal.

npm i -g nirium-cli

Pay and anchor receipts with a wallet created through Pollar.

npm i nirium-pollar-adapter

API keys

Some nodes (like Payouts) need a free API key. Get it in a minute.

Get your free API key

Prefer code? Pick an issue

How to claim an issue: comment with a plan for that specific issue, the files you will touch and how you will test it. A bare “I'll take it” or a generic template does not count. The first valid plan gets it, one active issue per person. If there is no draft PR within 48 hours of assignment, the issue goes back to the pool. A merged PR earns Contributor.

  1. Halloween edition: a short, original horror story about an AI agent, a payment or a Stellar transaction that goes wrong. The key that signed at midnight, the receipt that was never anchored, the facilitator that answered 402 forever. Add community/horror-stories/<your-github-handle>.md. English or Spanish.

    Done when: One file, 100 to 300 words, your name or handle at the end. Fictional characters only, never a real person or project.

  2. Add community/ascii/<your-github-handle>-<name>.txt with one piece: a jack-o'-lantern, the Nirium mark, a ghost, a bat, a haunted node. Plain ASCII characters only.

    Done when: One file, at most 80 columns and 40 lines, and the PR pastes what cat prints in a terminal.

  3. It is the shortest README under examples/. Add examples/go-x402/README.es.md and a one-line link to it at the top of the English README.

    Done when: Commands, code blocks and header names like PAYMENT-SIGNATURE are unchanged, and nothing is added that the English text does not say.

  4. anchor_audit_record() exists in the Python package, but examples/ has no Python example for Audit Trail. Add examples/python-audit-anchor: hash a file, anchor it on testnet, fetch the CID back and check the hash.

    Done when: README with exact commands, and the PR shows a real testnet CID produced by running it.

  5. packages/sdk-python/tests/ only covers the LangChain tool and the WebSocket client. Add tests for anchor_audit_record(): payload shape, hash vs record, and the error when neither is given. Mock HTTP, no network.

    Done when: pytest passes locally and the PR pastes the output.

  6. The verification model is only written up in the GitHub Action's README. Add docs/verify-audit-cid.md: fetch the document, recompute sha-256 over record, rebuild nirium-audit-v1:<sha256> and check the ed25519 signature against agent.key.

    Done when: Every step is a copy-paste command, and it is checked against a real testnet CID cited in the doc.

  7. There is no Spanish file in the repo. Translate docs/quickstart-x402.md to docs/es/quickstart-x402.md and link both ways.

    Done when: Commands and code blocks are unchanged, and you ran the quickstart on testnet while translating it (hash in the PR).

  8. Add packages/sdk-python/README.es.md with a link at the top of the English README. Keep the known limits it states (for example, MPP Charge in Python) exactly as written.

    Done when: Same sections as the English README, nothing added that the English one does not say.

  9. examples/express-x402 wires @x402/express by hand; only the Vercel example uses x402Serve(). Add a minimal Express server that charges for one route with x402Serve() on stellar:testnet.

    Done when: A paid request settles on testnet and the PR includes the settlement tx hash.

  10. The Python README says init_mpp()/mpp_fetch() cannot pay an MPP Charge server today. Fix it for testnet only, matching what the TypeScript client already does.

    Done when: A real payment to the hosted testnet /api/v1/mpp/signals with its tx hash, plus a test. The README note is updated in the same PR.

  11. No example covers Payouts. Add one that builds a two-recipient run on testnet with acknowledgeTerms, signs it with a throwaway testnet key and submits it.

    Done when: Testnet tx hash in the PR. The example never asks for a mainnet key.

  12. get_reporting_summary() and get_reporting_export() have no example. Add a short script that prints the testnet summary and saves the export to a file.

    Done when: Runs against testnet; the PR pastes the command and the first lines of output.

  13. examples/ has twelve folders and no index. Add examples/README.md with one line per example: what it shows, language, and network.

    Done when: Every folder is listed and every link resolves.

  14. The pre-sign policy hook decides one payment at a time. Write a design note on spending caps per time window, per destination and per asset, built on top of it. Related: #127.

    Done when: docs/research/aggregate-spending-caps.md with at least 3 designs compared, a policy in pseudocode and the edge cases: retries, concurrent payments, a restart mid-window.

  15. Can one DeFindex vault on testnet hold USDC, XLM and CETES at once? Find out, with sources.

    Done when: docs/research/defindex-multi-asset-testnet.md with a table of testnet contract ids, each with a stellar.expert link or a read-only call, and a clear yes or no with what is missing.

  16. Compare an Audit Trail receipt (a signed hash on IPFS) with W3C Verifiable Credentials and C2PA.

    Done when: docs/research/audit-receipts-vs-vc-c2pa.md with a comparison table, one real testnet CID mapped field by field to a credential, and the gaps on each side.

  17. Port the TypeScript pre-sign policy hook to the Python package: ALLOW, DENY or WAIT, with contextHash and expiresAt. Anything but a valid ALLOW signs nothing.

    Done when: pytest passes for each verdict, a wrong contextHash and an expired expiresAt, plus a testnet tx hash of a payment allowed by the policy.

  18. The Action fetches from one IPFS gateway, and today its default answers 429. Try several gateways in order and report which one answered. Related: #135.

    Done when: Tests for a downed first gateway and for a real testnet CID pass, and dist/index.js is rebuilt.

FAQ

Which parts of Nirium count, and on which network?
  • x402 MarketGET /api/v1/premium/market
    Testnet · 2Mainnet · +3

    0.05 USDC per call, paid from your account

  • Audit TrailPOST /api/audit/log
    Testnet · 2Mainnet · +3

    Free during beta. Counts when the anchor carries agent signed with your key

  • ReportingGET /api/reporting/summary
    Testnet · 0Mainnet · 0

    Live on mainnet, but read-only: it returns Nirium's own totals and leaves no record tied to your key, so it adds no points alone

  • MPP ChargeGET /api/v1/mpp/signals
    Testnet · 2Testnet only

    Verified on testnet. Never tested on mainnet

  • PayoutsPOST /api/payroll/run
    Testnet · 2Testnet only

    Testnet only for Niriumtober

  • Treasury RebalancePOST /api/treasury/rebalance/propose
    Testnet · 2Testnet only

    Testnet only for Niriumtober

Testnet points (2) are earned once, whatever nodes you use. Mainnet points are per node.

How do points work?
Accepted PR from the list (technical or fun)1
Any node on testnet, from your own project2
Audit Trail or x402 Market on mainnet, with your key+3 per node
Mainnet use on 2 or more different days (UTC)+2

Points only set the order of the perks. There is no public leaderboard. Champion is awarded apart.

What do I send as proof?
Project
name and one line on what it does
Repo
public URL where the integration lives. Optional for Builder, required for Mainnet Builder and Champion
Nodes used
Audit Trail, x402 Market, Payouts…
Network
testnet / mainnet
CID(s) or tx hash(es)
one per line
Public key
the G... address that signed or paid

Everything in the form is public, so never paste a secret key.

How do I claim an issue?

How to claim an issue: comment with a plan for that specific issue, the files you will touch and how you will test it. A bare “I'll take it” or a generic template does not count. The first valid plan gets it, one active issue per person. If there is no draft PR within 48 hours of assignment, the issue goes back to the pool. A merged PR earns Contributor.

Rules
  • We never give you funds or refund anything for mainnet transactions. Mainnet use is with your own funds; the only thing we pay for is the badges.
  • Team keys don't count: keys held by the Nirium team, our self-test accounts, or any account Nirium has funded.
  • Nirium is non-custodial software and never touches your funds. Mainnet is optional and at your own risk.
Can I use AI?

AI is welcome, unreviewed AI is not. Use any tool you like, but your PR must show you understood and ran it:

  • Say what you used AI for in the PR description.
  • Include how you tested it (command + output, or a testnet tx hash / Audit Trail CID).
  • Keep the diff to what the issue asks. Unrelated rewrites are closed.
  • PRs that look like unedited generic output are closed without review.

For the fun issues, testing means showing the result: the file renders, the story reads well, the translation matches. No hash or CID needed.

How do I verify a badge?

Each badge is a receipt Nirium signs and anchors in Audit Trail on mainnet, at our cost. It cites your evidence. Badge anchors are ours: we never count them as user activity.

event"niriumtober-2026"
badge"contributor" | "builder" | "mainnet-builder" | "champion"
github"@handle"
projectrepo URL
nodes["audit", "x402-market"]
network"testnet" | "mainnet"
evidenceyour CIDs, tx hashes or PR URL
participant_keyyour G... address
issued_atISO-8601
  1. Fetch the badge CID from any IPFS gateway.
  2. Recompute sha-256 over record and compare it with content_sha256.
  3. Rebuild nirium-audit-v1:<sha256> and check the ed25519 signature against agent.key, which must be the issuer key below.
  4. Open the participant's evidence the receipt cites: their CID's agent.key, or their tx on Horizon.
  5. Champion is checked the same way: same issuer key, tag niriumtober-2026, and badge: "champion" in the record.

Niriumtober issuer key: GBPDN4LQFQ4YJMP3Y43ZQ5PABLAMRID6IF52PGYILLHECC2ZDKH2NNY5. Steps 1-3 are what the verify-audit-cid GitHub Action already does.

verify-audit-cid
Dates
Oct 22 to Nov 2, 2026
Halloween week + 2 bonus days