Rewards & Affiliation
Invite Links

Invite Links

An invite link is a one-time secret key wrapped in a URL, backed by AE you have locked in the AffiliationTreasury contract. Whoever opens the link claims the AE and becomes your level-1 invitee, which is how you start earning from the affiliation system.

Invite links contain one-time secrets.

The link is not an identifier. It carries the secret key of a funded account, in the URL fragment. Anyone who reads the link can claim the AE. No wallet of yours is needed and no confirmation is asked of you.

  • Never paste an invite link into a shared channel, a group chat, an issue tracker or a support ticket. Send it to one person, directly.
  • Never commit one to a repository, and never write one into a log file, a shell history, an error report or a screenshot.
  • The app never persists the secret. Generated links are held in memory and cleared on reload. If you close the dialog without copying, the secret is gone. The AE stays locked on-chain and the only way to get it back is to revoke the code.
  • Treat a leaked link as spent. If one escapes, revoke it immediately.

What a link looks like

https://superhero.com/#invite_code=<secret key of the one-time account>

The app builds it from the current origin plus the invite_code fragment parameter. When someone lands on any page with that fragment, the app reads the code, strips the fragment and redirects them to the home feed, where the claim card appears.

The agent-skill CLI builds the same shape against the canonical host:

https://superhero.com#invite_code=<secret key>

Create links in the app

  1. Open https://superhero.com/trends/invite (opens in a new tab) and connect your wallet.
  2. Find the Generate Invites card.
  3. Enter Amount per invite (AE) (the AE the recipient will claim) and Number of invites.
  4. Press Generate invite links and confirm the transaction. All the links in one batch are registered in a single register_invitation_code call.
  5. A dialog opens with the links. Copy them now. The dialog will not close until you tick "I have copied the invitation links". Escape, clicking outside and the close button are all blocked.

What it costs

Each link locks the gift plus a small fee cover:

per link   = invitation_amount + redemption_fee_cover
total call = (invitation_amount + redemption_fee_cover) × count
paid       = total call, attached to register_invitation_code
plus       = the æternity transaction fee for the call itself

redemption_fee_cover is 0.001 AE (10n ** 15n aettos) in both the web app and the CLI, and that is also the contract's minimum: register_invitation_code aborts with MINIMUM_REDEMPTION_AND_FEE_NOT_MEET below 10 ^ 15 aettos. It funds the one-time account so the recipient can pay for their own redemption transaction, which is signed by the invite's key rather than the recipient's wallet. See redemption_fee_cover on the affiliation page.

Ten links of 1 AE each cost 10.01 AE plus gas.

  • The contract checks Call.value == (redemption_fee_cover + invitation_amount) × count with exact equality. Attaching more aborts with INVITATION_AMOUNT_AND_FEE_NOT_MATCHING.
  • Fund your wallet for (amount + 0.001) × count plus the transaction fee. The app's form checks your balance against amount × count only.

Claiming: the recipient's side

The recipient opens the link and sees a card showing the gift amount and your address. They connect a wallet and press Claim reward. The call is redeem_invitation_code(<their wallet address>), signed by the invite's one-time key.

Once it lands, they hold the AE and are attached to you in the affiliation tree: everything they subsequently spend on community tokens pays you 0.300% at level 1, and your own inviter 0.125% at level 2.

An address can only be invited once; a second attempt fails with INVITEE_ALREADY_REGISTERED. A link that has already been claimed fails with ALREADY_REDEEMED; the card reads the claimed flag from get_invitation_code and shows that state before the button is pressed.

Revoke a link

Revoke any link that leaked, or any that nobody claimed and you want the AE back.

  • From your invitation list: each row with status created has a Revoke button.
  • By opening your own link: if the connected wallet is the inviter, the claim card switches to Revoke invitation.
  • From the CLI: node scripts/superhero-invite.mjs revoke <invite_address>.

All three call revoke_invitation_code(invitation_address) with your wallet. The address is the public address of the one-time account, not the secret. It is safe to handle and it is what the invitation list shows you.

