Metadata: Terms & Restricted Countries

Besides its immutable sale parameters, every bench has an editable metadata string, stored in the bench's registry directory entry (up to 1014 bytes). Myth Bench uses it as a JSON object with the following optional keys:

KeyTypeDescription
tcstring (URL)Terms & Conditions link
bcstring[]Restricted countries, as ISO 3166-1 alpha-2 codes (e.g. ["US", "KP"])
tr0, 1 or 2Terms enforcement: 0/absent = not enforced, 1 = simple, 2 = challenge-response. See Terms enforcement.

Example: {"tc":"https://example.com/token-sale-terms","bc":["US"],"tr":1}

The SDK validates metadata objects (validateMeta): only these three keys are accepted, bc must be a non-empty array of strings when present, tr must be 0, 1 or 2 when present, and the object may not be empty. The SDK exposes tr as termsRequired (tr >= 1) and termsChallenge (tr === 2) on the bench state.

Terms & Conditions

When set, the frontend shows a prominent "Make sure to read: Distribution Terms & Conditions" notice linking to the URL on the bench page.

Terms enforcement

Optionally, sellers can require buyers to open or accept the Terms & Conditions before the buy form is shown. Tick "Enforce T&C validation" when creating or managing a bench and pick a method:

MethodtrBehaviour
Simple / open tab1The buy form is replaced by a "Terms & Conditions" card. Clicking its button opens the T&C URL in a new tab and unblocks the bench.
Challenge-Response2The buyer is redirected to the T&C page, which must send them back with the answer to a challenge. Requires the T&C page to implement the handshake below.

Acceptance is remembered in the buyer's browser (localStorage), per bench and per T&C URL. Changing the URL re-blocks everyone.

Like country restrictions, terms enforcement is a myth.finance frontend feature only. It is not enforced by the smart contract.

Challenge-Response handshake

With tr: 2, the frontend redirects the buyer to the T&C URL with two query parameters appended (existing query parameters on the URL are preserved):

<tc URL>?callback=<bench page URL>&tcChallenge=<a>,<b>

a and b are random integers in the range 1 to 2^26 - 1. Their product is below 2^52, so plain JavaScript Number multiplication is exact.

Once the buyer has accepted the terms, the T&C page must redirect to the callback with the product of the two numbers:

<callback>?tcResponse=<a * b>

Rules:

  • tcResponse must be a plain decimal integer: digits only, no sign, decimal point or exponent, at most 20 digits. Anything else fails verification.
  • The callback is the bench page's origin and path with no query string. Do not add other parameters.
  • Only redirect to callback hosts you trust (e.g. app.myth.finance), as the callback is user-controlled input to your page.
  • If verification fails, the buyer sees an error and can retry with a fresh challenge.

Minimal implementation for the T&C page:

const q = new URLSearchParams(location.search);
const callback = q.get("callback");
const m = (q.get("tcChallenge") || "").match(/^(\d{1,20}),(\d{1,20})$/);

function accept() { // wire to the "Accept" button
  if (!callback || !m) return;
  const answer = BigInt(m[1]) * BigInt(m[2]);
  const url = new URL(callback);
  url.searchParams.set("tcResponse", answer.toString());
  location.assign(url.toString());
}

To test an implementation without creating a bench, use the challenge validator: it issues a challenge, sends you to your T&C page, and grades the response on return.

Restricted countries

When set, the frontend geolocates visitors by IP address (browser side) and shows a "Restricted Access" page instead of the bench to visitors from the listed countries.

Country restrictions are enforced by the myth.finance frontend only. They are not enforced by the smart contract: anyone can interact with a bench directly, and other frontends may not honour the list. Sellers remain responsible for the compliance of their sales.

Setting and updating metadata

Metadata is set at creation, and can be updated or removed at any time by the bench owner, from the "Manage" page or with the SDK (setMeta). Updates go through the registry (set_meta), which verifies that the caller is the bench's owner. Passing an empty string removes the metadata.

Metadata is not part of the bench contract's own state: it is read through the registry (get_meta, get_state_with_meta, log_bench_states_with_meta).