Skip to content

Repository files navigation

Tanda: Savings circles on Nimiq

Tanda coordinates a fixed rotating savings circle without holding its money.

JavaScript Vite Nimiq Tests License: MIT

Tanda home screen

Live demo

Open Tanda

Open the normal URL for the browser preview, then choose Use the Nimiq web wallet to enter the real TestAlbatross wallet flow. Nimiq Pay continues to use the native Mini App provider.

What is Tanda?

A rotating savings circle gives each member one turn to receive the group’s contributions. Tanda records the circle name, contribution amount, and fixed turn order in its invitation link. Members sign those terms in Nimiq Pay or the Nimiq web wallet.

Each contribution goes from one member’s wallet to the current recipient. Tanda does not have a platform wallet, escrow account, backend, or database. It rebuilds the pot from memo-tagged Nimiq transaction history.

Screenshots

Create the order Review the terms Follow the pot
Create a circle Review circle terms Pot progress interface preview

The pot image uses representative confirmation data to show the interface. The running app only labels payments confirmed after finding included transactions in Nimiq chain history.

Features

  • Join by link: The invitation carries the circle terms and fixed member order.
  • Signed membership: Joining calls Nimiq Pay's native sign() flow or the Nimiq Hub signMessage() flow in explicit browser-test mode.
  • Verifiable membership: Members publish their acceptance in a transaction bound to a canonical fingerprint of the circle name, amount, and fixed order. Nimiq Pay uses a zero-value transaction; the browser-wallet testnet path uses a disclosed one-Luna self-transfer because Hub checkout requires a positive value. Every member can check who agreed without trusting the app to report it.
  • Visible payment register: The active round names the recipient and marks every other member as paid or waiting from confirmed chain history.
  • Direct payments: Contributions use sendBasicTransactionWithData.
  • No self-payments: The member receiving a round does not pay into their own pot. They receive from the other members, and the round completes without a pointless transaction to themselves.
  • Real browser testnet: ?wallet=hub-testnet routes approvals through the Nimiq web wallet and reads the TestAlbatross chain. It never requests mainnet funds.
  • Four languages: English, Spanish, Portuguese and German. Nimiq Pay selects its host language; standalone browser mode defaults to English.
  • Chain-derived pot: Confirmed transaction history is the source of truth.
  • No custody: Funds move from a member to the round’s recipient.
  • No database: Clearing local app data does not erase circle payment history.
  • Fixed rotation: The order is frozen when the invitation is created.
  • Accessible mobile UI: Touch targets, focus states, errors, loading labels, and reduced-motion support are built in.

Tech stack

Layer Technology
Wallet interfaces Nimiq Pay Mini Apps SDK, Nimiq Hub API
Chain client @nimiq/core
Frontend JavaScript, HTML, CSS
Build tool Vite 8
Tests Node test runner
Persistence Nimiq transaction history
License MIT

Nimiq integration

Tanda’s NIM path depends on the wallet and chain APIs below.

API Use
listAccounts() Select the member's Nimiq Pay account
sign(message) Accept the fixed terms inside Nimiq Pay
Hub signMessage() Accept the fixed terms in the web wallet
Hub checkout() Publish or pay a TestAlbatross transaction
isConsensusEstablished() Block payment while the wallet is syncing
getBlockNumber() Set the transaction validity start height
sendBasicTransactionWithData() Send the contribution and its circle memo
getTransactionsByAddress() Rebuild confirmed circle state

Tanda does not deploy a smart contract. Nimiq’s native transaction data field is enough for the Cycle I scope: fixed-order NIM circles with direct payments.

Run locally

Requirements:

  • Node.js 22 or newer
  • npm
  • Nimiq Pay for native Mini App testing, or a Nimiq testnet web wallet for browser testing

Install and start the development server:

npm ci
npm run dev

Open the printed local URL in a desktop browser. The normal URL is a preview and offers a clearly labelled entry into the web-wallet testnet flow. Native Mini App actions still run inside Nimiq Pay.