Revoking returns the invitation_amount to your wallet; the 0.001 AE fee cover was sent to the one-time address at registration and is not part of the refund. Revoking ten unclaimed 1 AE links returns 10 AE, and costs a transaction fee.

There is no expiry. An invitation_codes entry is the tuple (inviter, invitation_amount, is_redeemed). It carries no timestamp, and no entrypoint prunes the map. An unclaimed link stays claimable indefinitely, which is why revoking a leaked one matters.

Three errors you can hit: INVITATION_NOT_REGISTERED if the code was already revoked or never existed (the app uses this to drop a stale local entry), ALREADY_REDEEMED if somebody claimed it first (the app refreshes so the row flips to claimed), and CALLER_NOT_INVITER if the connected wallet is not the address that registered the code.

Track your invitations

The Your Invitations list shows every code you registered, with one of three statuses:

StatusMeaning
createdRegistered on-chain, nobody has claimed it. Revocable. Shows the copyable link if the secret is still in this browser session.
claimedRedeemed. Shows the claimer's address and the claim time.
revokedCancelled. Shows when.

The list is assembled from two sources:

  • Middleware transaction history: the app pages through the middleware's /v3/transactions endpoint, filtered to the invitations contract and to your address as the caller, and keeps the calls whose function name is register_invitation_code or revoke_invitation_code:

    <middleware>/v3/transactions?contract=ct_2GG42rs2FDPTXuUCWHMn98bu5Ab6mgNxY7KdGAKUNsrLqutNxZ&caller_id=<your address>

    This is the part of the list that survives a page reload. The contract address is the mainnet treasury; the testnet treasury is ct_2QmAcPxY4TBbFmkSUhxU4UTwoRot8SMmZzaAKL6oyHmQqRL1rK. On testnet, use the API below or a middleware query against the testnet address.

  • Superhero's API: GET /api/invitations with an inviter filter, paginated, which returns claim status per invitation. The response fields are receiver_address (the one-time invite address), claimed, claimer_address, claimed_at and claim_tx_hash. It accepts order_by of amount or created_at, order_direction of ASC or DESC, plus limit and page.

    limit is validated to 1–100 and defaults to 100; page must be 1 or more; any other order_by or order_direction is a 400. The backend indexes the treasury per network, so this endpoint works on testnet as well as mainnet. The underlying row carries status as one of pending, claimed or revoked, plus tx_hash, block_height, amount, sender_address, invitee_address, revoke_tx_hash and status_updated_at.

Because the secret keys are never persisted, links you generated in an earlier session appear in the list with their status and amount but without a copyable link. The AE is still recoverable by revoking.

From the command line

The agent skill ships scripts/superhero-invite.mjs, which talks to the same contract. It requires AE_PRIVATE_KEY in the environment and runs against https://mainnet.aeternity.io. Run it from the skill's root directory, because it reads ./contracts/CommunityFactory.aci.json by relative path.

# Print usage and the cost formula
node scripts/superhero-invite.mjs help
 
# Five links, 1 AE each — total ~5.005 AE plus gas
node scripts/superhero-invite.mjs generate 1 5
 
# A single 0.5 AE link
node scripts/superhero-invite.mjs generate 0.5
 
# Reclaim an unclaimed link
node scripts/superhero-invite.mjs revoke ak_...

generate prints a JSON object on stdout with count, amount_ae_per_invite, total_cost_ae, tx_hash and a links array. Progress messages go to stderr, so the stdout payload stays parseable.

The links array is the secret material. Do not pipe it into a log, a CI artefact, a chat webhook, or anything an agent will later summarise into a shared transcript. Redirect stdout to a file with restrictive permissions, or read the links and clear the output.

Turn invites into withdrawable rewards

The affiliate balance becomes withdrawable once 4 of your direct invitees have each spent at least 10 AE in token sales, cumulatively. Only direct invitees count: someone your invitee invites earns you 0.125% at level 2 but does nothing for your qualification, so a wide first ring gets you paid sooner than a deep chain.

Rewards accumulate in 30-day periods and withdraw() pays the current and previous period, so withdraw monthly once you qualify. The Collect Rewards card tracks the gate and the live get_accumulated_rewards balance. See Claiming Rewards and The Affiliation System.

Related