Business integration lab · fictional data

NFT / ICO / Token Offering

A disclosure-to-allocation worksheet separating publication, eligibility, payment, allocation and delivery, plus an explicit unresolved-delivery case.

Reviewed 2026-09-28 · Hybrid-Chain platform team · Work at your own pace

What you will build.

An issuer plans fictional allocation DEMO-OFFER-01: 100 units remain and a purchaser requests 20. Test an ineligible purchaser, an allocation beyond supply and a paid purchase that has not been delivered. Nothing in this exercise constitutes an offering or investment recommendation.

Have these ready — preparation checklist

Tick each item once you have verified it. These ticks are not saved to your account.

Your working record

Create a private worksheet with columns for the source reference, observed state, responsible system, observation time, expected result and unresolved issue. Use the same fictional case throughout the steps; do not paste live personal or financial records into this exercise.

  1. 01Define the entitlement before the token
  2. 02Test purchaser and supply gates
  3. 03Separate payment from delivery
  4. 04Retain the disclosure trail

Run the example before changing it.

Inspect the baseline record below. Download and read the complete JavaScript file before running it. It uses only Node’s built-in test and assertion modules; there is no package installation, account connection or secret to configure.

Fictional baseline record—not an API response
{
  "eligible": true,
  "requested": 20,
  "remaining": 100,
  "paid": true,
  "delivered": true
}

Save it as nft-ico-token-offering.mjs. Open a terminal in that folder and run:

Run with Node.js 22 or later
node --version
node --test nft-ico-token-offering.mjs

Expected result: four passing tests and zero failures. These tests verify the teaching classifier only. They do not verify a production integration, security boundary or financial outcome.

File or test runner will not start?

Check that Node.js 22 or later is installed, the filename ends in .mjs rather than .mjs.txt, and your terminal is in the download folder. If a managed browser blocks scripts, open “Read the full exercise” and save that text locally under the same filename. Do not disable organizational security controls.

Read the full exercise
Complete offline JavaScript exercise
// Hybrid-Chain offline teaching model: nft-ico-token-offering
// Fictional fields/states; NOT an API client, authorization system or production implementation.
// No network calls, credentials, payments or file writes. Review before running.
// Requires Node.js 22+. Run: node --test nft-ico-token-offering.mjs
import test from 'node:test';
import assert from 'node:assert/strict';

export function inspect(record) {
  if (!record.eligible) return 'PURCHASER_REVIEW_REQUIRED';
  if (record.requested > record.remaining) return 'ALLOCATION_EXCEEDS_SUPPLY';
  if (record.paid && !record.delivered) return 'PAID_DELIVERY_UNRESOLVED';
  return 'ALLOCATION_READY_FOR_REVIEW';
}

const baseline = {
  "eligible": true,
  "requested": 20,
  "remaining": 100,
  "paid": true,
  "delivered": true
};
const cases = [
  {
    "name": "reviewable allocation",
    "patch": {},
    "expected": "ALLOCATION_READY_FOR_REVIEW"
  },
  {
    "name": "purchaser unresolved",
    "patch": {
      "eligible": false
    },
    "expected": "PURCHASER_REVIEW_REQUIRED"
  },
  {
    "name": "excess allocation",
    "patch": {
      "requested": 101
    },
    "expected": "ALLOCATION_EXCEEDS_SUPPLY"
  },
  {
    "name": "paid but undelivered",
    "patch": {
      "delivered": false
    },
    "expected": "PAID_DELIVERY_UNRESOLVED"
  }
];

for (const example of cases) {
  test(example.name, () => {
    assert.equal(inspect({...baseline, ...example.patch}), example.expected);
  });
}

Know what the tests demonstrate

reviewable allocation
ALLOCATION_READY_FOR_REVIEW
purchaser unresolved
PURCHASER_REVIEW_REQUIRED
excess allocation
ALLOCATION_EXCEEDS_SUPPLY
paid but undelivered
PAID_DELIVERY_UNRESOLVED

Now change one fixture at a time. If you change a case’s input without changing its expected result, the test should fail. Read the actual-versus-expected difference and use the walkthrough to decide whether your rule or your expectation needs correcting. Keep an unchanged copy for comparison.

Work through the case, step by step.

  1. 01

    Define the entitlement before the token

    Do this

    1. Write DEMO-OFFER-01 and explain what a purchaser is intended to receive.
    2. Record the approved disclosure version, issuer and transfer conditions.
    3. Separate permission to publish information from permission to distribute the entitlement.
    Expected result

    The allocation model has a defined subject and does not imply that a published listing authorizes an offering.

    If your result is different

    If the entitlement or required offering approvals are unresolved, stop before designing a real purchase flow.

  2. 02

    Test purchaser and supply gates

    Do this

    1. Run the baseline with eligible=true, requested=20 and remaining=100.
    2. Set eligible=false, then test requested=101 in a separate case.
    3. Confirm PURCHASER_REVIEW_REQUIRED and ALLOCATION_EXCEEDS_SUPPLY respectively.
    Expected result

    The worksheet names two different reasons an allocation cannot proceed rather than reporting a generic checkout failure.

    If your result is different

    The numeric comparison is not a reservation engine. Production concurrent allocation requires an atomic supply-control mechanism.

  3. 03

    Separate payment from delivery

    Do this

    1. Set paid=true and delivered=false; expect PAID_DELIVERY_UNRESOLVED.
    2. Add separate provider-payment and asset-delivery references to the worksheet.
    3. Assign the unresolved delivery to an owner and define customer support/refund escalation outside the exercise.
    Expected result

    The customer record can show money received without pretending the entitlement has been delivered.

    If your result is different

    Do not retry payment to resolve failed delivery. Reconcile the existing payment first.

  4. 04

    Retain the disclosure trail

    Do this

    1. Keep the disclosure reference used for the allocation, even if a newer version is published.
    2. Save the test cases and list additional checks for refunds, supply changes and transfer restrictions.
    3. Use the governance walkthrough to map which reviewed version a decision actually concerns.
    Expected result

    You finish with a reviewable distribution design, not proof of investment quality, offering permission or exchange admission.

    If your result is different

    Any proposed external exchange listing remains a separate process; it is not a consequence of passing these local tests.

Review what you produced.

Your acceptance checklist

Tick each item once you have verified it. These ticks are not saved to your account.

Save the worksheet, unmodified test output, one deliberately failing case and the explanation of its fix. A useful result includes an unresolved item with an owner; it is not just a screenshot of four green tests.

Map the model to actual systems.

The issuer owns commercial terms, legal classification, purchaser eligibility, disclosure accuracy, allocation, and unresolved delivery or refund handling.

For each worksheet field, name the owning system, exact current operation, permission and error behavior. Put “not available” next to any missing operation and assign a dependency owner. Do not substitute the teaching classifier for that missing integration.

Open the current API reference and inspect each operation’s request, response, scope and implementation status. Code examples on this page are local models only; they do not call those operations.

Before a real deployment, the responsible organization must obtain appropriate legal, compliance and security review. The tutorial does not determine licensing, eligibility, entitlement enforceability or financial suitability.

Take the next technical step.

Use your worksheet and failing-case notes in the next walkthrough. Keep the same reference trail so you can see which assumptions become actual observations—and which remain dependencies.

Review the approved disclosure decision

Need help with access or an unavailable integration? Contact the team with a redacted error and the guide step. Never send credentials or private records.