Hkchain

Hkchain — Roles and Permissions

Role taxonomy

Hkchain defines a small number of primary roles and a set of sub-roles that delegate from a primary role with constrained authority.

Primary roles

RoleLevelDelegated viaGranted by
Licensed Issuer5—Governance (MsgWhitelistIssuer)
Auditor— (registered in x/reserve)—Governance (MsgRegisterAuditor)
KYC Provider— (address in the x/kyc parameter kyc_provider_addresses)—Governance (MsgUpdateParams)
Compliance authority— (single address in the x/compliance parameters; can be a multisig)—Governance (MsgUpdateParams)
Institutional holder4—KYC Provider (MsgEnroll or MsgUpgradeLevel)
Retail (enhanced)3—KYC Provider (MsgEnroll or MsgUpgradeLevel)
Retail (basic)2—KYC Provider (MsgEnroll or MsgUpgradeLevel)
Unverified1—KYC Provider (MsgEnroll)
Blacklisted0—Compliance authority (MsgBlacklist or MsgUpdateSanctionsList), or a block decision on a reviewed flag
Supervisor (HKMA)——No on-chain identity; read-only access to the dashboard and public queries

An address with no identity record has no level at all and can be neither party to an HKD transfer.

Sub-roles

Sub-roleParentDelegated viaMessage allowlistExtra enforcement
Compliance ReviewerIssuer (L5)MsgBindSubRole{role: reviewer}MsgReviewFlag, MsgEscalateFlagA block decision blacklists the flag's subject (kycKeeper.Blacklist(...) with flag/<id> as the evidence chain). KYC-provider enrollment (MsgEnroll / MsgUpgradeLevel) gates on a separate address allowlist (x/kyc.Params.kyc_provider_addresses), not the reviewer sub-role. Reviewer-as-KYC-provider convergence is roadmap.
Compliance OfficerIssuer (L5)MsgBindSubRole{role: officer}MsgCloseFlag onlyCloses escalated flags. A block decision blacklists the subject through the same primitive, with flag/<id> as the evidence chain. Direct MsgBlacklist / MsgUpdateSanctionsList are not in the Officer allowlist: those are signed by the compliance authority, a single address appointed by governance (which can be a multisig), not a sub-role.
AgentRetail / Institutional user (L2 / L3 / L4)MsgBindSubRole{role: agent, policy_envelope}MsgSend onlyAgentPolicyDecorator enforces daily_cap, per_tx_cap, revoked

Principle of minimum surface: each sub-role is intended to hold exactly the message types it needs. Mint, distribute, per-issuer pause and redemption acknowledgement are never delegated: their handlers require the signer to be the issuer itself.

Sub-role enforcement is implemented by the RoleGateDecorator in the AnteHandler chain. A transaction in which a sub-key signs a recognised message outside its allowlist is rejected at admission. The gate recognises MsgSend and the compliance administrative messages; other message types fall through to the authority checks in their own handlers, which is where a sub-key's attempt to mint or pause fails. For the Agent sub-role, the AgentPolicyDecorator runs immediately after RoleGateDecorator and enforces the policy envelope on hkd.* transfers.

Revocation: MsgRevokeSubRole{parent, sub_addr} applies to any sub-role type and takes effect at the next block. In the agent case, this delivers a chain-enforced agent revocation primitive: the user's revocation binds regardless of which service the agent is interacting with.

Agent policy envelope (strict scope): three fields only: daily_cap, per_tx_cap and revoked. Both caps are denominated in one hkd.* denomination. The daily cap applies to a fixed 24-hour window that starts at the agent's first spend, so across a window boundary an agent can spend up to twice the cap within 24 hours. Other policy dimensions (time windows, merchant whitelists, velocity curves) are roadmap.

What each role sees and does

The dashboard at /dashboard is read-only: it signs no transactions. Each party signs its own operational messages (mint, distribute, redemption acknowledgement, review decisions, co-signatures) with its own key, for example through the hkchaind CLI. The dashboard landing page links to one view per role.

HKMA Supervisor: /dashboard/supervisor

  • Circulation: total across all hkd.* denominations
  • Reserve: latest attested reserve market value, with its period and freshness
  • KYC distribution: identity counts by level; each non-empty level opens a paged list of its addresses under /dashboard/supervisor/kyc/
  • Sanctions set: the current sanctions list
  • Transaction detail: the block explorer (/explorer) shows each transaction's gate trace, flags, Travel Rule payload and audit entries

