Skip to content

Contract Diagram

Cursor Agent edited this page Apr 8, 2026 · 11 revisions

OCP Contract Architecture

Contract Hierarchy

flowchart TB
    OcpFactory -->|AuthorizeIssuer| IssuerAuthorization
    IssuerAuthorization -->|CreateCapTable| CapTable
    CapTable -->|Edit| Issuer["Issuer (OCF object)"]
    CapTable -->|Create/Edit/Delete| OCF["OCF Objects & Transactions"]
Loading

CapTable manages all OCF contracts via Maps (OCF object ID → ContractId) for O(1) lookup. The OCF object ID is a business identifier (typically a GUID from the database), not the DAML ContractId which changes on each archive/recreate.

Contract Flow

sequenceDiagram
    actor SO as System Operator
    actor I as Issuer
    participant OcpFactory
    participant IssuerAuthorization
    participant Issuer
    participant CapTable
    participant OCF as OCF Contracts

    SO->>OcpFactory: Deploy (once)
    SO->>OcpFactory: AuthorizeIssuer(issuer)
    OcpFactory->>IssuerAuthorization: create

    I->>IssuerAuthorization: CreateCapTable(issuer_data)
    IssuerAuthorization->>Issuer: create
    IssuerAuthorization->>CapTable: create (with Issuer)

    I->>CapTable: UpdateCapTable(creates, edits, deletes)
    CapTable->>OCF: archive/create OCF contracts
Loading

Key Design Patterns

Pattern Description
Dual Signatories All contracts require both issuer and system_operator
Factory Chain OcpFactory → IssuerAuthorization → CapTable
State Management CapTable maintains Map Text (ContractId T) for O(1) lookup
Reference Validation CapTable validates referenced objects exist before creating (e.g., stakeholder must exist before stock issuance)
Archive + Recreate Edit = archive old contract + create new + update map
Issuer is Special Exactly one per CapTable, can only be edited (no delete)

File Structure

OpenCapTable-v34/daml/Fairmint/OpenCapTable/
├── OcpFactory.daml          # Factory contract
├── IssuerAuthorization.daml # Authorization contract  
├── CapTable.daml            # State management (GENERATED by codegen)
├── Types.daml               # Shared types & enums
└── OCF/                     # 47 OCF object contracts
    ├── Issuer.daml
    ├── Stakeholder.daml
    ├── StockClass.daml
    ├── StockIssuance.daml
    └── ...

scripts/codegen/
├── generate-captable.ts     # Generates CapTable.daml from OCF types
└── captable-config.yaml     # Reference validation configuration

Code Generation: CapTable.daml is generated by scripts/codegen/generate-captable.ts, which discovers OCF types from OpenCapTable-v34/daml/Fairmint/OpenCapTable/OCF/ and generates the appropriate Maps and CRUD choices. Run npm run codegen:captable to regenerate.

NFT packages (separate from CapTable factory chain)

CapTable / OcpFactory flow above is unchanged. NFT contracts live in two DAML packages:

Package Role
NftApi-v01 Nft.Api.V1 — canonical Nft interface and types
NftReference-v01 Nft.Reference.V1 — reference registry, assets, metadata, receive authorization

npm run codegen runs scripts/merge-nft-iface-codegen.ts after both packages codegen: it copies Nft/Api from the API package into the reference package’s generated lib/ so the standalone reference tarball exports both Nft.Api and Nft.Reference (the merged root lib/ does the same for the NPM bundle).

Older OpenCapTableNftIface-v01 / OpenCapTableNft-v01 DAR backups under dars/ are unrelated to current source layout.

References

Clone this wiki locally