Build the production bundle:

npm run build
npm run preview

Vite writes the static output to dist/. Any static host can serve that directory.

Test with the Nimiq web wallet

This is a real TestAlbatross flow, not a simulated provider.

  1. Start Tanda and open the printed URL with ?wallet=hub-testnet appended.
  2. Create or import two testnet accounts in the Nimiq web wallet and fund them with testnet NIM. Never enter a mainnet recovery phrase for this test.
  3. Create a two-member circle using those exact TestAlbatross addresses. Put the intended payer second so the first account receives round one.
  4. Open the generated invitation and choose Sign with Nimiq Wallet using the payer's listed account.
  5. Optionally choose Publish acceptance (0.00001 NIM). Nimiq Hub cannot publish a zero-value checkout, so this is disclosed as a one-Luna self-transfer carrying the circle fingerprint.
  6. Choose Pay and verify the testnet recipient and amount in Nimiq Wallet before approving.
  7. Return to Tanda and use Check confirmations until the register reflects the included transaction.

The query parameter is preserved in invitation links created in this mode. If Tanda detects the Nimiq Pay host, it ignores the browser-wallet parameter and uses the native Mini App provider.

Test inside Nimiq Pay

  1. Run or deploy Tanda over HTTPS.
  2. Open nimiqpay://miniapp?url=<encoded-app-url> on the phone.
  3. Create a circle with two or more member addresses.
  4. Share the invitation link with another member.
  5. Open the invitation inside Nimiq Pay.
  6. Tap Sign and join and review the native signing request.
  7. Tap Pay N NIM and review the recipient, value, and network fee.
  8. Approve the transaction.
  9. Wait for a chain confirmation, then tap Check confirmations.

Every payment is user-approved. Tanda cannot transact in the background. Use low-value accounts when testing a live network.

Tests

Run all 89 tests:

npm test

Run the sprint verification gates:

./verify.sh phase-r   # hardening
./verify.sh phase-c   # on-chain membership, shareable links
./verify.sh phase-7   # locales
./verify.sh phase-8
./verify.sh phase-10
./verify.sh global

The Phase 10 live URL check now runs against the production deployment. The full submission gate remains red until its video URL and contact email are provided. Real-phone timing, native approval, and chain-rebuild checks are manual.

How it works

Circle creator
  |
  v
Invitation URL: name + amount + fixed member order
  |
  v
Member opens Tanda in Nimiq Pay or explicit Hub testnet mode
  |
  +-- sign(circle terms) / Hub signMessage(circle terms)
  |
  +-- sendBasicTransactionWithData(
        recipient,
        amount,
        "T1:C:<circle-id>:<round>"
      )
  |
  v
Nimiq transaction history
  |
  v
Pure derivation engine
  |
  v
Current round + recipient + confirmed pot

Only included or confirmed transactions count. A contribution must have the expected memo, sender, recipient, amount, and round.

Project structure

src/
  app/          invitation, terms, pot model, journey controller
  engine/       memo codec, immutable rotation, state derivation
  locales/      all visible copy, in en/es/pt/de
  providers/    Nimiq Pay and chain-history boundaries
  ui/           screen templates
tests/          unit and journey tests
brand/          selected mark and art direction
docs/images/    README screenshots
submission/     competition metadata and image assets
screenshots/    local interface preview fixtures

The engine has no import path to the providers. Tests can prove the state model without a wallet or network.

Privacy and security

Tanda has no analytics, server, database, or key storage. Wallet keys remain in Nimiq Pay or Nimiq Wallet. Circle details in an invitation are visible to anyone who receives the link, and payment history is public on the selected Nimiq network.

The current Cycle I build supports NIM circles in English, Spanish, Portuguese and German. USDT circles, staking-backed bonds, and additional locales are deferred.

License

Tanda is available under the MIT License.

About

Nimiq savings circles: fixed rotations, direct payments, and chain-derived progress without custody

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages