Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Project Overview

This is a working document and changes are expected. Currently as of Nov 2024, pages with * prefix are yet to be updated to the new design with SPV legal structure.

NYMLAB is building the Platform-D project, which is comprised of components and integration between different legal entities.

The project's core utility is for SME owners to securitise and tokenise their electronic invoices efficiently; for buyers, a way to demonstrate good payment history and access better suppliers and rates; for investors, a way to democratise credit transmission investments.

The investment grade security-tokens provide low risk, deposit-rate-plus yield for retail & institutional investors.

In order to achieve this, there are 3 core entities with specific functions.

  1. Digital SPV: PD-SPV - A digital (both on and off chain) special purpose vehicle that issues security tokens backed by electronic invoices and artifact that make up Origination Data Package (ODP).
  2. Digital Securities Depository (DSD): Platform-D Ltd A regulated entity that provides the infrastructure for the issuance and settlment of securities, in this case, recorded as tokens on a Blockchain.
  3. Assurance Reserve Trust (ART): PD-ART A trust that holds fiat currency reserve offchain for PTs issued by the SPV.

The onchain parts of all the components are built on D-Chain. For details on the chain, please refer to the D-Foundation documentation.

In the initial MVP stage, Platform-D Ltd will only operate the DSD. It is however planned for it to also operate as an MTF.

We will highlight the key technical components here, for more details, please refer to the legal structures documents.

Roles / LicenseEntityDescription and Component interactions
DSD & MTFPlatform-D Ltd.Issuance and settlement of PTs - smart contracts and registered on x/orderbook, x/tokenfactory
SPVPD-SPV Ltd.Notarises ODP, PT price discovery and services PTs - build on smart contracts and registered x/notary, x/orderbook, x/tokenfactory
Verifiable Credential Issuer & CustodianGayadeed (for PD-SPV)Document composition, digital signature, issuance and storage of verifiable credentials
Onboarding services (KYC / KYB / AML)Gayadeed (for PD-SPV)The KYC / AML flow for onboarding is provided by Gayadeed
Crypto AML / tx servicesGayadeed (for PD-SPV)transaction APIs: enforce checks via webauthn

Repos overview

RepoDescriptionSpecs
ChainD Chain modules and contractsDocs
SPV WebappThis needs to be forked / replaced to here
SPV contractsSmart contracts for SPVsee SPV onchain services
DSD contractsSmart contracts for DSDsee DSD onchain services
SPV APIsBackend API for the webapp
Gayadeed VC APIIssuer and custodian of verifiable credentials
Gayadeed Onboarding APIKYC / AML onboarding flow pre-account registration
Utils: Protobuf rust & grpc clientsRust protobuf get and GRPC tonic clients
Utils: Protobuf ts & codegen clientsTS protobuf interfaces and contract interfaces

MVP stack

components image

Contribution Guide

This book is a series of markdown files, please see general style guide.

Easy version control

In order to easily identity git diffs, make sure to break up sentences / paragraphs to different lines logically (Typically at comma / full stops etc).


**DO NOT DO THIS**
This is a long sentence, with comma and others. Changing a single word will cause a diff on a whole paragraph.


**DO THIS INSTEAD**
This is a long sentence, 
with comma and others. 
Changing a single word will only cause a diff on a single line.

For reability and not to repeat oneself, we please look at the following for how to do hyperlinks in a page


This is a page with some links:

--------------
**DO NOT DO THIS**

- [google](https://google.com) can be used to search the internet, by using [google](https://google.com)...

--------------

--------------
**DO THIS INSTEAD**

- [google] can be used to search the internet, by using [google]...

Then at the bottom of the page you can link references

[google]: https://google.com

--------------

Frontend Only Demo

This project is for a sprint that will demonstrate visually only E2E from an invoice (existing) and added already to platformD to the point where the PT securities are created.

Highlevel components required in this demo:

  • platformD WebApp
    • Supplier
    • Investor
  • platformD server
    • CRUD states (Invoices, PTs, Users) (mock chain states)
    • orderbook
  • Gayadeed
    • SPV tenant
    • VC-API

The flow can be seen in this:

sequenceDiagram
autonumber

actor s as Supplier
actor o as Obligor
participant ws as WebApp <br /> Supplier
participant spv as SPV <br /> backend
participant g as Gayadeed
participant wi as WebApp <br /> Investor
actor i as Investor

s ->> ws: Log In
note over ws: 1. Get Invoices
s->> ws: Selects Invoice <br /> Request for CTA
ws ->> spv: request create deed
spv ->> g: deeds/create
g ->> o: invites to sign
note over g: VC issued
g ->> spv: Sends VC
note over spv: invoice status: Notarised

s ->> ws: List Invoice <br /> w/ reserve price
ws ->> spv: updateInvoice <br /> status: listed
note over spv: Create sell order in orderbook

i ->> wi: Buy order
wi ->> spv: Create buy order in orderbook

note over spv: Order matches
note over spv: 1. deduct investor account
note over spv: 2. credit supplier
note over spv: 3. create PTs
note over spv: 4. update invoice: status sold

Objects Design

User

Data Structure

  • userid
  • role (supplier, investor)
  • balance (Euros)
  • supplier VAT (if supplier)

Invoice

States

stateDiagram-v2
    [*] --> Pending_CTA
    Pending_CTA --> Notarised
    Notarised --> Listed
    Listed --> Notarised
    Listed --> Settled

Template of Verifiable credential for invoice

disclosable: disclosable in sd-jwt

  • supplier VAT
  • buyer name
  • supplier name
  • invoice number (specific to the invoice)
  • creation date (ddmmyyyy)
  • (disclosed) buyer VAT
  • (disclosed) supplier_onchain_address dchain addr
  • (disclosed) reference to calculate the DID of the notorised asset
  • (disclosed) DID (identifier of the notarised asset - did:dchain)
  • (disclosed) total_amount_due : coin (amount, denom)
  • (disclosed) payment_due_date: timestamp

Reference string for notarise asset is hash of:

  • buyer VAT
  • supplier VAT
  • invoice number
  • invoice issuance date (ddmmyyyy)
  • amount due

PT

There are 2 underlying structure here

  • PT (the actual structure representing the security with the metadata)
  • PT units (the units related to one of the PT structures)

PT Data Structure

  • ISIN;
  • Status: (Issued, Matured, Redeemed)
  • ref_id (key for PT Units)
  • Max supply

PT Units

in the db it will just be key (ref_id, user_id)

  • ref_id
  • owner (userid)
  • amount

Order

Data Structure

  • type: buy / sell
  • reserver price
  • quantity
  • filled (sell only will this be 0 / 100%)

Orderbook

AON - All or nothing on the sell side orderbook

Gayadeed Deed creation


{
    "folderName": "BUYEXXYZ",
    "folderType": "PLATFORM_D_CONTRACT",
    "kind": "INVOICE_NOTARIZATION",
    "signType": "FEQ",
    "enableChecklist": true,
    "signatoryUserId": <ENV_TENANT_USER_ID>,
    "description": "202510123",
    "participants": [
        {
            "name": "Egidio",
            "surname": "Casati",
            "email": "egidio.casati+odp_01@gmail.com",
            "phoneNumber": "+39-3459277339",
            "fiscalCode": "CSTGDE70C22F205C",
            "gender": "M",
            "birthDay": "1970-03-22",
            "cityBirthPlace": "Milano",
            "districtBirthPlace": "MI",
            "birthCountry": "IT",
            "citizenship": "IT",
            "address": {
                "street": "Viale Teodorico",
                "number": "7",
                "city": "Milano",
                "district": "MI",
                "cap": "20149",
                "region": "Lombardia",
                "country": "IT"
            },
            "metadata": {
                "BuyerName": "ACME S.p.A",
                "BuyerVatNumber": "IT12312312312",
                "BuyerAddressStreet": "C.so di P.ta Vittoria, 47",
                "BuyerAddressCity": "Milano",
                "BuyerAddressZipCode": "20122",
                "BuyerAddressCountry": "Italy",
                "BuyerLegalRepName": "Egidio Casati",
                "BuyerLegalRepTin": "CSTGDE70C22F205C",
                "SupplierName": "NYMLAB Srl",
                "SupplierVatNumber": "IT32132132132",
                "SupplierAddressStreet": "piazza del duomo, 1",
                "SupplierAddressCity": "Milano",
                "SupplierAddressZipCode": "20100",
                "SupplierAddressCountry": "Italy",
                "SupplierOnchainAddress": "dchain:0x1234567890abcdef1234567890abcdef12345678",
                "OnchainRef": "some-hash-of-the-invoice-data",
                "DID": "did:dchain:1234567890abcdef1234567890abcdef12345678",
                "InvoiceId": "2025010123",
                "InvoiceIssueDate": "2025-06-15",
                "InvoiceAmount": "25000.00",
                "InvoiceDescription": "Consultancy Q1 2025",
                "InvoicePaymentDueDate": "2025-07-15",
                "InvoiceUpdatedPaymentDueDate": "2025-07-31"
            },
            "participantType": "SUBSCRIBER",
            "personType": "NATURAL_PERSON"
        }
    ],
    "autoStartConfig": {
        "afterDocumentAutoGeneration": false,
        "afterChecklistCompletion": true
    }
}

Digital SPV (PD-SPV)

platformD Web Applications

There are several individual applications:

  • Public Website (Details / Docs / Background / Call to action)
  • Public Analytics Dashboard: Current platformD statistics including the art (differ from Dchain dashboard)
  • Authenticated Page is the majority of the applications

We will focus on the Authenticated Area in this section.

Authenticated Page

Important to note that the authenticated area itself is a wallet using the Vectis infrastructure

This page contains:

  • Account Info (Personal data / documents uploaded)
  • Verifiable credentials (stored (custody) in Gayadeed servers)
    • Physical Person
    • Eligibility to use Platform-D
    • Notarised invoices (Suppliers)
    • Legal Person (Suppliers)
    • potentially others...
  • Wallet settings: Plugins etc (see old demo
  • Balances and User transactions (see previous dashboard)
  • Orderbook
  • Suppliers notarisation workflow tab (Unlocked by completing more checks)
  • Investors investment tabs (Unlocked by completing more checks)

Gayadeed API and Integration

This service serves as the middle point between Gayadeed other services and [Platform-D API]. In general, it provides offchain processes, data and information, e.g.

  • KYC / AML process
  • Personal data storage (uploaded documents)
  • Issuance of verifiable credential process
  • Verifiable Credential storage
  • Provides the challenge for webauthn and verify

platformD API

This service is the main backend of the UI. As accounts authenticate into Gayadeed API, they are automatically authenticated into this service.

Most onchain services are provided here:

  • Crypto continuous AML
  • Indexing onchain transactions
  • Provide pricing data onchain

Onboarding

The onboarding of all users require a minimal KYC requirements no matter what role they undertake.

The key identifier for any users in the system is their credential in Keycloak, the subject sub identifier is used across all microservices.

Components involved in the onboarding process are:

Apart from the Keycloak Admin Client connection, all services communicate via gRPC.

Sequence of onboarding and logging in

sequenceDiagram
    autonumber
    actor User
    participant Keycloak
    participant User Mgmt
    participant Gaya-kyx-&-vc

    participant D-Account
    participant D-Chain

    Keycloak --> User Mgmt: Holds Admin Client <br> controls user attributes

    User ->> Keycloak: Create Webauthn Credential
    User ->> Keycloak: Login with token
    User ->> D-Account: check `AccountKycStatus`

    alt AccountKycStatus == `init`
        D-Account->> Gaya-kyx-&-vc: `GayaKyxCreateTransactionService` <br> with `response_endpoint` to User Mgmt
        Gaya-kyx-&-vc ->> D-Account: `CreateTransactionResponse` with `challenge_url`
        Note over D-Account, Gaya-kyx-&-vc: The `response_endpoint` is in the transaction request <br> but challenge_url is returned to D-Account for the User

        D-Account ->> User: re-route to `challenge_url`
        User ->> User: Jumio web client re-route to <br> `platformd.io/kyx-pending`

        Note over Gaya-kyx-&-vc: Jumio calls `/kyx/callback` on update
        Gaya-kyx-&-vc ->> User Mgmt: `GayaKyxCallbackService` <br> with status and decide if it should issue credential
        User Mgmt ->> Gaya-kyx-&-vc: `CallbackResponse` <br> with info regarding if Gaya-vc should be called

        opt On `CallbackResponse` create physical person cred == true
            Gaya-kyx-&-vc ->> Gaya-kyx-&-vc: Request batch issuance of credential for physical person
        end

        User Mgmt ->> Keycloak: Update user attributes accordingly


    else AccountKycStatus == `pending`
        D-Account ->> User: wait

    else AccountKycStatus == `success`
        Note over D-Account: Check `token.dChainAddr`

        alt token.dChainAddr == empty
            D-Account ->> D-Chain: create onchain wallet
            D-Account ->> User Mgmt: update token.dChainAddr field
        else token.dChainAddr == not empty (support only 1 in this case)
            D-Account ->> D-Chain: query data (also from indexer)
            D-Chain ->> D-Account: return account data
        end
        D-Account ->> User: Return account data

    end

User registration

Impl: Keycloak Platform-D Realm

This step users interact with keycloak Platform-D realm to register their Webauthn credentials. The public key created and stored in keycloak will be used to create they Onchain wallet later on.

The tokens must present following attributes on top of the standard OIDC claims:

{
    "kycStatus": "init",
    "roles": ["<roles>"]
    "dChainAddr": ["<address>"]
}
  • kycStatus includes both identity proofing and blacklist check status. Please see KYC Status for more details. This attribute is updated by the gaya/kyx calling to the UserManagement API.

  • roles are the roles that the user has in the system. Currently roles are supplier, investor and admin. This attribute is updated by the platform-D onboarding API for the user on the UserManagement API.

  • address are the onchain addresses created for the user by the platform-D onboarding API after KYC_SUCCESS status. This attribute is updated by the platform-D onboarding API for the user on the UserManagement API.

Please see webauthn background on credential_id

KYC and Blacklist check

Impl gaya/gaya-kyx

After a value token is created, the user will be navigated to the KYC process. The KYC process depends on the nationality of the user. For Italian users, Gayadeed provides SPID identity proofing and Blacklist test, for other nationalities, Jumio is used for identity proofing and ComplyAdvantage.

The state of the KYC is stored in the Keycloak user attributes.

Please see details of iframe communication for the process of KYC by jumio here

KYC Status

The KYC states are tied to the sub.

stateDiagram-v2
    [*] --> KYC_INIT
    KYC_INIT --> KYC_PENDING
    KYC_PENDING --> KYC_FAILED
    KYC_PENDING --> KYC_SUCCESS

Verifiable Credentials Management

Impl gayadeed-vc-api

This service interacts with Paradym.id API services to create credential templates (see credential services for more template details), and stores the issued credentials on behalf for the users.

This service stores the credential for the users.

Onchain Transactions

In order for users to transact on Platform-D chain, they must be able to sign a transaction with the controller pubkey associated in the Entity, and they must present a verfiable presentation (derived from the verifiable credentials).

In core/services/wallet.services.ts we have signDirect which signs our RelayMsg for Platform-D Proxy.

FIXME: decide on integrating abstraction in sdk

As opposed to asking the user to use passkeys multiple times during transactions, we provide a reusable token (reuse for requesting presentations) for the user on login.

Note: The current (Berlin branch), in login the wallet itself verifies the challenge just to verifies the pubkey correctness.

sequenceDiagram
    autonumber
    actor Platform-D Webapp
    participant Platform-D API
    participant AML/TR
    Participant Gayadeed API/DB
    Platform-D Webapp ->>+ Platform-D API: Transaction Details
    Platform-D API ->> AML/TR: AML / TR Risk Analysis
    AML/TR -->> Platform-D API: Analysis results
    Platform-D API ->> Gayadeed API/DB: Tx Data Storage attempt (record keeping)
    Gayadeed API/DB ->> Platform-D API: Relevant VC Presentation


    alt Passed
        Platform-D API ->>- Platform-D Webapp: call `navigator.credentials.get()` with `credential_id`
    else Failed
        Platform-D API ->> Platform-D Webapp: Error in AML / TR
    end

Please see webauthn background on credential_id.

Continuious AML Provider

Range is a Cosmos / IBC / Ethereum OFAC list specific risk calculation service. See their core offerings

Absolutely useful! They are looking for product partnership so pricing is very flexible.

Short term:

Continuous Crypto AML (transaction security API - RISK): They are specified in Cosmos / IBC and Ethereum (ofac list) / own research on scams, for our mainnet deployment (Neutron)

Medium term:

These are on top of Continuious Crypto AML

Users: They provide very useful UX API aka transaction security API - SIMULATION: they provide API to tell the user what will be the state of their wallet after they do the transactions (i.e. more NFT / Less fund / etc), but currently only on Osmosis, need intergration with Platform-D node.

Platform-D: Thread detection API - For IBC etc probably not so immediate (i.e. they usually do funds leaving bridges etc) but we can get them to monitor say --- ECB interest rates suddenly drop for 20% on unexpected dates from the oracle then something probably wrong. They also work with auditors to provide more vulnerable states. We will also know, for example if our yield curve have big changes then we know as well.

Crypto Travel Rule Provider

**WIP - update with NoteBene **

platformD ART and Data Dashboard

Dashboard

There are 2 main types of metrics

  1. ART: Assurance Reserve Trust data
  2. Overall Metrics: TVL, orderbook summary data and link to orderbook, invoice / investment data

2. Trading Data

  • Total value locked (TVL): Sum of principles of all outstanding invoices

$$TVL=\sum_i Principle_i$$

Example: Centrifuge TVL (Top left)

  • Assurance Resereve (AR) treasury size: Fees are generated when suppliers and investors interact onchain, these fees go into the Assurance Reserve that is onchain. (Since inception)

2.1 Orderbook Summary

Summary of orderbook, with a link to the orderbook

  • Total outstanding supply of invoices - outstanding volume of invoices that have been submitted to the order book, but have not been matched

  • Total liquidity from investment buy orders - outstanding volume of investments that have been submitted to the order book, but have not been matched

  • Predicted Yield Curve: An example of this is US Treasury, however, for invoices it will be max 3 months on the x-axis.

2.2 Assets Summary

Summary of traded assets

  • Daily maturing assets

  • Weekly maturing assets

  • Weighted average maturity (WAM) $$InvoiceWeight= \frac{Principle}{TVL}$$ $$WAM=\sum_i InvoiceWeight_i*T_i$$

  • Total buyers default risk - Italian public entity rating - Currently BBB, from source.

  • Outstanding assets and maturities (detailed) - if expanded by the user.

  • Late assets (volume and percentage of TVL)

  • Defaulted assets (volume and percentage of TVL)

Examples:

  • centrifuge pool: On the top right there are some metrics for each pool. It is different to what we are doing but this is a view we found.
  • rwa.xyz: Scroll down to investment and the table (sroll right) has similar metrics as an example as well.

3. Governance

The purpose of this page is to show the proposals and voting status, creating proposals. PT holders are able to create proposals

  • DAOs can have different treasury and pools for community spending and token holders can hold them.

Examples:

  • DAODAO: This app actually hosts a few Decentalised Autonomous Organisations (DAOs), the link is to one called Neutron. You can can the proposal details etc.
  • CommonWealth: This app also hosts many different chain's governance. We have recently proposed for cheqd and you can see the onchain proposal here.

The details of governance functions can be found on the cosmos-sdk docs, which is what we will be using.

Calculations: Calculated Values

  • Market cap (circulating)

$$Market Cap (circulating) = P_{pT} * S_{cir} $$

  • Market cap (diluted)

$$Market Cap (diluted) = P_{pT} * S_{total}$$

  • Total value locked ($TVL$)

$$TVL=\sum_i Principle_i$$

  • Weighted average maturity ($WAM$)

$$InvoiceWeight= \frac{Principle}{TVL}$$

$$WAM=\sum_i InvoiceWeight_i*T_i$$

  • Net assets value ($NAV$)

$$NAV=\sum_i \frac{RiskAdjCashflow_i}{(1+DR_i)^{T_i}}$$ , where $$RiskAdjCashflow=Principle*(1- POD*LOG)$$

  • Timeseries of each investment and its annualised yield $$AnnualisedYield= \frac{Principle-InvestmentAmount}{InvestmentAmount}*\frac{365}{T}$$

$$AnnualisedReturns= \frac{\sum_{y=CurrentDate-1Year}Principle_i-InvestmentAmount_i}{\sum_{y=CurrentDate-1Year}InvestmentAmount_i}$$

  • Calendar year returns - returns for the current year, example for year 2023: $$CalendarYearReturns= \frac{\sum_{y=01/01/2023}Principle_i-InvestmentAmount_i}{\sum_{y=01/01/2023}InvestmentAmount_i}$$

TBD:

Individual investor metrics

Returns

  • Timeseries of each investment and its annualised yield $$AnnualisedYield= \frac{Principle-InvestmentAmount}{InvestmentAmount}*\frac{365}{T}$$

$$AnnualisedReturns= \frac{\sum_{y=CurrentDate-1Year}Principle_i-InvestmentAmount_i}{\sum_{y=CurrentDate-1Year}InvestmentAmount_i}$$

  • Calendar year returns - returns for the current year, example for year 2023: $$CalendarYearReturns= \frac{\sum_{y=01/01/2023}Principle_i-InvestmentAmount_i}{\sum_{y=01/01/2023}InvestmentAmount_i}$$

Individual invoice indicators

symbolArgsOn / Off ChainDescriptionLocation
$$Principle$$Invoice PrincipleOff ChainInvoice principle amountInvoice parameter
$$InvestmentAmount$$Investment AmountOnOrder book matched price of a discounted invoiceOrder book module
$$T$$Invoice MaturityOff ChainTime until invoice principle amount is dueInvoice parameter
$$POD$$Probability Of DefaultOff ChainDefault probability of a buyerOracle
$$LGD$$Loss Given DefaultOff ChainExpected loss given default of a buyerOracle
$$DR$$Discount RateOff ChainCashflow discount rateYield curve module

Backend Services

Oracle Services:

  • Euro Credit States: update on Investor action fiat deposits and withdrawals
  • Invoice States: update on buyer paid / is late / default
  • Orderbook approval: update external market data and risk engine data
  • Market Data: Update algo curve with external market data

Verifiable Credential Services:

  • Update data like issuer list / revocation onchain if not over IBC

Oracle (Assurance, Yield Curve, Payments)

Fiat Payment Cash Leg

Before a fullly onchain stable coin payment system, there will be all / partial interaction with fiat banking payments.

flowchart TD
    I(Investor Acc) -- Burn Euro Credits \n Pays Supplier --> S(Supplier Account)
    I(Investor Acc) -- Burn Euro Credits \n Withdraw --> I2(Investor Other Bank Acc)
    P(Payment Acc) -- Mint Euro Credits \n Buyer Pays Invoice --> I
    I2 -- Mint Euro Credits \n Top Up --> I

  • Payment Acc: the omnibus account for all invoice Buyers to pay into; Platform-D Ltd can instruct to send funds to investors
  • Investor Acc: the investor's segregated account on Fabrick; Platform-D Ltd can instruct to send fundst to suppliers

Assurance

Yield Curve

Open Banking Integration

SPV Onchain Services

PD-SPV is registered on on several modules D-Chain as a DApp.

Interactions

Smart Contracts

  • Notary Verifier: a simple contract that calls AVIDA sd-jwt verifier to verify the ODP verifiable presentation submitted by a user
  • Notarised ODP: Stores information of the underlying ODP, i.e. the owner and states
  • Orchestrator: the main contract with interfaces
    • for x/notary to call PostVerExec to instantiate a notarised ODP contract
    • interacts with x/tokenfactory to create and burn SU price syndication units to interact on x/orderbook
    • interacts with the instantiated notarised ODP contracts to instruct listing on x/orderbook when specified by supplier
    • interacts with x/orderbook to create orderbook for specific SU

Module Registrations

  • x/notary: for notarisation process for the ODP
  • x/tokenfactory: for creating and burning SU & EuroCredits tokens, SU are fungible across the same expiration date
  • x/orderbook: for creating price syndication orderbook for SU and EuroCredits

Process Flows

sequenceDiagram
    actor Supplier

    participant M as module
    participant SPV
    participant DSD
    participant ART
    actor Investor
    actor Obligor
    autonumber

    SPV ->> M: x/notary MsgRegisterAsset
    Supplier ->> M: x/notary MsgNotarise;
    M ->> DSD: verify
    DSD -->> M: result
    M ->> M: notarise and burn DTs
    M ->> SPV: on notarise
    SPV ->> M: sell order

    M ->> M: x/matchengine: add sell order to AON orderbook
    Investor ->> M: x/matchengine: add buy order
    M ->> M: x/matchengine: order matching
    M ->> SPV: x/matchengine: on match
    SPV ->> DSD: issue request
    DSD -->> M: x/tokenfactory mint & assign securities
    DSD -->> Supplier: payment
    DSD -->> SPV: ISIN
    SPV -->> M: x/notary update ISIN and owner

    Obligor ->> SPV: payment
    SPV ->> DSD: mature
    DSD ->> M: x/bank burn securities
    DSD ->> Investor: Payment

Implementation Details

x/notary DSD Verifier

The example verifier contract has the correct interface that the x/notary module calls.

Given that we are not using sylvia anymore(it is only a code generation tool), we can still use the d-foundation/protocol-contracts package for the types.

However the trait that the example contract implements will just have to be an enum in the ExecuteMsg entry point.

On the interface with AVIDA sd-jwt, we can look at the example contract in the AVIDA repo.

The verifiable presentation have to disclose the following fields.

  • buyer: string
  • value: coin
  • maturity timestamp
  • did_addr (string) expected instantiate2, code address

This has to be signed by a jwk that represents the SPV entity. Maturity timestamp > the current block time

Expected Verifiable Presentation

Instantiate2 logic

  1. Query API / webapp logic to get odp_contract_address (instantiate2 address) with a salt for instantiate2 which is hash of:

    • buyer VAT
    • supplier VAT
    • document type (invoice)
    • progress number
    • creation date (ddmmyyyy)
  2. Offchain issue verifiable credential (ODP VC)

    • (disclosable) buyer VAT
    • supplier VAT
    • document type (invoice)
    • progress number
    • creation date (ddmmyyyy)
    • (disclosable) salt for instantiate2
    • (disclosable) amount_due : coin (amount, denom)
    • (disclosable) payment_due_date: timestamp
    • (disclosable) odp_contract_addr: (from step 1)
  3. Supplier submits ODP VP (derived from step 2 ODP VC) onchain to notarise, the ODP VP will disclose

    • (disclose) salt for instantiate2
    • (disclose) amount_due : coin (amount, denom)
    • (disclose) payment_due_date: timestamp
    • (disclose) odp_contract_addr: (from step 1)
  4. notary verification passed, SPV orchestrator (recieves postverexec: output_ver / input_ver which is the VP) use instantiate2 to create the ODP Verified Object, SPV orchestrator checks that odp_contract_address is the correct one for the instantiate2 calculation. Populate with:

    • buyer VAT: string
    • amount_due : coin (amount, denom)
    • payment_due_date: timestamp
  5. the ODP Verified Object will need to store in state

    • (static) buyer VAT: string -(static) amount_due : coin (amount, denom)
    • (static) payment_due_date: timestamp
    • (Updatable) owner supplier address

Notarised ODP Contract

This smart contract is instantiated by the Orchestrator post notary verification.

The purpose of this contract is to provide metadata to the owners of the PTs. PTs are issued based on the underlying ODP that this contract represents.

If the ODP is for 10,000 Euros, there will be 10,000 x 1000 mPTs issued. i.e. 1 mPT = 0.001 Euro.

States

status

Current status of the ODP

Type: Enum - Notarised, Issuance Requested, Issued, Matured, Redeemed, Default

This can only be updated by the ODP Admin.

State Transitions

stateDiagram-v2
[*] --> Notarised: `MsgNotarise`
Notarised --> IssuanceRequested: Updated by SPV on price match
IssuanceRequested --> Issued: Issuance Request accepted by DSD
Issued --> Matured: `maturity_timestamp` is reached
Issued --> Redeemed:  `PT` holder(s) are paid
Matured --> Redeemed: `PT` holder(s) are paid <br /> post maturity
Matured --> \Default: Assurance reserve kicked in

odp_admin

The admin address for this ODP contract. This address does not have to be the owner of the ODP itself. This address can update the status of the ODP.

Type: Address

owner

Current owner of the underlying ODP

Type: Address

balances

A mapping of PT holders and the number of PTs they hold. PT by default is in the unit of mPT (milli PT)

Type: Map - Address -> uint256

value

The value of the underlying ODP. In the case of e-Invoices, it is the recievable amount.

Type: coin{ "denom": "EUR", "amount": 10000 }

maturity_timestamp

The date when the ODP matures. In the case of e-Invoices, it is the due date of the invoice.

An ODP state will change by endblocker hook to Matured if the maturity_timestamp is reached. This timestamp is feed in as epoche seconds as part of the input for notarisation.

Type: Expiration - a cosmwasm type with timestamp

notarised initiator

This is the address of the supplier who initiated this process. This is forwarded by the notary module.

Type: Address

Messages

Queries

Orchestrator

This is the SPV orchestrator as a placeholder for now to instantiate notarised ODP contracts.

Business Process

Actors

Supplier

graph LR;
ob[onboarding]-->b2g[B2G e-invoice]-->not[notarisation]-->neg[negotiation]-->co[cashing out]

Buyer

graph LR;
ob[onboarding]-->b2g[B2G e-invoice]-->not[notarisation]-->pay[pay]

Investor

graph LR;
ob[onboarding]-->or[onramp]-->invest[invest]-->div[divest]-->offr[off ramp]

FT Fund

OnBoarding

B2G e-invoicing Process

  1. B2G e-Invoicing Process

Notarisation

  1. e-invoice Notarisation

Negotiation

Cash out

Pay

On Ramp

Invest

Divest

Off Ramp

Onboarding

Jump to specific onboarding processes

The general purpose of onboarding is to:

  • gather information (for checks and archival)
  • facilitate and store digital signatures (to verify formal agreements, declarations)
  • facilitate and record keep 3rd party service provider verification (KYC / AML / etc)

The process of onboarding ends with issuance of verifiable credentials to the users. Depending on the role, different information / process may be performed in order to issue one or multiple verifiable credentials.

There are 2 types of verifiable credentials onchain:

  1. Identity: This is required for all transactions
  2. Invoice Notarisation: This is required to notarise eInvoices onchain, required only by Suppliers

There are 5 role types in Platform-D in terms of onboarding with common prerequisites, aka [Identity Credential]:

  1. Suppliers: eInvoice issuers, the suppliers of goods and services, holds both Invoice and Identity credentials
  2. Buyers: Payers of eInvoices, the buyers of goods and services, holds Identity credential
  3. Investors: The buyers of the securities - DTs, holds Identity credential
  4. Validators: The Platform-D node validators, holds Identity credential
  5. Administrators: The Platform-D authorised administrator accounts (including oracles), holds Identity credential

Identity Credential (Common Prerequisite)

The credential schemas and definitions include:

  1. Derived physical person identity
  2. Legal Person Identity
  3. Power of representations
  4. PeP (politically exposed person)
  5. CFT (Combating the Financing of Terrorism)
  6. Adverse Media (aka Crime)

Supplier Onboarding

Pre-requisites:

  • Platform-D appoints Gayadeed as trusted Issuer, with credential schemas and defs:

    1. Derived physical person identity
    2. Legal Person Identity
    3. Power of representations
    4. PeP (politically exposed person)
    5. CFT (Combating the Financing of Terrorism)
    6. Adverse Media (aka Crime)
  • Platform-D establishes (via Gayadeed) integration with one or more public Notary (ideally one for each district - or via Notartel) for the credit transfer certification via public act.

  • Platform-D set up the supplier on-boarding procedure which includes:

    1. AML/CFT of supplier legal representatives
    2. Mint of NFT smart contract for the supplier (where invoice tokenId will be defined)

Supplier onboards to Platform-D

  1. Gayadeed verifies:
    1. Derived physical person identity (via SPID, CIE)
    2. Legal Person Identity (via Infocamere API)
    3. Power of representations (via Infocamere API)
    4. (in case of joint powers) Repeat the process for any other legal representative
    5. PeP+CFT+AM (via Sefin API)
    6. Financial Suitability Questionnaire
    7. ML Questionnaire
  2. Supplier signs Platform-D agreement with attachments with FEQ. These includes:
    1. Public Notary of reference
    2. Fees acceptance
    3. Terms of Service (using the wallet, etc)
    4. Prospectus (DT)
  3. Supplier onboards with Fabrick for Open Banking API. The purpose of this is to
    1. allow Platform-D API to query their accounts incase of Buyer wrongly deposited
    2. allow user to display their balance

Buyer Onboarding

Investor Onboarding

The onboarding of investors includes the following steps:

  1. The initial onboarding (KYC / AML / T&C) that is required for all roles
  2. The onboarding of financial suitability test
  3. The creation of escrow account in Fabrick (Banking Partner)
  4. (When wanting to invest) they top up of Euro Credits.

Context: the concept of Euro Credits is only valid before a stable coin

2. Create Escrow Bank Account

This step is a redirect from the Platform-D webapp user flow to the partnering Fabrick bank's UI for account creation.

3. Top Up Euro Credits

This is an Oracle MINT action, see Fiat Payment for other Euro Credits actions

flowchart TD
    Investor -- Invest Fiat --> Bank
    Investor --Invest Crypto --> o(Onchain Account)
    o -- Offboard --> c(CEX)
    Bank --> e(Fabrick Escrow Account)
    c --> e(Fabrick Escrow \n Segregated Account)

    e -- Emits Events ---Oracle
    Oracle -- Mints Euro Credits --> Protocol

Investors are presented with the correct information to fund their own Escrow account which they created in Step 3.

B2G e-Invoicing process

actors:

  • Supplier: a private or public administration company incorporaed in italy
  • SDI (Sistema di Interscambio - Data Exchange system): back end service managd by a company named SOGEI on behalf of the Italian Ministry of Finance
  • Buyer: a public administration company incorporated in italy
  • Agid: italian competent authority for the e-invoicing specs
  • e-invoicing intermediary: a third party private company offering web services to facilitate E-INVOICE management (preparation, digital signature, sending and receiving messages through the SDI)

e-invoicing process high level overview

sequenceDiagram
    Supplier->>Supplier: prepares and signs E-INVOICE
    Supplier->>SDI: sends signed E-INVOICE
    SDI->>SDI: verifies E-INVOICE and create metadata
    SDI->>Buyer: sends E-INVOICE and metadata
    SDI->>SDI: prepare and signs RECEIPT OF FILE DELIVERY TO RECIPIENT
    SDI-->>Supplier: sends RECEIPT OF FILE DELIVERY TO RECIPIENT
    Buyer->>Buyer: E-INVOICE formal and busness internal cheks
    Buyer->>SDI: senda CUSTOMER NOTIFICATION OF OUTCOME (acceptance or rejection)
    SDI->>Supplier: senda CUSTOMER NOTIFICATION OF OUTCOME

type of messages and formats:

E-INVOICE and metadata

B2B E-INVOICEs are XML files complying to the "FatturaPA" format and always requires Qualified Electronic Signature.

The Signature may of two alternative types:

  • (XAdES) XML Signature (the signature is included in the XML)
  • (PAdES) P7M Signature (the signsture is external to the file and both the file and the signature are wrapped in a mime-type envelope)

notifications

notifications are xml files complying to the Data Exchange System Specigifations

Notifications types that are relevant for platform-d are:

  • RECEIPT OF FILE DELIVERY TO RECIPIENT (see par. 1.2 of the specs): attests the succesfull delivery of the E-INVOICE to the buyer. It includes a digital signature by the SDI.
  • CUSTOMER NOTIFICATION OF OUTCOME (see par. 1.5 specs): attests the formal acceptance or rejection of the E-INVOICE.

E-INVOICE examples

ToDos

  • add the case where the outcome isn't receinved: in this case the time ut notification is mandatory (in order to avoid a negative result, hidden by the supplier plus forgery of buyer identity)
  • add another type of notification as required (in case of lacking of the outcome)
  • if either the outcome or the timeout notificaiton aren't presented by the supplier, the notarisation cannot proceed
  • add checking via AISP account that the e.invoice hasn't been paied at time of notarisation and negotiation

eInvoice Origination

This is the process that is required to collect all the required data, documents and required signatures for a trusted issuer to issue the Invoice Notarisation Credential.

PT Notarisation Dossier Type

This is a specific Dossier Type provided by Gayadeed. The overall process is as such:

sequenceDiagram
    Supplier->>Gayadeed: create PT Notarisation Deed
    Supplier->>Gayadeed: Select Buyer and upload invoice and notification
    Gayadeed->>Buyer: invite to participate and sign
    Buyer->>Gayadeed: Log in and perform Identification
    Buyer->>Gayadeed: review documentation and sign (QES) CTA Letter
    Gayadeed->>Supplier: invite to sign
    Supplier->>Gayadeed: review and sign (QES) CTA Letter

Invoice Origination Data Package

graph LR
    dtdp[Invoice Origination Data Package]
    dtdp --> einv[signed eInvoice]
    dtdp --> not[signed notification]
    dtdp --> ctal[Mutually signed CTA Letter]
    dtdp --> ctalmd[CTA letter metadata]
    dtdp --> md[einvoice metadata]
    dtdp --> gd[Gayadeed verification metadata]
    md --> amount
    md --> suppVat
    md --> buyerVat
    md --> expiryingDate
    md --> issuingDate
    md --> progressNumber
    md --> originalBankAccount
    ctal --> supplierDateOfSigning
    ctal --> buyerDateOfSigning
    ctal --> paymentlink
    ctal --> newbankAccount
    ctal --> PaymentDate
    gd --> auditTrailID
    gd --> auditResult

Credit Transfer Authorisation Letter (CTA)

This is a PDF document, once signed by both the Supplier and the Buyer with a QES, the Buyer:

  • formally certifies that all the attachment provided are correct (einvoice and notification)
  • formally certifies the existence and the validity of the credit in regards to the e-invoice
  • formally authorises the Supplier to transfer the credit
  • formally acknoledge to pay its debit at maturity, via the payment link provided
  • formally accept all the terms and conditions applicable in case of delayed payment

the CTA letter is signed through Gayadeed, assuming that both the Supplier and the Buyer succesfully completed their onboarding on Platform-d

Open Issues

  • Credit assignment by the public administration (PA) requires:
    • Explicit acceptance by the PA (need to on-board the list of one or more Signatories from the Buyers).
    • The form of a public deed or private contract between the parties, authenticated by a public notary (Gayadeed may be inlcude signature by a public notary - can this be a PAdES-T signature?))
  • eInvoice Acceptanceby the Buyer via SDI is
    • Optional
    • May arrive within 15 days from the delivery
  • In case the acceptance ntification isn't produced by the Buyer, the SDI automatically notifies the supplier with a meet of the deadline notificatoin
  • eInvoice explicit Acceptance Deadline expiration does not determine implicit acceptance of the debt by the PA
  • Supplier-side signature powers: how to determine them automatically (Chamber of Commerce "Infocamere" API)
  • Buyer-side signature powers: how to determine them automatically? (API Infocamere?)
  • How to prevent double spending of the invoice (Air protocol + optional "Notes" field of the electronic invoice containing references (did) to the NFT smart contract for the supplier in question)

DSD

DSD Onchain Services

DSD Main Contract

*MFT

Interaction with the x/tokenfactory and x/orderbook

Initially ODP related PTs are not fractionised, i.e. investors must buy and sell PT equivalent to the entire e-Invoice.

DSD Offchain Services

Oracle

Reporting

Testnet Theodoric-II Scope

Overview

Theodoric-II is the testnet of dchain.

Recap of Theodoric-I

In Theodoric-I, we tested the following features.

Theodoric-II Scope

Building on the SSI-enabled validator onboarding, 2 layers governance and decentralisable verifiable credentials issuance, Theodoric-II will focus on the following features:

  • Tokenomics: The burning and minting of DTs is designed to provide supported applications with a predictable cost and to provide DT holders with security lending rewards that aligns with the success of the network.

    • Minting: The rewards schedule is designed such that DT reaches a maximum supply of 100 billions DTs. The testnet will start wit 80 billions DTs and simulate an accelerated schedule for unlock, minting and reward reduction.
    • ** Burning**: The burning of DTs will be tested by platformD application.
  • Abstract Account: Allow users to sign up and complete onchain transactions with webauthn.

  • Staking: Using abstract account to complete staking related transations

  • Governance: Voting in the governance on Dchain. In order to vote, requires staking DTs AND valid verifiable presentation as part of the voting transaction. Vaildators have the voting power proportional to their own staked DTs only, delegated DTs can only be used to vote by the delegators themselves.

  • platformD initial end-to-end flow: The initial end-to-end flow of platformD application will be tested on Theodoric-II. This includes burning of DTs as part of the utilities fees of using modules on Dchain.

Testnet users onboarding

Initial account creation (pre-genesis)

sequenceDiagram
    autonumber
    actor dh as DT holder

    participant kc as Keycloak
    participant be as platformD Backend
    participant Dchain

    dh ->> kc: create new account (with webauthn)
    kc ->> be: event hook (account created)
    be ->> be: predict proxy contract address
    be ->> kc: update user with contract address
    note over be: batch create vesting <br /> create proxy with authenticator contracts
  1. In the testnet we will allow user to just go to demo.platformd.io and create a new account. We can do this by allowing self-registration in keycloak. We will ask for email and require webauthn registration, we can ask for password if we want, but must have webauthn. See the setting of the keycloak realm for just webauthn and no password.

  2. When the account is created, we want to have a hook to call the backend to predict the proxy contract address. It looks like some sort of java event listener is needed. I asked grok and I think its pretty standard. Here is an example I found.

  3. The backend that gets called will predict the proxy contract address. This actually requires a few things.

    • We need to assume an "platformD admin" dchain address that will deploy the proxy contract, a salt (which we need to store to make sure we use the same one when we create the proxy contract), and I think we also need to have the code id and also the message? (check out Instantiate2 logic, I think we can use fix_msg option to make it independent of instantiation message?), see x/abstractaccount/keeper/msg_server.go l:75
  4. Update keycloak with the new address. We want the frontend to have such address in the jwk to pull balances in the future.

@Andrew: here are some previous work that you should checkout before implementation:

  1. The backend can in fact get the credentialData from Keycloak user data. I did it in rust here
  2. This credentialData should be the correct data to be used in the proxy authenticator, some details on this:
    • As a reference ONLY (vectis has changed significantly since we wrote this webapp) - We directly used the browser to create the credential here, not keycloak. but insteaof using this.navigator.credentials.create, I expect keycloak will do all that and store the AuthenticatorAttestationResponse in the credentialData field of the user. Keycloak should be storing the same data the type from MDN Reference.
    • You can see the end to end flow of using the passkey-cli to create a credential and then use that to sign a challenge - the challenge being the hash of the bytes from the cosmos transaction in the test here

Software Components Selection

Platform-D Chain

IBC

Identity

Application Specific Blockchain Stack

Platform-D is built on Cosmos-sdk with consensus by CometBFT & smart contracts framework by CosmWasm.

Modules and Smart Contracts

Cosmos-sdk is the application layer of a blockchain node and communicates with the underlying networking and consensus layer - CometBFT. As the name suggests, it is a SDK and applications can add modules to it to interact with the states.

One notable module that any application specific blockchain can add is x/wasm. It is a Cosmos-sdk module that contains the Go binding (wasmvm) to the underlying CosmWasm-VM, which rus the CosmWasm smart contracts.

Given there are now 2 ways to customise functionalities on the blockchain, the design decision is where should such business logic lie for flexibility and efficiency.

Flexibility

One of the advantages of using CosmWasm over other smart contract frameworks is the ability to reuse other libraries written in rust (with some limitatiosn), in particular - many high quality cryptographic libraries.

Another way to reuse other libraries / keep up with newest development from the wider developer communities is to be able to load WASM code in the blockchain node. At the time of writing, WASM loader is not available in the runtime of Cosmos-sdk. However, in the 2024 roadmap the contributors include both cross language WASM loader & exploring alignment with CosmWasm.

With all these developements, the initial MVP of Platform-D will align with the Cosmos-sdk roadmap, it will be flexible by incorporating the x/wasm module.

It is important to note the EVM runs bytecodes that are customised, is very restrictive in its instruction and memory that makes it very difficult to write safe, efficient smart contracts. In addition, applications must be specifically built for the EVM, making it impossible to leverage external libraries outside of the ecosystem.

Efficienty


Last updated: Belsy Yuen, 28-11-2023

Inter-Blockchain Communications (IBC)

One of the primary advantages of building the Platform-D on cometBFT, cosmos-sdk & CosmWasm is the native support for IBC protocol, which is a trust-minimizing and permission-less solution for interoperability bridge.

IBC minimises third-party risks

Bridges with centralised third parties

Most bridge solutions requires a trusted third-party to relay messages between chains and/or to onboard a new chain. This is a valid solution for specific use cases, notably Circle's Cross-Chain Transfer Protocol, which requires Circle as an entity must be the only master minter of USDC. This means that:

  1. Chain Onboarding: Circle is the only entity that can add a new chain to the CCTP ecosystem
  2. Permission and Trust: Circle is a centralised entity to "burn/lock & mint" from one chain to another

It is also worth noting that there is a trusted implementation of IBC by using a centralised / multisig Light Client Proxy verification with [TEE] offchain then using the TEE to submit the verification onto another chain. There is ongoing project with this method for Cross-Chain settlement of Stable Coin with banks in Japan.

Permissionless and Trustless bridging

However, outside of the stable coin application, it is important to minimise third-party risks when it comes to chain interoperability. IBC allows for each implementing chain to verify the light client of the other, via cryptographic proofs; these proofs can be submitted onchain by anyone and will not depend on the bridging entities.

If the states proofs are incorrect, e.g. the client hash does not reflect the previously accepted one, then the submission will fail, therefore finality is set. Because of the design of the consensus algorithm implemented in cometBFT, finality is provided per block and therefore the updates that are required on the remote chain light client is final.

IBC allows for normal users of either chain to run a stateless IBC-relayer, implemented in different languages and maintained in open-source (hyperspace-relayer, ts-relayer, hermes (rust), cosmos/relayer (golang), yui/ibc-relayer), to submit state updates from one chain to another chain. In simple terms, as long as the chains themselves are considered trusted (e.g. requires verifiable credential, decentralised, has qualified validators, etc), then interoperability via IBC minimises third-party risks.

Proven Technology across multiple ecosystems

IBC is a proven technology with ~70 Cosmos-sdk based chains already connected and over [25B USD transacted] with no , others are being developed / used described below:

ProjectsTarget EcosystemDetails
Polymer LabsEthereum
UnionEthereumzkIBC proof of ed25519 curve (consensus) verification, not state transition
Electron LabsEthereum
LCP - Light Client ProxyEthereumOffchain [TEE] for light client verification & ibc-solidity contracts on EVM chains
Hyperledger Fabricyui-fabric-ibc
Cordayui-corda-ibc
Ethereum[yui]
LandslideAvalanch SubnetA subnet in Avalanch ecosystem building on the forked Tendermint consensus
Composable FinancePolkadot / KusamaUnique project bridging Polkadot & Kusama with IBC-substrate Pallet
PolkadotProduction
Ethereum(Testnet)
SolanaIn development

IBC on Platform-D

Platform-D is an application specific chain that runs the business logic and has qualified validators to validate and replicate state change. For external settlement or interoperability, i.e. if we want to consider Platform-D states to also update states on external blockchains for any reason, or would like to interact with other blockchains, Platform-D can either utilise [TEE] for IBC verification (where it requires existing validators to verify), or have the out-of-the-box IBC module in cosmos-sdk to interact trustlessly with the various open-source relayers.

It is worth noting that any external state updates via IBC on Platform-D also follows that same requirements as any transactions, i.e. only those with verifiable credentials.


Last updated: Belsy Yuen, 28-11-2023

Verifiable Credentials

W3C

sd-jwt

AnonCreds

Background

Some notes on how some of the modules work in Cosmos-SDK which is used in D-Chain.

Standard process flow diagrams

(NOT D-Chain specific)

Delegations Flow (cosmos-sdk v0.50)

sequenceDiagram
    participant Delegator
    participant Validator
    participant OtherNodes as Other Nodes
    participant Consensus as Consensus Engine
    participant Staking as x/staking
    participant Slashing as x/slashing
    participant Distribution as x/distribution
    participant Mint as x/mint
    participant Auth as x/auth

    Delegator->>Staking: Delegate tokens
    Staking->>Validator: Update stake

    loop Each block
        Mint->>Auth: Mint new tokens
        Auth->>Distribution: Transfer minted tokens + fees
        Distribution->>Distribution: Calculate rewards
        Distribution->>Validator: Distribute validator rewards
        Validator->>Delegator: Distribute delegator rewards
    end

    rect rgba(0, 0, 0, 0.1)
        Note over OtherNodes,Slashing: Evidence Submission
        OtherNodes->>Slashing: Submit double signing evidence
        Consensus->>Staking: Report missed blocks
        Staking->>Slashing: Check for downtime at end of window
    end

    rect rgba(0, 0, 0, 0.1)
        Note over Slashing,Distribution: On valid evidence
        Slashing->>Validator: Slash
        Slashing->>Distribution: Update rewards
    end

    Delegator->>Distribution: Withdraw rewards
    Delegator->>Staking: Undelegate tokens

    rect rgba(0, 0, 0, 0.1)
        Note over Staking,Distribution: Governance can adjust parameters
    end

Minting Flow (cosmos-sdk v0.50)

sequenceDiagram
    participant Mint as x/mint
    participant FeeCollector as Fee Collector<br/>(x/auth)
    participant Distribution as x/distribution
    participant Validators
    participant Delegators

    rect rgba(0, 0, 0, 0.1)
        Note over Mint,FeeCollector: Minting and Fee Collection
        Mint->>FeeCollector: Mint new tokens
        Note right of FeeCollector: Minted tokens sent to<br/>fee collector account
        activate FeeCollector
        FeeCollector->>FeeCollector: Collect transaction fees
        deactivate FeeCollector
    end

    rect rgba(0, 0, 0, 0.1)
        Note over FeeCollector,Distribution: Distribution Process
        Distribution->>FeeCollector: AllocateTokens()
        FeeCollector-->>Distribution: Transfer all balances
    end

    rect rgba(0, 0, 0, 0.1)
        Note over Distribution,Delegators: Reward Distribution
        activate Distribution
        Distribution->>Distribution: Calculate rewards
        Distribution->>Validators: Distribute validator rewards
        Validators->>Delegators: Distribute delegator rewards<br/>(minus commission)
        deactivate Distribution
    end

Primary Market Orderbook

There is a 2 steps process for creating a sell order on the orderbook by the supplier.

  1. The supplier signs and expresses the slippage (percentage) and limit order on discount
  2. The offchain oracle - supported by the risk calculation engine approves / declines the the order

For users of the orderbook, When adding their orders to the orderbook, they can define slippage (percentage) and limit order (acceptable discount / yield) depending on their circumstance.

Platform-D Orderbooks

At the MVP stage we will implement a module that is the CLOB and will use EndBlocker execute all market orders / matching orders in the same block for DTs in a FBA way.

State

Messages

Keeper

Params

Design references: the state-of-the-art

There are several blockchains in the Cosmos Ecosystem that are designed for fast trading with orderbooks, as they are state-of-the-art, we will summarise their innovation and what Platform-D has for its MVP.

The below are all Central Limit Order Book (CLOB).

ProtocolCometBFT featuresFBAAdditional Info
dydxUpcoming: uses ExtendVote for validators to collaborate to agree on block (instead of just single proposer)FBA for all the trades in the block (voted in in the previous block)Orderbook is offchain in memory and managed in the CLOB in the sdk
Sei- Optimistic Block Processing
- Intelligent Block Propagation
FBA for all market orders in the same block for the same orderbookAt EndBlocker hook, all market transactions go through the DEX module as the main order matching engine (including FBA)
InjectiveN/AAt EndBlocker hook, transactions in the Exchange module are matched in FBA fashion

x/wasm

This module supports CosmWasm smart contracts.

Introduction

There are much information around CosmWasmo on the internet, here is a simple summary to provide some very high level overview of what is under the hood.

The overall design is as such:

  • wasmvm: This is the Go code that imports cosmwasm-vm via cgo
    • cosmwasm-vm is compiled lib (.so, dylib, .dll, .a) to be linked via cgo
    • The APIs for this is in internal/api
  • cosmwasm-vm: This is written in rust uses wasmer embedded runtime to run the CosmWasm smart contracts

NewApp

When the node starts, along with creating all module keepers, the wasmKeeper is also created.

This calls [newVM] which creates cosmwasm VM which has the wasmer engine, the runtime for the CosmWasm contracts.

This VM is used for the execution / code store / query etc.

Transaction flow

On StoreCode the wasm file is compiled (into executable code). Both the original wasm and the executable code are stored.

When there is a transaction to execute, a contractInstance is created by loading the existing contract state / code. Contract address and other relevant info along with prefixStore for that contract are then passed into the C code compiled from cosmwasm-vm for Execute in wasmvm -> CosmWasm-vm via the cgo import.

WebAuthn

Background

The is a tech follow-up on the discussions we have had is around is a user allow to create more than a single account with Vectis on the same device / foundational ID.

Given the current flow in Onboarding, the flow of creating a webauthn credential happens BEFORE any account is created, this means that in the PublicKeyCredentialCreationOptions, that the PublicKeyCredentialUserEntity has a randomly generated id.

This id MAY be used in authentication, i.e. when the user Login, or in our case, signs a transaction, we can leave the CredentialDescriptor empty. In the [discoverable credential] model (which we are using), this means that the passkey are returned for all the credentials relevant to our rpID.

On the other hand, if Login requires interaction with a Vectis API, i.e. in the case to unlock for VC, then, it is possible to request a specific id that was created in Onboarding.

This method does not prevent creation of multiple accounts, unless we have get or create type api available, however, this is still only in discussion.

Example

ICP has a good example that we need to upgrade to, getting the credentialID so there will only be 1 credential you can login with, even if you have created a few different accounts (given you entered the correct id).

Platform-D Glossary

Foundation

The entity that is the foundation in Platform-D

Notarised Invoice

eInvoices that are notarised on the Platform-D chain.

DT

The native govenance tokens for Platform-D

PT

Securities token

Verifiable Credential

(TODO) Digital credentials that are cryptographically proven to be issued by a party.

Verifiable presentation

A verifiable presentation derived from the verifiable credential

Invoice Notarisation Credential

This is the verifiable credentials issued by a Trusted Issuer that are used to verify that the offchain-collateral of the eInvoice had been checked and are valid. The offchain-collateral [DT Data Packet]

Identity Credential

This is the verifiable credentials issued by a Trusted Issuer that are used to derive proof presentation for interacting with Platform-D upon doing KYC & AML checks.

Trusted Issuer

Any Platform-D appointed trusted issuers - such as [Gayadeed], will be able to issue [verifiable credentials] that is recognised by Platform-D systems.

Pratically speaking, this means that the issuers' DID document (Public Keys) are made available onchain.

DT Data Package

This is a data package that is comprised of artifacts required for a trusted issuer to issue a verifiable credential that is used in the notarisation process of the electronic invoice to an onchain [invoice] instance.

The data must contain:

  • Supplier signed (Qualified Electronic Signature) invoice with machine readable data
  • Notification of acceptance (of credit transfer)

(To be completed)

SSI driven consensus with RWA (Invoice) staking

Background and motivation

Invoices are assets that do not create yield. We want to change that.

See flow diagrams for processes

Design perimeter and assumptions

There are the native staking bonding_denom that is DT. To avoid creating another token which complicates the system and divert values from DT, which should represent the security of the network, we have decided to translate invoices into DT for the purpose of staking.

However, there are very distinct differences between staking DT and staking invoices. This is because the expected risk and reward are different.

Considerations specific to invoice staking

  • Invoice value are in fiat (Euro) and must be paid in fiat via the banking system of choice
  • Suppliers and Buyers are not necessarily DT holders
  • Suppliers are expected to take risk on the yield derived from invoice staking, which would have been zero if not staked anyway

Distinction between DT and invoice staking

DT stakingInvoice stakingRationale
HoldingsAlready holds DTNotarising invoices which are translated into staked DT, cannot transfer invoice derived DTinvoices -> DT is allowed for the purpose of providing security service to the network, it is not an exchange between assets
DelegateDelegate desired amount of DT to validatorNotarise invoice and all minted DT are by default stakedWe cannot allow partially staking of invoices, the full face value of the invoices must be fully staked, but it can be delegated to different validators
Expected RisksDT rewards rates vs Slashing of validatorNo slashing of invoice face value, only on rewardsSuppliers is providing their invoices as a service for the security of the chain, their risk is on the potential yield (i.e. service fee) and not the actual invoice value
RewardsReward rate depends on the inflation and desired bonding ratio minus validator commissionRewards are shared between supplier and validator node (and therefore the delegators)Since there is no unbonding period or slashing of the face value, rewards are shared between the validator and the supplier
Reward distribution & collectionReward distributed and collectable at every blockReward distribution and collection on invoice payment onlyThis prevents invoice default or fraudulant invoices minting DT rewards
Unbonding PeriodChain unbonding periodstaked DT can have unbonding period, rewards will be distributed following unbonding decisionSecurity of the network is reflected by the value of the assets staked, if the invoice has been paid, the staked DT must at least be unbonded then burnt or burnt immediate, see section below for details
UndelegateCan undelegate DT and withdraw after unbonding periodCannot undelegate invoice derived DT, only exit when buyer paysDT derived from notarised invoices are not transferable, they are minted on staking and burnt on payment, reflecting the ownership and asset value of the invoices on chain

* This point must be carefully analysed, unbonding period is there to:

  • prevent short range attacks (double spending) where validators can be slashed during the unbonding period
  • ensure the stability of the network (prevent sudden changes in the validator set)
  • ensure "skin in the game" for validators and delegators (prevent vote and exit, quickly unbond to validate another network) scenarios

Economic model and financial incentives

Suppliers (Invoice issuer)

On completion of the goods or services delievered to the Buyer, the invoices become an asset on the balance sheet of the suppliers - account recievable. However, there are no ways to derive any yield from this asset.

There are a few incentives for the suppliers to stake their invoices:

  • Service Fee: By providing the option for staking the invoice, the supplier is able to derive service fees (yield in DT). It must be designed such that suppliers do not put their assets at risk (Buyers are still liable to pay the invoice via traditional banking services or in the near future - regulated stable coins). The yield the network provides compensates for the the service the supplier provides to the network - security.
  • Speed of payments: D Chain should be encouraging buyers to pay early in order to attract suppliers. A early payment bonus (defined by params) is a feasible solution
  • Other services: Notarised invoices are a proof of the transaction between the supplier and the buyer. This can be used for other services - discounting via Platform-D DApp
  • DT rewards: Suppliers invoice staking service fees are paid in DT which will supplement their future transaction on D Chain, also allowing them to also stake their DT for additional yield

Buyers (Invoice payer)

Buyers are not directly involved in the staking process however, there are benefits for them to be involved:

  • Early Payment Bonus: the system encourages faster payments by introducing an Early Payment Bonus to the buyers with a set params of invoice notarisation date
  • Better offers: suppliers knowing that the buyers can provide track record (of payments) and that are willing to allow them to use their invoices (on DChain or other services) will be more likely to provide better offers (e.g. discounts, better payment terms, etc.
  • Other services: Buyers can may use other services, such as be investors on Platform-D DApp, which supplies their treasury with high quality short term assets

Validators

Validators are not directly incentivised or involved by invoice staking, however, they may benefit from:

  • invoice notarisation transactions bringing more fees to the network
  • self-delegation (see next section)

Delegators of DTs

Delegators of DT has more risk than invoice stakers:

  • has to wait for unbonding period
  • can be slashed

However, they are also able to be more flexible in their stakin:

  • deciding on unbonding date
  • collecting rewards at every block

They must be rewarded better than the invoice staking of the same amount of DT

Immediate or unbonding period of invoices?

Given that the unbonding period is actually introduced for security measures, we can keep that for invoices.

Pros:

  • gives a chance for the reward to be slashed (so that other delegators are not as affected)
  • delays reward distribution to supplier
  • follows the protocol of normal DT staking
  • no extra voting power when unbonding
  • no need to discount total voting power because it follows the same protocol as normal DT

Cons:

  • delays reward distribution to supplier (from supplier point of view)
  • the invoice no longer exist, we are just delaying the burn (which can be a good thing)

Point of Considerations:

  • when tokens unbond, the voting power of the validator decreases but everyone elses increases
  • during unbonding period, the unbonded tokens can still be slashed
  • during unbonding periods, the tokens are already inactive, removed from total active staked
  • during unbonding period, voting not allowed
  • the rewards are not distributed to the unbonded tokens

Non-Slashable invoice face value staking

Regardless on unbonding or not The problem of Non-Slashable invoices causes an inbalance in the system, where native DT stakers will have to pay for the slashed amount.

Example

Let's consider an example without yield for now.

  • Block H: Total active staked = 100, 000 - Buyer pays, invoice DT tokens are unbonds (10,000) (this is fine because it will just be burnt after unbonding period)
  • Block H + 1 : Total active staked = 90,000, unbonding is 10,000
  • Block H + 10 - Validator gets slashed for double sign at Block H - 10 (when invoice DT were still actively staked), penalty is 5%. Total active staked at validator is now 90,000*0.95 = 85,500 and total unbonding is 10,000*0.95 = 9,500
  • Block H + unbonding-ends - 10,000 tokens must be burnt but only 9,500 tokens are available, the remaining 500 tokens comes from the actively staked pool, i.e. remaining is 85,000. The remaining delegators has additional stash of 500/85500 = 0.58% of their tokens.

In this case, the reward pool must lock in the potential reward on the invoice DT portion because it might not be distributed if the invoice is not paid. Once it is paid, then the reward is split between the supplier and the shares in the validator (delegators)

This scenario breaks down when the validator does not have sufficient total active staked DT from normal staked DTs (NOT invoice derived DTs). Imagine the scenario that (if there are zero rewards, or rewards is less that 405/10000 = 4.05% of the total staked DTs)

  • Block H: Total active staked = 10, 100 - Buyer pays, invoice DT tokens are unbonds (10,000) (this is fine because it will just be burnt after unbonding period)
  • Block H + 1 : Total active staked = 100, unbonding is 10,000
  • Block H + 10 - Validator gets slashed for double sign at Block H - 10 (when invoice DT were still actively staked), penalty is 5%. Total active staked at validator is now 100*0.95 = 95 and total unbonding is 10,000*0.95 = 9,500
  • Block H + unbonding-ends - 10,000 tokens must be burnt but only 9,500 tokens are available, the remaining 500 tokens comes from the actively staked pool, but only 95 are remaining.

The following graph shows the yield of a specific case where

  • 100,000 DT are staked, 10% yield applied, 5% slashing, 0% commission
  • ratio of those DTs are invoice derived (x axis)
  • yield of the delegators relative to the total staked invoice DTs (y axis)
  • part of the yield is split between the supplier and the validator (delegators)

See data here

Fund Limit Pricing Engine (FLPE)

(It is basically yield curve +/- some)

Rational behaviour of the normal investor Looking at the pile of cash behind

Fund puts limit pricing that balances requirement for attracting its investors and then buying the supply.

Burner Wallet & Vectis

Wallet address and sd-jwt can both be one use to minimise correlation.

Currently Vectis Factory only allows a wallet creator to deploy wallet contracts. This is important because the process of KYC / AML is done when there is an account creation.

However, if we decouple this process of KYC / AML (and issuing a VC) to the user wallet, before an onchain account is created, then it is possible to allow users to create their own wallet if and only if they have the a valid credential presentation.

Oracle Providers

Discussion

Platform-D Webapp Login with OID4VC to support multiple wallets

see Northern Block demo for more context. Use their wallet for best results

Sequence Diagram

sequenceDiagram

    autonumber

    participant Platform-D API (Gayadeed)
    participant Platform-D Webapp
    actor Vectis Wallet

    participant Vectis API
    participant Gayadeed API/DB


    Note over Vectis Wallet: User Logged in (has Gayadeed token)

    Platform-D Webapp ->> Vectis Wallet: Request VP on Vectis iframe
    Vectis Wallet ->> Vectis Wallet: Approve request
    Vectis Wallet ->> Vectis API: Request VP with Gayadeed token
    Vectis API ->> Gayadeed API/DB: Request: VP with Gayadeed token
    Gayadeed API/DB ->> Gayadeed API/DB: Derive VP
    Gayadeed API/DB ->> Vectis API: Response: VP token with presentations
    Vectis API ->> Vectis Wallet: VP token with presentations
    Vectis Wallet ->> Platform-D Webapp: Response with VP token
    Platform-D Webapp ->> Platform-D API (Gayadeed): Request to verify VP
    Platform-D API (Gayadeed) ->> Platform-D Webapp: Approved and with token and user data

For step 2: Please see [Nortern Block demo] to show requested data

Verifier Request VP

Example QR code for requesting verifiable presentation:

openid-initiate-issuance://?
issuer=https://agent.openid4vci.nborbit.io
&credential_type=Gym Membership
&pre-authorized_code=
4688babc-5025-458a-91bb-b915c7a1d150.8068ef1d-07b7-4e30-8604-b4382489b272.d294fc0b-5ced-473d-8e03-a84e3be66e53