Skip to main content

Integration

Start here to build on Coordination Network. This page shows the parts of the stack, which packages each part installs, and how they talk to each other. Each package page under Packages has its full API, and the glossary defines the terms.

Run it locally​

See the whole system work before you write any code. You need Node 22.18 or later, Yarn 4 and Foundry 1.8.5. From the repository root:

yarn
yarn setup:foundry
yarn build:libraries && yarn build:contracts
yarn stack --check

The last command starts a local chain, deploys the contracts, starts three member servers, and plays onboarding, issuing, proving, revoking and member admission over HTTP. It ends with stack check passed. Run yarn stack without --check to keep the stack running with its dashboard. The phone apps and Sepolia are covered in the Sepolia demo.

The parts​

PartRuns onWhat it doesReference app
User app (wallet)User's phoneHolds the user's keys and credentials, builds proofs, and answers member apps over deep linksapps/user-app
Network member appUser's phoneBuilt by each member, installed by users. Holds no user keys: it asks the user app and calls its member serverapps/network-member-app
Member serverMember backendRegisters users on chain, issues and revokes credentials, and verifies presentationsapps/issuer-service
IndexerMember backendScans stealth address announcements for the member's usersapps/indexer
VerifierAny backendChecks that a user holds a valid, unrevoked credentialBuilt into apps/issuer-service (POST /v1/verify)

Each member builds its own app and runs its own server and indexer. Users install one user app, and it serves every member app.

What to install​

Packages install as @coordination-network/<name>.

User app​

npm install @coordination-network/user-app-core @coordination-network/user-app-link @coordination-network/wallet @coordination-network/identity

user-app-core is the engine: give it a secure Store, a hardware device key and a prover, and it creates the identity and serves member app requests. user-app-link turns each incoming deep link into a call on it. On Android, the device key comes from expo-identity-keystore and the prover from noir-prover-native, which also needs noir-prover-ffi, the native library. These three are Android only:

npm install @coordination-network/expo-identity-keystore @coordination-network/noir-prover-native @coordination-network/noir-prover-ffi

Network member app​

npm install @coordination-network/network-member-app-core @coordination-network/user-app-link

network-member-app-core runs the member flows (enrol, issue, verify, revoke) over a link client from user-app-link and a client for the member server. You add your own policy and screens.

Member server​

Run apps/issuer-service as is, or build your own with:

npm install @coordination-network/credential @coordination-network/zk-artifacts @coordination-network/network-member-client @coordination-network/network-member-proof @coordination-network/revocation-registry @coordination-network/network-member-governance

credential and zk-artifacts issue credentials and verify proofs. network-member-client handles every chain write for users, using network-member-proof for the proof each write needs. revocation-registry keeps the revocation tree. network-member-governance is only for the member's own admission to the network.

Indexer​

Run apps/indexer, or build your own with:

npm install @coordination-network/identity

Verifier​

npm install @coordination-network/credential @coordination-network/zk-artifacts

Verify the proof, then accept it only if the chain still accepts the two roots it outputs. See Verification and revocation checks.

How the parts connect​

+--------------------------+ deep links +---------------------------+
| User app | <---------------> | Member app |
| user-app-core | user-app-link | network-member-app-core |
+------------+-------------+ +-------------+-------------+
| |
| challenge, credential, proof | HTTP, member token
| v
| +---------------------------+
+-------------------------------> | Member server |
| credential |
| network-member-client |
+-------------+-------------+
|
| reads, sponsored writes
v
+--------------------------+ scans +---------------------------+
| Indexer | ----------------> | Chain |
| identity | announcements | registries, announcer |
+--------------------------+ +---------------------------+
  • User app and member app talk over deep links with three requests: sign a registration, issue a credential, create a presentation. The user approves each one in the user app.
  • User app and member server talk directly for anything with key material, so the member app never sees a credential or a proof.
  • Member server and chain: each write for a user carries an anonymous proof that an approved member made it, and the Semaphore paymaster pays the gas for registrations, credential deliveries and revocations.

Verification and revocation checks​

For a custom verifier, use credential with matching zk-artifacts. verifyZkPresentationProof verifies the proof and expected inputs; it does not check contract state. Before accepting a presentation:

  1. Bind it to a request your verifier created, including its one-time challenge, audience, time, programme, and country.
  2. Check the approved-issuer root and revocation root against the authoritative contracts on the intended chain.
  3. Claim the request atomically before verification, so concurrent submissions cannot both succeed, then record the result on your backend. The wallet reporting that it sent a proof is not an acceptance decision.

The issuer service verification route shows the reference sequence. Programme and country remain public in the presentation.

Wallets must refresh revocation state before presenting. Updating a local tree does not publish a revocation; a member must submit the contract write. Contracts may accept superseded roots for a configured window, so revocation does not necessarily invalidate every in-flight presentation immediately. See the revocation registry and privacy and security guide.

Packages​

To use a package marked Not on npm, copy its folder into your project or add it as a workspace dependency.

PackageDescription
accountEIP-7702 accounts and Semaphore paymaster proofs for sponsored user operations
app-uiNot on npm. Design tokens and screen components shared by the reference apps
circuitsNoir presentation circuit
contractsSolidity contracts: registries, governance, approved-issuer set and paymaster
credentialIssues credentials and builds and verifies zero-knowledge presentations
expo-identity-keystoreExpo module for hardware-backed P-256 keys in the Android Keystore
identityDerives networkId and the user's keys on device, plus stealth address helpers
issuer-setApproved-issuer tree and its membership proofs
network-member-app-coreMember app flows: enrol, issue, verify, revoke and membership status
network-member-clientMember server helpers: issue credentials and write to the registries
network-member-governanceSafe transactions that admit or remove a network member
network-member-proofSemaphore proofs that authorise registry writes
noir-prover-ffiReact Native binding with the prebuilt Android library
noir-prover-nativeNative prover for React Native
revocation-registryRevocation tree with membership and non-membership proofs
user-app-coreUser app engine: identity creation and the deep-link requests
user-app-linkDeep-link protocol between the user app and member apps
user-clientOne-call onboarding: derive keys and build the signed registration request
walletHolder SDK: credential storage, revocation sync and consent-gated presentations
zk-artifactsCompiled credential circuit and its verification key

Networks​

The contracts run on Sepolia. Their addresses are on the deployed contracts page. The issuer service page lists the settings a member server needs.

Further reading​