Supervisor cannot sign transactions. They observe.

Licensed Issuer operations: /dashboard/issuer

  • Treasury: per denomination, the circulation held externally, the minted_available balance still in treasury, and pending_redemption
  • Mint: the two-step MsgMint → MsgDistribute flow; a mint requires a fresh attestation and is rejected if the latest one is stale
  • Open redemptions: requests from holders who have burned, awaiting the issuer's MsgAckRedemption with an off-chain fiat payment reference
  • Pause state: the global and per-issuer pause flags. An issuer can pause its own denomination; a global pause requires governance

Licensed Issuer compliance team: /dashboard/compliance

  • Flag queue: every flag, newest first, with its review state
  • Sanctions list: the current sanctions set, for case context. Updates are signed by the compliance authority via MsgUpdateSanctionsList, not by the Officer sub-role
  • Reports: a pointer to the Report query, a period roll-up of the audit log and the flag queue

Reviewers approve, block or escalate flags with their sub-keys (MsgReviewFlag, MsgEscalateFlag); officers close escalated flags via MsgCloseFlag. A block decision from either role cascades to the address blacklist automatically (kycKeeper.Blacklist(...) with the flag id as evidence chain). KYC applications are not processed here: on the test network they are reviewed in the onboarding portal, and the chain records only the outcome.

Auditor: /dashboard/auditor

  • Pending co-sign: PENDING_AUDIT attestations awaiting an auditor's MsgCoSignAttestation
  • Auditor registry: the registered auditor addresses; registry membership is what grants the co-sign capability

Institutional holder: standard wallet experience

  • MetaMask via the issuer's extended ERC-20 precompile (balances display as for any ERC-20 token; transfers use transferWithTravelRule), or a dedicated HK-issuer-provided wallet
  • Visible: balance, transaction history, and in the explorer any flags raised on their transactions (escalation visibility for their own compliance obligations)

Retail holder: public wallet + /dashboard/public/reserve-lookup

  • Wallet: balance, transfer, burn/redeem
  • Reserve lookup page: enter any address (typically their own) and see, for each HKD denomination held, which attestation backs the balance, with its signers and the hash that binds it to the issuer's published assurance report

Public: /dashboard/public/reserve-lookup

  • Same as retail holder, accessible without wallet connection. Anyone can verify any address's reserve backing.

Authentication in MVP demo

The Dashboard uses a URL query parameter (?role=supervisor|issuer_ops|…) plus local storage for demo convenience. This is not a production auth scheme — production will require real RBAC integration with each organization's identity provider.

Governance and on-boarding

  • A new licensed issuer is onboarded via a governance proposal (MsgWhitelistIssuer). The message names the issuer's address, its display name and a licence reference (an HKMA licence number or document hash, verified off chain by governance participants), and sets the address to level 5. The issuer's denomination (hkd.<issuer-shortname>) is registered by a separate governance message (MsgRegisterDenom); giving it an EVM representation also requires a software release.
  • A new auditor is onboarded via governance (MsgRegisterAuditor), naming the auditing firm, its signing address and a licence or engagement reference.
  • A new KYC provider is onboarded via governance too, but through the module parameters rather than a dedicated message: MsgUpdateParams adds its address to x/kyc's kyc_provider_addresses, and only an address on that list may sign MsgEnroll or MsgUpgradeLevel.
  • The compliance authority is appointed and rotated by governance through the x/compliance parameters. It signs time-sensitive operational actions: sanctions updates, blacklistings and account freezes, which carry a reason and an evidence reference, and rule parameter changes, which are recorded as an on-chain event.

These governance messages are authorised by the governance module account, so they take effect only as passed governance proposals, which are public and go through a voting period. Production will require a governance arrangement with HKMA observability.

Deliberate omission: no supervisor write path

Hkchain deliberately does not provide a supervisor-signed transaction type. The supervisory role is observational, not operational. Emergency remediation (e.g., global pause of a denom) routes through governance, where HKMA may participate as a proposing or voting party according to the governance arrangement, but does not unilaterally sign into the chain.

This matches HKMA's operational model — supervise, demand, sanction — and avoids the uncomfortable narrative of regulators "operating the chain."