For the complete documentation index, see llms.txt. This page is also available as Markdown.

Subscription

Time-based subscription token with recurring payment approvals and auto-deletion on expiry

Category: Token Types

Summary

Required standards: ["Subscriptions"]

  • validTokenIds: MUST be exactly one token ID [{ "start": "1", "end": "1" }]

  • Subscription faucet approval requirements:

    • fromListId: "Mint"

    • overridesFromOutgoingApprovals: true

    • coinTransfers: at least 1 entry, both override flags false

    • predeterminedBalances.incrementedBalances.durationFromTimestamp: MUST be non-zero (duration in ms)

    • allowOverrideTimestamp: MUST be true

    • incrementTokenIdsBy: "0", incrementOwnershipTimesBy: "0"

    • orderCalculationMethod: MUST have exactly ONE method true (default: useOverallNumTransfers)

  • Duration constants: monthly = "2592000000", annual = "31536000000", daily = "86400000"

  • CRITICAL: recurringOwnershipTimes MUST be all-zeros { startTime: "0", intervalLength: "0", chargePeriodLength: "0" } β€” chain enforces mutual exclusivity with durationFromTimestamp

Instructions

Subscription Collection Configuration

When creating a subscription collection, you MUST follow these EXACT requirements:

Required Structure

  1. Standards: MUST include "Subscriptions"

    • "standards": ["Subscriptions"]

  2. Invariants: MUST set noCustomOwnershipTimes to FALSE

    • Subscriptions use time-dependent ownership β€” this invariant MUST be false or subscriptions cannot function.

    • "invariants": { "noCustomOwnershipTimes": false, ... }

  3. validTokenIds: MUST be exactly one token ID (per tier)

    • "validTokenIds": [{ "start": "1", "end": "1" }]

  4. Subscription Faucet Approval Requirements:

    • fromListId: MUST be "Mint"

    • tokenIds: MUST be exactly 1 token: [{ "start": "1", "end": "1" }]

    • coinTransfers: MUST have at least 1 entry, NO override flags (both false)

    • predeterminedBalances.incrementedBalances:

      • durationFromTimestamp: MUST be non-zero (subscription duration in milliseconds)

      • allowOverrideTimestamp: MUST be true

      • incrementTokenIdsBy: "0"

      • incrementOwnershipTimesBy: "0"

    • orderCalculationMethod: MUST have EXACTLY ONE method set to true (default: useOverallNumTransfers)

    • overridesFromOutgoingApprovals: true (required for Mint approvals)

Duration Constants (in milliseconds)

  • Monthly: "2592000000" (30 days)

  • Annual: "31536000000" (365 days)

  • Daily: "86400000" (24 hours)

Complete Example

Subscription-Specific Gotchas

  • MUST have exactly 1 token ID (not multiple)

  • coinTransfers override flags MUST be false (not true)

  • durationFromTimestamp MUST be non-zero

  • allowOverrideTimestamp MUST be true

  • CRITICAL MUTUAL EXCLUSIVITY: The chain enforces that ONLY ONE of durationFromTimestamp, incrementOwnershipTimesBy, or recurringOwnershipTimes can be non-zero. For subscriptions, use durationFromTimestamp and keep recurringOwnershipTimes as ALL ZEROS: { "startTime": "0", "intervalLength": "0", "chargePeriodLength": "0" }. DO NOT set non-zero values in recurringOwnershipTimes β€” the template already has the correct structure.

Common Mistakes

  • DON'T set recurringOwnershipTimes to non-zero values β€” it is mutually exclusive with durationFromTimestamp. Keep all fields as "0".

  • DON'T forget durationFromTimestamp must be non-zero β€” this is the subscription duration in milliseconds (e.g. "2592000000" for 30 days).

  • DON'T forget allowOverrideTimestamp: true β€” subscriptions need this so each mint gets its own start timestamp.

  • DON'T use multiple token IDs β€” subscriptions must use exactly one token ID [{ "start": "1", "end": "1" }].

  • DON'T set coinTransfers override flags to true β€” for standard subscription payments, both overrideFromWithApproverAddress and overrideToWithInitiator must be false.

  • DON'T set noCustomOwnershipTimes: true in invariants β€” subscriptions require noCustomOwnershipTimes: false (or omit the invariant) because each subscription period mints a new ownershipTime window.

Last updated