XChain Platform: Token Bridge
The Cross-Chain Bridge gives XCHAIN, the platform’s own fee token, a
shadow balance on every chain it runs on. This document describes the same mechanism opened up
to any issuer’s token: one supply on its origin chain, provably backed one for one in a
protocol-owned escrow, with shadow balances anyone can mint and redeem elsewhere. See
XBRIDGE for the wire action (versions 3, 4 and 5) and
Token Bridge for the issuer-facing explanation.
Who this is for
- Quote assets. A stablecoin issuer who issues on one chain and wants the same supply
spendable on the others, so every token on those chains can be listed against it locally with
no
COINPAYleg. - Project tokens. An issuer with a community on more than one chain who wants one supply and one price rather than three independent issuances that drift apart.
Principle
Nothing here is specific to XCHAIN except which chain is the origin. The origin chain is
wherever the token was issued (ISSUE, not necessarily BTC): its escrow lives there, lock
happens there, burn happens on a bridged copy, and a copy never bridges onward. Spoke-to-spoke
travel is two hops through the origin, so every token has exactly one escrow and the invariant
stays per token per destination chain, exactly as it does for XCHAIN.
No key can touch a bridged row. The escrow is the origin chain’s keyless role address
(ADDRESS.BRIDGE_<COIN>); the bridged copy on the destination is owned by that chain’s own
keyless bridge role address, not by any issuer key. An owner key could set lists, bind a
controller, or transfer the row, all of which milestone 1 keeps off the bridged copy entirely
(see What does not generalize). With a keyless owner, nobody can,
and the row’s own locks are belt and braces.
Naming: the bridged row lives under its origin chain’s root
The bare-name question decides whether this is usable at all: three options were weighed, and only one survives a squatter.
- Same bare name, required free on every destination. Fails the day one squatter registers the name on one chain for one issuance fee; a stablecoin’s expansion would be blockable by anyone.
- A mapping registry. Nothing on the wire says two tokens on two chains are one asset, the map is state somebody has to administer, and it confuses users.
- Origin-rooted namespace (adopted). A token native to BTC lands on DOGE and LTC as
BTC.<NAME>; a token native to DOGE lands on BTC asDOGE.<NAME>.
BTC, LTC and DOGE are reserved ticks on every chain, and the platform’s subasset parent
gate refuses any child whose parent does not exist or is owned by another address. The bridge
creates the root row itself the first time a token from that origin arrives: protocol-owned,
supply zero, every lock set. From that block a user ISSUE of <COIN>.anything on that chain
fails with the ordinary parent-owner refusal, and no new guard is needed for children. This is
the same origin-badge convention wrapped tokens use elsewhere: the name on the wire says where
the asset is native, there is no registry, and squatting cannot block anyone. Wallets and
explorers render the bare name with an origin badge (BTC.PEPECASH shows as “PEPECASH,
bridged from BTC”). The one bare-name exception is XCHAIN itself, reserved on every chain and
needing no root.
Two limits in milestone 1
Both are refused at lock time, so no transfer can strand:
- Dotted origin names. A subasset (
BTC.PEPE.CASH) would need an intermediate row the bridge does not yet create; a lock or opt-in of a dotted native tick is refused withinvalid: TICK (subassets are not bridgeable yet). A later milestone walks the prefix and creates the missing intermediate rows. - Length. A native tick that would not fit once rooted (origin prefix plus a dot) is refused
with
invalid: TICK (too long to bridge).
The bridged row on the destination
Created by the first settle leg for that tick on that chain, the way the XCHAIN row is created on first use:
- The root row (
<ORIGIN>), if absent: owned by this chain’s own bridge role address for that origin, uncapped supply, zero decimals, every lock set, mint permanently disabled. One per origin chain per destination chain, ever. - The child row (
<ORIGIN>.<NAME>): the same owner and locks, decimals taken from the signed transfer record, uncapped supply (nothing off the origin can ever mint it, and a copied cap would go stale the moment the origin’s ownMAX_SUPPLYchanges). Nothing else is copied from the origin: the bridged row starts with no description, no lists, no controller.
If the child row already exists, a later settle leg compares the signed decimals against it: equal applies normally; unequal with zero supply re-parameterizes the row (the same rule every token gets: decimals may move until supply exists); unequal with supply refuses the leg outright and logs it, rather than silently drifting two chains’ views of the same token’s precision.
Supply on a bridged row moves only by a settle-in (up) and a burn (down): a broadcast ISSUE of
a coin-rooted tick is refused by the ordinary parent-ownership gate, and a DESTROY of a bridged
row is refused in favor of the burn leg of XBRIDGE.
Issuer opt-in
Bridgeability is a property the token owner sets on the origin row, default off, through
ISSUE format 7:
BRIDGE_CHAINS: which destination chains a lock may target. Empty means unchanged, so a later format7can extend the list without restating it.MIN_DEPTH: a confirmation depth the federation must honour for this token’s locks, on top of the platform default; raise-only, never lower.LOCK_BRIDGE: freezes both fields forever, the holder’s assurance against the owner (and against a new owner after an ownership transfer, which inherits both fields).
A lock checks the origin row’s BRIDGE_CHAINS at its own block; a destination not on the list
is refused with invalid: TICK (not bridgeable to DEST_COIN). MIN_DEPTH is stamped onto the
pending transfer at lock time and never re-read later, so an issuer raising it afterward can
never make an already-accepted lock un-signable. Removing a chain from BRIDGE_CHAINS only
stops new locks; it never touches balances already bridged, and burns are always allowed, so an
issuer can close a door but never strand anyone on the other side of it.
What does not generalize
- Trust. Cross-Chain Bridge: Trust model applies unchanged, and matters more here: XCHAIN’s milestone-1 hub-trusted mint is a statement about the platform’s own token. A third-party issuer bridging real value should read that section before opting in. This spec arms nowhere before the checkpoint cross-check described there is built and armed on that network.
- Reorg finality. An applied mint is final and the origin escrow can drop on a reorg (see
Reorgs and finality). For a third-party token that is
the issuer’s own unbacked liability, not the platform’s;
MIN_DEPTHis the issuer’s own price for that risk, and the token’s page shows it. - Issuer policy across chains. Allow lists, block lists, controller bindings and sleep live
on the origin row and, in milestone 1, do not carry to a bridged copy at all. A regulated
issuer who needs a block on one chain to also hold on another cannot rely on this milestone.
Milestone 1 keeps the two states mutually exclusive rather than silently under-enforcing: a
token with any live list or controller binding cannot opt into bridging, and a bridged token
cannot set one. Sleep is chain-local by the same reasoning: sleeping the origin stops new
locks but never touches outstanding copies, which keep trading, and burns still release.
Behind
TOKEN_POLICY_INHERITANCE_ACTIVATIONthe list and sleep half of this exclusion lifts; see Policy inheritance below. Controller bindings never lift on their own (a controller names a local contract; nothing about it is portable to another chain).
Milestone ladder: plain, undotted tokens with no policy first; then activation on a proven network; then policy inheritance and generic (any-coin) lists; mainnet arming last, gated the same way XCHAIN’s own bridge is.
Policy inheritance
Once TOKEN_POLICY_INHERITANCE_ACTIVATION is active on a network, a token’s allow list, block
list and sleep state are no longer mutually exclusive with bridging: the issuer’s policy is
signed once on the origin row and inherited on every bridged copy, never re-issued per
chain. See the platform’s policy-propagation specification for the full mechanism; the
shape that matters to a reader of this page:
- One list, everywhere. The origin’s
ALLOW_LISTandBLOCK_LISTmembership is signed by thecross_chainquorum into apolicy_snapshotsrow (the same mirror channelbridge_transfersrides) and materialized on each destination as its own local lists, owned by that chain’s bridge role address so no user key can edit them (invalid: LIST_ACTION_INDEX (bridge-owned),LIST). Sleep carries the same way, as an injectedSLEEP. - A confirmed lag, not a live mirror. Between an origin-side edit and its effect on a copy:
the origin’s own confirmation depth, a signing round, the mirror, and an
effective_timemargin, the same discipline a bridge lock’s own finality already accepts. The copy enforces the previous policy for that window; nothing is retroactive.getappliedpolicy(tick)(indexer, open read) shows exactly what a given chain has applied and as of which origin block. - Detaching a list. When the origin issuer detaches its allow or block list (an
ISSUEformat5carrying0in that field), the next signed snapshot carries that list as null. From the destination’sBRIDGE_POLICY_DETACHactivation, read at the destination chain’s own block height (values on Flag-Day Values), each copy’s matching list is detached the same way, by an injectedISSUEformat5with0; below it, a null list leaves the copy’s list attached as before. A null list is never materialized as an empty list, which would deny every address. - A membership ceiling. A token whose
ALLOW_LISTorBLOCK_LISTexceedsXPOLICY_MAX_MEMBERScannot opt into bridging in the first place (invalid: TICK (policy list exceeds XPOLICY_MAX_MEMBERS),ISSUEformat7). For lists that travel by membership, every snapshot and every destination materialization carries the full membership, so this bounds both the mirror’s transport size and the write amplification on every chain holding a copy. A by-reference side is not counted againstXPOLICY_MAX_MEMBERS. - A shared list travels by reference. At or above
LIST_SHARE_PRODUCER_ACTIVATION, which the hubs read on the BTC snapshot plane, an allow or block list on a bridged token travels by reference when it is a shared list (a list shared with a format2SHARE) or a chain’s mirror of one.gettokenpolicyanswers that side as<HOME>:<root>(for example,DOGE:2701) and repeats the value asallow_list_reforblock_list_ref. The signed policy snapshot carries that reference as a JSON string in itsallow_listorblock_listin place of the members, andpolicy_hashcovers the reference instead of the membership. Editing the shared list therefore creates no new policy snapshot, because the list itself travels as cross-chain list versions. At or aboveLIST_SHARE_CONSUMER_ACTIVATION, read at the destination’s own block height, each chain binds its own mirror of the list, or the home list itself on the home chain, with one injectedISSUEformat5pointer and noLISTleg. A reference whose mirror does not exist yet waits with nothing applied. Below that gate, a snapshot carrying a reference waits without holding up any other token’s snapshots. A later full-copy snapshot creates a fresh list on the copy rather than editing a shared list. A local or union list keeps the full copy. - Any-coin list items. Because one list now has to be enforced identically on every chain a
token has a copy on, a
LISTof typeADDRESSaccepts an address of any coin the platform runs, not only the chain it was broadcast on; seeLIST. - Controller bindings are the one thing that still does not travel. A controller names a
local contract deployed on one chain (
utility.jsruns itsguardin that chain’s own VM); nothing about a snapshot can make that contract exist elsewhere. A controller-bound token cannot opt into bridging and a bridged token cannot bind one, under this activation or any later one, without a separate controller-portability build the platform does not carry today.
Cross-chain list versions
A list shared with a format 2 SHARE reaches every other chain as a
sequence of list_snapshots versions signed by the cross_chain quorum. There is at most one
version per network, home chain, home list index and seq. Version 1 (kind full) carries
every member; each later version (kind delta) carries only the members added and removed,
together with the resulting members_hash.
Each version carries a signed admission height for every consuming chain. A consuming chain
applies one list’s versions in seq order once its own block reaches that height, so every node
of that chain applies a version at the same block. A missing version below a later due one, a
version with no height for that chain, a failed quorum check, or a mirror whose members do not
match the signed members_hash halts the consuming indexer instead of committing the block;
skipping a version would fork. The hub’s ANCHOR archive carries every version, so a node
rebuilt from the archive applies the same sequence.
LIST_SHARE_PRODUCER_ACTIVATION is read by the hubs on the BTC snapshot plane and binds the
leader poll, follower validation and archive legs. LIST_SHARE_CONSUMER_ACTIVATION is read at
each consuming chain’s own block height and binds the apply pass.
Reads and surfaces
getbridgeinvariant (hub) takes an optional tick and, without one, returns the map keyed by
tick with XCHAIN always present. getpendingbridgetransfers and getbridgetransfer (indexer)
gain the tick, decimals, and effective confirmation depth fields the general case needs. The
explorer, SDK and wallet surfaces are the same ones XCHAIN’s own bridge uses, extended with a
tick dimension; see Token Bridge for the issuer- and
holder-facing view.
Copyright © 2025–2026 Dankest, LLC
Based on XChain Platform by Dankest, LLC – https://dankest.llc
Licensed under the GNU Affero General Public License v3.0 (AGPL-3.0-or-later) with a commercial license available for proprietary use.
You may use, modify, and distribute this material under the terms of the License. See LICENSE and NOTICE for full terms. See the licensing overview.