§ Verifiable Public Registry v4 Specification
Latest draft: spec v4-draft21
Latest stable: spec v3
- Editors:
- Contributors:
- Participate:
§ Abstract
Decentralized trust ecosystems need shared infrastructure to answer a fundamental question: who is authorized to issue, verify, or govern credentials in a given context? Without a common registry layer, each ecosystem operates in isolation, trust decisions depend on ad hoc configurations, and there is no interoperable way for Verifiable Services and Verifiable User Agents to resolve the legitimacy of a credential or its issuer.
The Verifiable Public Registry (VPR) is a decentralized “registry of registries” that provides this foundational infrastructure. It allows ecosystems to create and manage their own ecosystems, define credential schemas with fine-grained permission policies, and assign roles — issuers, verifiers, grantors — through a transparent, on-chain governance model.
The VPR exposes a standardized query API that Verifiable Services and Verifiable User Agents use during trust resolution to confirm, in real time, whether a given participant is authorized to perform a specific action under a specific credential schema. This is what makes the trust in Verifiable Trust actually verifiable.
The VPR is DID-method-agnostic — it stores registrations, not validations — leaving trust decisions and cryptographic verification where they belong: with the relying parties. It supports flexible permission management modes (open, ecosystem-controlled, or grantor-delegated), enabling ecosystems to tailor governance to their specific requirements.
This specification defines the data model, API, and normative requirements for implementing and interacting with a Verifiable Public Registry.
§ About this Document
In order to fully understand the concepts developed in this document, you should have some basic knowledge of DID, DIDComm, VS, ecosystem, ledger-based applications, and more generally, all terms present in the Terminology section.
Before exploring this spec, it is highly recommended to first read the Verifiable Trust Spec.
§ Introduction
§ What is an Ecosystem?
This section is non-normative.
An ecosystem is an approved list of recognized participants, such as ecosystem operators, credential issuers and verifiers, that are authorized to onboard ecosystem participants, and or issue/verify certain credentials in an ecosystem.
An ecosystem typically expose APIs that are consumed by services that would like to query its database, and take decisions based on the returned result:
- can participant #1 issue credential for
schemaABC ofecosystemE1? - can participant #2 request credential presentation of credential issued by
issuerDEF fromschemaGHI ofecosystemE2 incontextCONTEXT?
§ What is a Verifiable Public Registry?
This section is non-normative.
A Verifiable Public Registry (VPR) is a “registry of registries”, a public service that provides foundational infrastructure for decentralized trust ecosystems. It offers:
-
corporation lifecycle and directory:
- corporation onboarding, with associated DID and corporation governance framework publication
- multi-member governance via a Cosmos SDK group (members, voting policy, threshold)
- a public corporation directory queryable by indexers, verifiable services, and verifiable user agents
- corporations are the foundational actors of the VPR: they control participants and may themselves control ecosystems.
-
ecosystem management:
- governance framework publication and versionning
- credential schemas publication
- participant onboarding
- custom business models and permission policies
- and more.
-
query API for trust resolution:
A standardized API used by verifiable services (VSs) and verifiable user agents (VUAs) to perform trust resolution, enabling them to query registry data and validate roles and permissions in real time.
Participant directory is intended to be crawled by indexers, which resolve the listed DIDs, identify associated verifiable services, and index them.
Indexers may expose this data through APIs for querying the indexed services or use it to build a search engine for querying the database of indexed verifiable services.
§ Conformance
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative. The key words MAY, MUST, MUST NOT, OPTIONAL, RECOMMENDED, REQUIRED, SHOULD, and SHOULD NOT in this document are to be interpreted as described in BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals, as shown here.
§ Terminology
- account:
- A verifiable public registry account.
- applicant:
- A account that starts a onboarding process.
- corporation:
- A legal/organizational entity that controls Participants in zero or more ecosystems and may itself be the controller of zero or more ecosystems. A
Corporationextends a Cosmos SDK group with VPR-level attributes (DID, governance framework, lifecycle). - corporation governance framework:
- The governance framework (GF) of a corporation.
- :
- The governance authority (GA) of a corporation.
- credential schema:
- An VPR resource which represents a verifiable credential definition and the associated permissions and business rules for issuing, verifying or holding a credential linked to this credential schema.
- credential schema participant:
- A
Participantentry, linked to a credential schema, that represents, in a given ecosystem, a grant for being issuer, verifier, issuer grantor, or verifier grantor of a credential schema. - decentralized identifier:
- A decentralized identifier, as specified in [DID-CORE].
- decentralized identifier communication:
- DIDComm uses DIDs to establish confidential, ongoing connections.
- denom:
- Token that has been configured and is recognized in a VPR, example: uvna, USDC.
- native denom:
- Native token of a VPR, example: uvna.
ecosystem: a network of interacting entities, both technical and human, that work together to establish and maintain digital trust. It encompasses applications, credentials, governance frameworks, and the underlying technical infrastructure, all designed to facilitate trustworthy interactions.
- ecosystem governance framework:
- The governance framework (GF) of an ecosystem].
- :
- The governance authority (GA) of an ecosystem.
- entity:
- An account controller.
- estimated transaction fees:
- Estimated fees required, in denom, that is passed when execute a transaction in an VPR. Usually, a estimated transaction fees are always slightly greater than transaction fees, to make sure the execution of the transaction will not be aborted for an out-of-gas situation. Unused gas is refunded to account.
- governance framework:
- The governance framework (GF) of a VPR.
- :
- The governance authority (GA) of a VPR.
- grantor:
- A role an entity is granted by an ecosystem for operating its ecosystem.
- group:
- The underlying Cosmos SDK group primitive that a corporation extends. Members and policies are managed by the group module; VPR-level attributes (DID, governance framework, lifecycle) live on the corresponding corporation entry.
- holder:
- A role an entity might perform by possessing one or more verifiable credentials and generating verifiable presentations from them. A holder is often, but not always, a subject of the verifiable credentials they are holding. Holders store their credentials in credential repositories. Example holders include organizations, persons, things.
- issuer:
- A role an entity is granted by an ecosystem or an issuer grantor for issuing credentials of a given credential schema to holders.
- issuer grantor:
- An ecosystem operator role an entity is granted by an ecosystem for a given credential schema for adding or revoking issuers.
- json schema
- a Json Schema, as specified in https://json-schema.org/specification.
- keeper:
- A storage map(key, value) in the ledger of an VPR.
- linked-vp:
- A presentation of a verifiable credential as specified in LINKED-VP.
- participant:
- An entity that is recognized by one or several ecosystem(s) in a VPR.
- query:
- A read-only action that perform some reading in an VPR and returns value.
- subject:
- A thing about which claims are made. Example subjects include human beings, animals, things, and organization, a DID…
- transaction:
- An action that modifies the ledger of an VPR and which execution requires transaction fees.
- transaction fees:
- Fees required, in denom, to execute a transaction in an VPR.
- trust deposit:
- A financial deposit that is used as a trust guarantee. For a given corporation, its trust deposit is increased when running onboarding process (either as an applicant or as a validator).
- trust fee:
- Fees paid by a participant that are distributed to other participants.
- network fee:
- Fees paid by a participant that are distributed to network validators and trust deposit holders.
- trust unit:
- A fake denom that is not usable as a token (cannot be transferred, or used for paying in transactions). Trust unit is used to define fees in Permissions. Fees defined in trust units are automatically converted to native denom when a transaction is executed, using an exchange rate
TU/[[ref: native denom]]. Trust unit is used to compensate native denom fluctuation. - ecosystem
- An approved list of participants that are authorized to issue/verify certain credentials in an ecosystem.
- URI
- An Universal Resource Identifier, as specified in rfc3986.
- active participant:
- A participant of a given role, which effective_from timestamp is lower than current timestamp, and (effective_until timestamp is null or greater than current timestamp), and revoked is null and slashed is null.
- future participant:
- A participant of a given role, which effective_from timestamp is higher than current timestamp, and (effective_until timestamp is null or greater than effective_from timestamp), and revoked is null and slashed is null.
- onboarding process:
- A process run by applicants that want to, for a specific credential schema, be a issuer, be a verifier, or simply hold a verifiable credential linked to the credential schema.
- validator:
- A role an entity performs by participating in onboarding processes with applicants in order to register them as issuer, or verifier of a credential schema, or to deliver a verifiable credential to them.
- verifiable public registry:
- a public, normally decentralized, ledger-based network, which provides: ecosystem features, that can be used by all its participants: create ecosystems, for each ecosystem, define its credential schemas, who can issue, verify credential of a specific credential schema,… and a tokenized business model for charging/rewarding participants.
- verifiable service:
- A service, identified by a resolvable DID that can be deployed anywhere by its owner, and that is conforming to this spec and has a resolvable Proof-of-Trust. See VT Spec.
- verifiable user agent:
- A user agent for accessing and using VSs. To be considered a VUA, a user agent must conform and enforce this spec, such as presenting a proof of trust to end user before accepting connecting to VS compliant services, and refuse connecting to not compliant services. See VT Spec.
- Verifiable Trust Specification:
- see VT Spec.
- verifier:
- A role an entity is granted by an ecosystem or a verifier grantor for verifying credentials of a given credential schema.
- verifier grantor:
- An ecosystem operator role an entity is granted by an ecosystem for a given credential schema for adding or revoking verifiers.
- verifiable credential:
- A verifiable credential as defined in [VC-DATA-MODEL].
§ Naming Conventions
§ In this spec
- For clarity, Camel Case is used for naming Modules, Entities, Objects, etc.
§ In Implementations
- All APIs MUST return valid JSON.
- All JSON content MUST use Snake Case for object, attribute… names.
- Object attributes and Json Content in general can be returned in any order.
§ Features of a Verifiable Public Registry (VPR)
§ Ecosystem Management
This section is non-normative.
In an VPR, any corporation can create an Ecosystem entry to represent an ecosystem it controls. Each Ecosystem entry MUST provide, at a minimum:
- an ecosystem controlled resolvable DID;
- one or more ecosystem governance framework document(s);
- zero or more credential schemas.
The Verifiable Public Registry (VPR) is agnostic to the specific DID methods used. Trust resolution is performed externally, outside the VPR, allowing flexibility and interoperability across ecosystems.
§ Credential Schemas and Participants
This section is non-normative.
Credential schemas are created and managed by ecosystems (i.e., by the corporation controlling each ecosystem). Each Credential schema includes, at a minimum:
- A Json Schema that defines the structure of the corresponding verifiable credential.
- An IssuerOnboardingMode for issuance policy, which determines how
ISSUERParticipantentries are created. Modes include:OPEN:ISSUERParticipants can be self-created by any corporation.ECOSYSTEM_ONBOARDING_PROCESS:ISSUERParticipants are created directly by the controlling ecosystem through an onboarding process.GRANTOR_ONBOARDING_PROCESS:ISSUERParticipants are created by one or several issuer grantor(s) — ecosystem operators responsible for onboarding issuers for the credential schema of this ecosystem — selected by the ecosystem through an onboarding process.
- A VerifierOnboardingMode for verification policy, which determines how
VERIFIERParticipantentries are created. Modes include:OPEN:VERIFIERParticipants can be self-created by any corporation.ECOSYSTEM_ONBOARDING_PROCESS:VERIFIERParticipants are created directly by the controlling ecosystem through an onboarding process.GRANTOR_ONBOARDING_PROCESS:VERIFIERParticipants are created by one or several verifier grantor(s) — ecosystem operators responsible for onboarding verifiers for the credential schema of this ecosystem — selected by the ecosystem through an onboarding process.
- A HolderOnboardingMode for holder policy, which determines how
HOLDERParticipantentries are created. Modes include:ISSUER_ONBOARDING_PROCESS:HOLDERParticipants are created directly by issuers for holders, through an onboarding process.PERMISSIONLESS: a holder that wants to obtain credentials from an issuer does not require aParticipantentry in the VPR.
- A Participant tree that defines the roles and relationships involved in managing the schema’s lifecycle. Each
Participantentry in the tree can define business rules; see Business Models below.
Participant roles are defined in the table below:
| Participant Role | Description |
|---|---|
| Ecosystem | Create and control ecosystems and credential schemas. Recognize other participants by validating them onto the schema (creating their Participant entries). |
| Issuer Grantor | Ecosystem operator that creates ISSUER Participant entries for candidate issuers. |
| Verifier Grantor | Ecosystem operator that creates VERIFIER Participant entries for candidate verifiers. |
| Issuer | Can issue credentials of this schema. |
| Verifier | Can request presentation of credentials of this schema. |
| Holder | Holds a credential. HOLDER Participant entries carry credential status (active, revoked, …). |
Example of a Json Schema credential schema:
{
"$id": "vpr:verana:mainnet/cs/v1/js/VPR_CREDENTIAL_SCHEMA_ID", // ignored, will be generated
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "ExampleCredential",
"description": "ExampleCredential using JsonSchema",
"type": "object",
"properties": {
"credentialSubject": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uri"
},
"firstName": {
"type": "string",
"minLength": 0,
"maxLength": 256
},
"lastName": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"expirationDate": {
"type": "string",
"format": "date"
},
"countryOfResidence": {
"type": "string",
"minLength": 2,
"maxLength": 2
}
},
"required": [
"id",
"lastName",
"birthDate",
"expirationDate",
"countryOfResidence"
]
}
}
}
To participate in an ecosystem and assume a role associated with a specific credential schema:
-
if the schema is
OPENfor issuance and/or verification: a corporation MUST have a registeredCorporationentry in the VPR and self-create itsParticipantentry. -
if the schema is not
OPENfor issuance and/or verification: a corporation MUST have a registeredCorporationentry in the VPR and complete an onboarding process to obtain itsParticipantentry.
The onboarding process involves two parties:
- The applicant — the corporation requesting a
Participantentry for a credential schema within the ecosystem. - The validator — a corporation that already holds a
Participantentry for the same credential schema and has been delegated authority to validate applicants and create newParticipantentries.
Running an onboarding process typically involves the payment of trust fees. The trust fee amount to be paid by the applicant is defined in the validator's Participant entry:
§ Corporation Management
This section is non-normative.
A corporation is the VPR-level entity that represents an authority acting in the registry. It extends a Cosmos SDK group (whose members and policies are managed by the group module) with VPR-specific attributes: a DID, a corporation governance framework (CGF), and lifecycle metadata. A Corporation entry has no id of its own — it is keyed by its underlying group (1:1).
A corporation interacts with the VPR in two complementary ways:
- as the controller of zero or more ecosystems — i.e., the corporation owns the corresponding
Ecosystementries. The controlling corporation manages each ecosystem’s EGF, its credential schemas, and the rootECOSYSTEMParticipantentries of those schemas. - as the owner of zero or more
Participantentries in zero or more ecosystems — i.e., the corporation acts asISSUER,VERIFIER,ISSUER_GRANTOR,VERIFIER_GRANTOR,HOLDER, or rootECOSYSTEMfor credential schemas of those ecosystems.
The two roles are independent: a corporation MAY control no ecosystem at all and only hold Participant entries in third-party ecosystems; or it MAY control several ecosystems and additionally hold Participant entries in others; or any combination of the two.
The same Corporation entry is the single entry point for the corporation’s governance (the CGF), authorization delegation (via OperatorAuthorization to one or more operator accounts), and trust-deposit accounting (TrustDeposit). See the Corporation Module for the methods that manage Corporation entries.
§ DID Indexing
This section is non-normative.
The Participant registry is the foundation for building searchable indexes of verifiable services and the verifiable metadata they expose. Crawlers iterate over Participant entries, resolve each service identifier (currently a DID, extensible in the future), verify that the service is a verifiable service, and extract its verifiable metadata — most notably the credentials presented through linked-vp — together with the ecosystem memberships, credential schema permissions, and trust deposit level associated with the controlling corporation.
Unlike a traditional web index, this index is trust-typed: every entry carries cryptographically verifiable claims about what the service is, who operates it, and under which governance frameworks it is accredited. This unlocks a class of discovery use cases that traditional search engines cannot serve.
§ AI agent discovery
AI agents are first-class consumers of the index. Before delegating a task or accepting a connection, an agent needs to find counterparts whose presented credentials match the capabilities required for the interaction. Querying the index, an AI agent can:
- find verifiable services qualified for a specific task — for example, a payment processor accredited in a given jurisdiction, a KYC issuer recognized by a target ecosystem, or an MCP-style service whose operator holds a recognized organization credential;
- discover other AI agents whose credentials prove the right scope, authority, or operator;
- restrict the search to a specific ecosystem or to services that comply with a chosen credential schema;
- rank candidates by trust deposit size, accreditations held, slashing history, or credential freshness, in order to bias selection toward parties with stronger economic accountability.
Because every indexed claim is anchored in the VPR, an AI agent can verify a counterpart end-to-end before initiating the interaction, avoiding spoofed services and unaccredited issuers.
§ Verifiable User Agent content discovery
Verifiable user agents (VUAs) — such as social browsers, agentic browsers, or CDN-aware clients — use the index to find content and services that are compatible with the user’s context: the credentials the user holds, the ecosystems the user trusts, the jurisdictions and languages that apply, and the schemas that the user’s wallet can satisfy.
Typical VUA queries include:
- “Show only services accredited under ecosystem X” — filter by ecosystem membership.
- “Show services that accept the credentials currently in my wallet” — match the holder’s credentials against each VS's expected presentations.
- “Show issuers of schema Y operating in jurisdiction Z” — combine credential schema permissions with corporation metadata.
- “Show services my user has previously interacted with successfully” — combine the index with the VUA’s local history.
The result is a feed of VSs for which a proof of trust can be displayed to the user before connection, in line with the VUA enforcement obligations defined in this spec and in the VT Spec.
§ Other consumers
The same index serves additional consumers:
- Trust-aware and traditional, form-based search engines, which can return ordinary links to VSs enriched with verifiable trust signals (issuer accreditations, ecosystem memberships, trust deposit level).
- Ecosystem operators and governance authorities, which use the index to monitor accredited issuers, verifiers, and grantors, observe schema adoption across ecosystems, and detect rogue or expired participants.
- Auditors, regulators, and compliance tools, which rely on the index to map the supply chain of trust behind a given service or credential, and to verify that participants are still in good standing.
- Analytics and reputation services, which combine indexed metadata with on-chain history (trust-deposit movements, slashing events, session volumes) to produce reputational signals at the corporation level.
§ Indexing pipeline
§ Business models
§ Trust Deposit
This section is non-normative.
In a VPR, each corporation is associated with a trust deposit.
This trust deposit is automatically funded through transactions involving trust operations, such as onboarding processes, credential issuance, or presentation…
The trust deposit is fundamental to the “Proof-of-Trust” (PoT) mechanism of the Verifiable Trust Specification, and it operates as follows:
- The more a corporation uses the VPR, the more its trust deposit grows.
- Trust deposits generate yield: block execution fees are distributed not only to network validators, but also to trust deposit holders.
- network-level penalties: If a participant violates the governance framework of the VPR or engages in fraudulent activity, their trust deposit may be partially or fully slashed by the VPR's governance authority.
- ecosystem-level penalties: If a participant operates within an ecosystem (e.g., as a grantor, issuer, verifier, or holder,…) and fails to comply with that ecosystem’s governance framework (EGF), their ecosystem-specific trust deposit can be slashed by the corresponding ecosystem governance authority.
- A slashed deposit must be refilled to continue using the services that triggered the penalty.
- When a participant withdraws from an ecosystem, the associated accumulated trust deposit may be released.
- Released deposits can be reused in other services or withdrawn, however, withdrawals incur penalties, and a portion of the withdrawn amount is burned.
- Holding a large trust deposit does not grant governance rights in the VPR: participants who generate high transaction volume cannot gain control over the governance of the VPR solely through usage or deposit size.
This system ensures that participation in the trust ecosystem is backed by economic accountability, reinforcing the integrity, governability and verifiability of the VPR.
§ Onboarding Process Trust Fees
This section is non-normative.
We’ve explained in the Credential Schemas and Participants section above what is an onboarding process.
The table below summarizes the possible combinations of applicants and validators:
| Payee → Payer ↓ | Ecosystem | Issuer Grantor | Verifier Grantor | Issuer | Verifier | Holder |
|---|---|---|---|---|---|---|
| Issuer Grantor | renewable subscription (1) | |||||
| Verifier Grantor | renewable subscription (2) | |||||
| Issuer | renewable subscription (3) | renewable subscription (1) | ||||
| Verifier | renewable subscription (4) | renewable subscription (2) | ||||
| Holder | renewable subscription (5) |
- (1): if issuer onboarding mode is set to GRANTOR_ONBOARDING_PROCESS.
- (2): if verifier onboarding mode is set to GRANTOR_ONBOARDING_PROCESS.
- (3): if issuer onboarding mode is set to ECOSYSTEM_ONBOARDING_PROCESS.
- (4): if verifier onboarding mode is set to ECOSYSTEM_ONBOARDING_PROCESS.
- (5): if holder onboarding mode is set to ISSUER_ONBOARDING_PROCESS.
Onboarding process is started by the applicant.
Example of a candidate issuer (applicant) that would like to obtain an ISSUER Participant entry for a credential schema of an ecosystem, validated by a validator that holds an ISSUER_GRANTOR Participant entry:
The total fees paid by the applicant consist of:
- The validation trust fees defined in the validator’s
Participantentry (the one acting as the validator in the onboarding process), plus - an additional amount equal to the
trust_deposit_rateof that validation trust fees, which is allocated to the applicant’s trust deposit when the onboarding process begins, plus - network fees (not part of the escrowed amount).
Example, using 20% for trust_deposit_rate:
Upon completion of the onboarding process, escrowed trust fees are distributed to the validator as follows:
- A portion defined by
trust_deposit_rateis allocated to the validator’s trust deposit. - The remaining amount is transferred directly to the validator’s wallet.
§ “Pay-Per” trust fees
This section is non-normative.
Pay-per-issuance and pay-per-verification trust fees are defined on each Participant entry for each role within the ecosystem.
Corporations acting as issuers or verifiers for a given credential schema may be required to pay trust fees based on the schema’s configuration and Participant tree.
If trust fee payment is required, the entity must execute a transaction in the VPR to pay the appropriate trust fees before issuing or verifying a credential, else HOLDER agent will not accept the operation.
Key Points for “Pay-Per” Business Models
-
For a given credential schema, the ecosystem and its participants may define pay-per-issuance (or pay-per-verification) trust fees on their respective
Participantentries. -
In such cases, an
ISSUER(orVERIFIER)Participantmust pay:- the corresponding issuance (or verification) trust fees for each involved
Participantentry along theParticipanttree; - an additional amount equal to the
trust_deposit_rateof the calculated trust fees, allocated to the payer’s trust deposit; - (optional) an amount equal to
wallet_user_agent_reward_rateof the calculated trust fees, used to reward the Wallet User Agent; - (optional) an amount equal to
user_agent_reward_rateof the calculated trust fees, used to reward the User Agent.
- the corresponding issuance (or verification) trust fees for each involved
Fee Distribution Model
Trust fees are consistently distributed across participants:
- A portion defined by
trust_deposit_rateis allocated to the participant’s trust deposit. - The remaining portion is transferred directly to the participant’s wallet.
Agents that implement the VT spec must verify that the ISSUER or VERIFIER has fulfilled the required trust fee payment.
If not, they must reject the issuance or verification request.
Note: The User Agent and Wallet User Agent may refer to the same implementation.
Distribution example for the issuance by ISSUER #C of a credential, using the Participant tree above, 20% for trust_deposit_rate, 10% for wallet_user_agent_reward_rate and user_agent_reward_rate.
Distribution example for the verification by VERIFIER #E of a credential issued by ISSUER #C, using the Participant tree above, 20% for trust_deposit_rate, 10% for wallet_user_agent_reward_rate and user_agent_reward_rate.
§ Governance of a VPR
This section is non-normative.
A governance framework must define the governance rules that apply to a VPR.
A designated governance authority (aka a council) is responsible for enforcing these rules and, when necessary, applying financial sanctions to participants who violate the rules.
Ecosystem Governance Frameworks (EGFs) operate independently from the VPR governance framework.
While the VPR governance framework defines the global rules for operating the Verifiable Public Registry (e.g., trust deposits, fee distribution, slashing conditions), each ecosystem must define its own EGF to govern roles, permissions, credential policies, and compliance within its specific domain.
This separation ensures that ecosystems remain autonomous and can tailor governance to their unique needs, without being constrained by the global rules of the VPR.
§ Data model
For simplicity, the data model is presented using an object-relational structure. However, this representation may not be optimal for all implementation scenarios.
Implementors are responsible for adapting the data model to suit their chosen architecture.
For example, a key-value store may be more appropriate for a ledger-based implementation than a relational model.
§ Corporation
A Corporation is the VPR-level entity that extends a Cosmos SDK group with a DID, a governance framework, and lifecycle attributes. A Corporation may control participants in zero or more ecosystems and may itself be the controller of zero or more ecosystems.
Corporation:
did(string) (mandatory): the DID of the Corporation. MUST be globally unique across allCorporationentries (per-Corporationdiduniqueness invariant): at any block height, no twoCorporationentries MAY share the samedidvalue. Enforced at create time by [MOD-CO-MSG-1-2-1] and at rotation time by [MOD-CO-MSG-2-2-1].created(timestamp) (mandatory): timestamp this Corporation has been created.modified(timestamp) (mandatory): timestamp this Corporation has been modified.archived(timestamp) (optional): timestamp this Corporation has been archived.language(string) (mandatory): primary language tag (BCP 47) of this Corporation.active_version(int) (mandatory): active CGF version.
Note: a Corporation entry has no
idof its own. Its primary key is the underlying Cosmos SDK group (1:1, see thegroup --- corplink in the diagram above): a Corporation entry is created, looked up, and referenced by the id of the group it extends. Members and policies of a Corporation are managed by the underlying Cosmos SDK group module; the Corporation entry adds VPR-level attributes only (DID, governance framework, lifecycle).
§ Ecosystem
Ecosystem:
id(uint64) (mandatory): the id of the ecosystem.did(string) (mandatory): the did of the ecosystem. MAY be shared with otherEcosystementries (a single DID MAY be thedidof several ecosystems); per-Ecosystem DID uniqueness is NOT enforced because theEcosystemidentity is itsid. However, per-Ecosystem(did, corporation)consistency IS enforced: at any block height, allEcosystementries with equaldidMUST share the samecorporation. Enforced at create time by [MOD-ES-MSG-1-2-1] and at rotation time by [MOD-ES-MSG-2-2-1].corporation(group) (mandatory): corporation that controls this entry. Constrained by the per-Ecosystem(did, corporation)consistency invariant above.created(timestamp) (mandatory): timestamp this Ecosystem has been created.modified(timestamp) (mandatory): timestamp this Ecosystem has been modified.archived(timestamp) (mandatory): timestamp this Ecosystem has been archived.language(string) (mandatory): primary language tag (BCP 47) of this ecosystem.active_version(int): (mandatory) active governance framework version.
§ GovernanceFrameworkVersion
A GovernanceFrameworkVersion represents a single version of either an EGF or a CGF. Its owning subject is identified by exactly one of ecosystem_id or corporation (XOR).
GovernanceFrameworkVersion:
id(uint64) (mandatory): the id of the GFV.ecosystem_id(uint64) (conditional): the id of the ecosystem that controls thisGovernanceFrameworkVersionentry. MUST be set ifcorporationis null.corporation(group) (conditional): the corporation that controls thisGovernanceFrameworkVersionentry (i.e., the underlying Cosmos SDK group of the owningCorporation). MUST be set ifecosystem_idis null.created(timestamp) (mandatory): timestamp this GovernanceFrameworkVersion has been created.version(int) (mandatory): version of this GF. MUST Starts with 1.
Constraint: exactly one of
ecosystem_idandcorporationMUST be set.
§ GovernanceFrameworkDocument
GovernanceFrameworkDocument
id(uint64) (mandatory): the id of the GFD.gfv_id(uint64) (mandatory): the id of theGovernanceFrameworkVersionentry.created(timestamp) (mandatory): timestamp this GovernanceFrameworkDocument has been created.language(string) (mandatory): primary language tag (BCP 47) of this governance framework document.url(string) (mandatory): URL where the document is published.digest_sri(string) (mandatory): digest_sri of the document.
§ CredentialSchema
CredentialSchema:
General Info:
id(uint64) (mandatory): the id of the schema.ecosystem_id(uint64) (mandatory): the id of the ecosystem that controls thisCredentialSchemaentry.created(timestamp) (mandatory): timestamp this CredentialSchema has been created.modified(timestamp) (mandatory): timestamp this CredentialSchema has been modified.archived(timestamp) (mandatory): timestamp this CredentialSchema has been archived.json_schema(string) (mandatory): Json Schema used for issuing credentials based on this schema.issuer_grantor_validation_validity_period(number) (mandatory): number of days after which an issuer grantor onboarding process expires and must be renewed.verifier_grantor_validation_validity_period(number) (mandatory): number of days after which a verifier grantor onboarding process expires and must be renewed.issuer_validation_validity_period(number) (mandatory): number of days after which an issuer onboarding process expires and must be renewed.verifier_validation_validity_period(number) (mandatory): number of days after which a verifier onboarding process expires and must be renewed.holder_validation_validity_period(number) (mandatory): number of days after which an holder onboarding process expires and must be renewed.issuer_onboarding_mode(IssuerOnboardingMode) (mandatory): defines how permissions are managed for issuers of thisCredentialSchema. OPEN means anyone can issue credential of this schema; GRANTOR_ONBOARDING_PROCESS means an onboarding process MUST be run between a candidate ISSUER and an ISSUER_GRANTOR in order to create an ISSUER permission; ECOSYSTEM_ONBOARDING_PROCESS means an onboarding process MUST be run between a candidate ISSUER and the ecosystem owner (ecosystem) of theCredentialSchemaentry in order to create an ISSUER permission;verifier_onboarding_mode(VerifierOnboardingMode) (mandatory): defines how permissions are managed for verifiers of thisCredentialSchema. OPEN means anyone can verify credentials of this schema (does not implies that a payment is not necessary); GRANTOR_ONBOARDING_PROCESS means an onboarding process MUST be run between a candidate VERIFIER and a VERIFIER_GRANTOR in order to create a VERIFIER permission; ECOSYSTEM_ONBOARDING_PROCESS means an onboarding process MUST be run between a candidate VERIFIER and the ecosystem owner (ecosystem) of theCredentialSchemaentry in order to create a VERIFIER permission;holder_onboarding_mode(HolderOnboardingMode) (mandatory): defines how permissions are managed for holders of thisCredentialSchema. ISSUER_ONBOARDING_PROCESS means an onboarding process MUST be run between a candidate HOLDER and an ISSUER in order to create a HOLDER permission. HOLDER permission is used to check credential revocation status; PERMISSIONLESS means no onboarding is required to take place on the VPR (and thus an ISSUER cannot use the VPR to charge validation fees to candidate holders);pricing_asset_type(PricingAssetType) (mandatory): used asset for paying business fees. Can be TU (trust unit), COIN (a token available on the VPR chain), FIAT (means chain is used for settlement only and payment is done off-chain). Not that in all cases, trust deposits are always handled indenom.pricing_asset(string) (mandatory):"tu"ifpricing_asset_typeis set to TU, else examples: COIN:denom"uvna","ufoo","ibc/3A0F9C2E4E2A9B7D6F...","factory/verana1.../ueurv", FIAT:"USD","GBP",…digest_algorithm(string) (mandatory): algorithm used to compute thedigestSRIfor credentials issued under this schema. Valid values are defined in the Verifiable Trust spec.
§ SchemaAuthorizationPolicy
SchemaAuthorizationPolicy:
id(uint64) (mandatory): unique identifier of this authorization policy.schema_id(uint64) (mandatory): id of theCredentialSchemathis policy applies to.created(timestamp) (mandatory): timestamp when this policy entry was created.version(integer) (mandatory): version number of this policy for the given(schema_id, role).role(SchemaAuthorizationPolicyRole) (mandatory): role this policy applies to (ISSUERorVERIFIER).url(string) (mandatory): URL where the policy document is published.digest_sri(string) (mandatory): SRI hash of the policy document, used to guarantee integrity and immutability.effective_from(timestamp) (mandatory): timestamp from which this policy version is in force.effective_until(timestamp) (optional): timestamp until which this policy version is in force, if time-limited.revoked(boolean) (mandatory): indicates whether this policy version has been revoked and must no longer be used.
§ Participant
Participant:
id(uint64) (mandatory): the id of the participant.schema_id(uint64) (mandatory): the id of the relatedCredentialSchemaentry.role(ParticipantRole): ISSUER, VERIFIER, ISSUER_GRANTOR, VERIFIER_GRANTOR, ECOSYSTEM, HOLDERdid(string) (optional): DID this permission refers to. MUST conform to [RFC3986]. MAY be shared with otherParticipantentries (a single DID MAY be thedidof several participants); per-Participant DID uniqueness is NOT enforced because theParticipantidentity is itsid. However, per-Participant(did, corporation)consistency IS enforced: at any block height, allParticipantentries with non-null equaldidMUST share the samecorporation. Enforced by the create-time basic checks of [MOD-PP-MSG-1-2-1], [MOD-PP-MSG-7-2-1], and [MOD-PP-MSG-14-2-1].Participant.didis set at create time and is not rotated thereafter.corporation(group) (mandatory): corporation that owns this permission. Constrained by the per-Participant(did, corporation)consistency invariant above (whendidis non-null).vs_operator(account) (mandatory): verifiable service agent account. This is the account that will have the right to create or update permission sessions.created(timestamp) (mandatory): timestamp thisParticipanthas been created.adjusted(timestamp) (mandatory): timestamp thisParticipanthas been adjusted.slashed(timestamp) (mandatory): timestamp thisParticipanthas been slashed.repaid(timestamp) (mandatory): timestamp thisParticipanthas been repaid.effective_from(timestamp) (optional): timestamp from which (inclusive) thisParticipantis effective.effective_until(timestamp) (optional): timestamp until when (exclusive) thisParticipantis effective, null if no time limit has been set for this permission.modified(timestamp) (mandatory): timestamp this Participant has been modified.validation_fees(number) (mandatory): price to pay by an applicant to a validator (corporationgrantee of this perm) for running an onboarding process for a given validation period. Must be an integer. Default to 0. Considered unit depends onpricing_asset_typeandpricing_assetconfiguration of related schema.issuance_fees(number) (mandatory): fees requested by granteecorporationof this perm when a credential is issued. Must be an integer. Default to 0. Considered unit depends onpricing_asset_typeandpricing_assetconfiguration of related schema.verification_fees(number) (mandatory): fees requested by granteecorporationof this perm when a credential is verified. Must be an integer. Default to 0. Considered unit depends onpricing_asset_typeandpricing_assetconfiguration of related schema.deposit(number) (mandatory): accumulated grantee deposit in the context of the use of this permission (including the onboarding process), in native denom. Usually, it is incremented when for example, for a ISSUER typeParticipantperm, issuer issues credentials that require paying issuance fees: an additional % of the fees is charged to issuer and sent to its deposit, corresponding deposit amount increases thisparticipant.depositvalue as well. Ifpermis, let’s say revoked, then correspondingparticipant.depositvalue is freed fromparticipant.granteeTrust Deposit.slashed_deposit(number) (mandatory): part of the deposit in native denom that has been slashed.repaid_deposit(number) (mandatory): part of the slashed deposit in native denom that has been repaid.revoked(timestamp) (optional): manual revocation timestamp of this Perm.validator_participant_id(uint64) (optional): permission of the validator assigned to the onboarding process of this permission, ie parent node in theParticipanttree.op_state(enum) (mandatory): one of PENDING, VALIDATED, TERMINATED.op_exp(timestamp) (optional): validation expiration timestamp. This expiration timestamp is for the onboarding process itself, not for the issued credential orParticipantexpiration timestamp.op_last_state_change(timestamp) (mandatory)op_validator_deposit: number (optional): accumulated validator trust deposit, in denom.op_current_fees(number) (mandatory): current action escrowed fees that will be paid to validator upon onboarding process completion, in denom.op_current_deposit(number) (mandatory): current action trust deposit, in denom.op_summary_digest(string) (optional): an optional digest SRI, set by validator, of a summary of the information, proofs… provided by the applicant.issuance_fee_discount: (number) (mandatory): default to 0 (no discount). Maximum 1 (100% discount). Can be set to an ISSUER_GRANTOR or ISSUERParticipantentry (if GRANTOR_ONBOARDING_PROCESS mode) or to an ISSUERParticipantentry (ECOSYSTEM_ONBOARDING_PROCESS mode) to reduce (or void) calculated issuance fees for the subtree ofParticipantentries. Note: this should generally not be used because it reduces or void commission of all related ecosystem participants.verification_fee_discount: (number) (mandatory): default to 0 (no discount). Maximum 1 (100% discount). Can be set to a VERIFIER_GRANTOR or VERIFIERParticipantentry (if GRANTOR_ONBOARDING_PROCESS mode) and/or to a VERIFIERParticipantentry (ECOSYSTEM_ONBOARDING_PROCESS mode) to reduce (or void) calculated fees for the subtree ofParticipantentries. Note: this should generally not be used because it reduces or void commission of all related ecosystem participants.
Note: VS operator authorization settings (spend limits, feegrant, expiration, authorized message types) are no longer stored on
Participant. They live inParticipantAuthorizationRecordentries inside VSOperatorAuthorization, keyed byParticipant.id. See [MOD-DE-MSG-5] and [AUTHZ-CHECK-3].
§ ParticipantSession
ParticipantSession:
id(uuid) (mandatory): session uuid.corporation(group) (mandatory): corporation that controls the entry.vs_operator(account) (mandatory): verifiable service agent account that controls the entry (agent crypto account).created(timestamp) (mandatory): timestamp this ParticipantSession has been created.modified(timestamp) (mandatory): timestamp this ParticipantSession has been modified.session_records(ParticipantSessionRecord[]) (mandatory): session records, for this session.
§ ParticipantSessionRecord
ParticipantSessionRecord:
created(timestamp) (mandatory): timestamp this record has been created.issuer_participant_id(uint64) (optional): related issuerParticipantid (if applicable).verifier_participant_id(uint64) (optional): related verifierParticipantid (if applicable).wallet_agent_participant_id(uint64) (optional): related wallet agentParticipantid (if applicable).agent_participant_id(uint64) (optional): permission id of the agentParticipantid (if applicable).
§ TrustDeposit
TrustDeposit:
share(number) (mandatory): share of the module total deposit.corporation(group) (mandatory) (key): the corporationdeposit(number) (mandatory): amount of deposit indenom.refunded(number) (mandatory): amount of refunded trust deposit, indenom. Refunded trust deposit is reused as funding for the next trust deposit spending before drawing additional funds from the corporation account.slashed_deposit(number) (optional): amount of slashed deposit indenom.repaid_deposit(number) (optional): part of the slashed trust deposit, indenom, that has been repaid.last_slashed(timestamp) (optional): last time this trust deposit has been slashed.last_repaid(timestamp) (optional): last time this trust deposit has been repaid.slash_count(number) (optional): number of times this account has been slashed.
§ DenomAmount
denom(string) (mandatory): token denomination, as explain in denom.amount(number) (mandatory): amount expressed in the given denomination.
§ Digest
digest(string) (mandatory): digest to store.created(timestamp) (mandatory): block execution date of when it was persisted.
§ OperatorAuthorization
corporation(group) (mandatory): the corporation granting the authorization.operator(account) (mandatory): the operator account receiving the authorization.msg_types(msg_type[]) (mandatory): list of module message types this authorization applies to.spend_limit(DenomAmount[]) (optional): maximum amount of funds that the grantee is allowed to spend as a direct consequence of executing authorized messages.remaining_spend(DenomAmount[]) (conditional): runtime balance forspend_limit. Present iffspend_limitis set. Initialized tospend_limitat create time. Decremented per matchingdenomafter each authorized operation. Reset tospend_limitwhen the current cycle ends (seeexpirationandperiodbelow).fee_spend_limit(DenomAmount[]) (optional): maximum total amount of fees that can be paid using this authorization.remaining_fee_spend(DenomAmount[]) (conditional): runtime balance forfee_spend_limit. Present ifffee_spend_limitis set. Initialized, decremented and reset following the same rules asremaining_spend.expiration(timestamp) (optional): authorization window boundary. Ifperiodis unset, this is the absolute end-of-life: whennow() >= expiration, the authorization is dead. Ifperiodis set, this is the end of the current cycle: whennow() >= expiration, the runtime balances are reset to their original limits andexpirationis advanced tonow() + period(the authorization auto-renews until the corporation revokes it).period(duration) (optional): reset period forspend_limitandfee_spend_limit. If set,expirationMUST also be set.
§ FeeGrant
FeeGrant:
grantor(group) (mandatory): the corporation granting the fee allowance.grantee(account) (mandatory): the account that receives the fee grant fromgrantor.msg_types(msg_type[]) (mandatory): list of VPR delegable message types for which the fee allowance applies.spend_limit(DenomAmount[]) (optional): maximum amount of fees that can be spent using this grant.remaining_spend(DenomAmount[]) (conditional): runtime balance forspend_limit. Present iffspend_limitis set. Initialized tospend_limitat create time. Decremented per matchingdenomafter each authorized operation. Reset tospend_limitwhen the current cycle ends (seeexpirationandperiodbelow).expiration(timestamp) (optional): grant window boundary. Ifperiodis unset, this is the absolute end-of-life: whennow() >= expiration, the grant is dead. Ifperiodis set, this is the end of the current cycle: whennow() >= expiration,remaining_spendis reset tospend_limitandexpirationis advanced tonow() + period(the grant auto-renews until the grantor revokes it).period(duration) (optional): reset period forspend_limit. If set,expirationMUST also be set.
§ VSOperatorAuthorization
A VSOperatorAuthorization groups all ParticipantAuthorizationRecord entries delegated by one corporation to one vs_operator. It is keyed by the (corporation, vs_operator) pair. The entry exists if, and only if, it has at least one record.
corporation(group) (mandatory): the corporation granting the authorization.vs_operator(account) (mandatory): the operator account receiving the authorization.records(ParticipantAuthorizationRecord[]) (mandatory): per-permission authorization records granted tovs_operatorbycorporation.
§ ParticipantAuthorizationRecord
A ParticipantAuthorizationRecord carries the per-permission authorization configuration that was previously stored on Participant.vs_operator_authz_* fields. Each record is globally unique by participant_id: for any Participant.id, at most one record exists system-wide, so (corporation, vs_operator) can be derived from participant_id via a direct lookup.
participant_id(uint64) (mandatory): id of theParticipantthis authorization record applies to. Globally unique across allParticipantAuthorizationRecordentries.msg_types(msg_type[]) (mandatory): list of delegable message types for which thevs_operatoris authorized on behalf ofcorporationwhen acting in the context ofparticipant_id. Declared by the applicant at record creation time (see [MOD-PP-MSG-1] and [MOD-PP-MSG-14]). Frozen after creation.spend_limit(DenomAmount[]) (optional): maximum amount thevs_operatoris allowed to spend, in the context of thisParticipantentry, as a direct consequence of executing authorized messages.remaining_spend(DenomAmount[]) (conditional): runtime balance forspend_limit. Present iffspend_limitis set. Initialized tospend_limitat create time. Decremented per matchingdenomafter each authorized operation. Reset tospend_limitwhen the current cycle ends (seeexpirationandperiodbelow).fee_spend_limit(DenomAmount[]) (optional): maximum total amount of transaction fees that can be spent byvs_operator(paid bycorporationvia fee grant) in the context of thisParticipantentry.remaining_fee_spend(DenomAmount[]) (conditional): runtime balance forfee_spend_limit. Present ifffee_spend_limitis set. Initialized, decremented and reset following the same rules asremaining_spend.with_feegrant(bool) (mandatory): if true,corporationpays the transaction fees forvs_operatorwhen executing authorized messages in the context of thisParticipantentry, through an on-chainFeeGrant.expiration(timestamp) (mandatory): authorization window boundary. Ifperiodis unset, this is the absolute end-of-life: whennow() >= expiration, the record is dead. Ifperiodis set, this is the end of the current cycle: whennow() >= expiration, the runtime balances are reset to their original limits andexpirationis advanced tonow() + period(the record auto-renews until removed via [MOD-DE-MSG-6]). Initially written tonowat [MOD-PP-MSG-1] (disabled until validation) and toParticipant.effective_untilat [MOD-PP-MSG-3] / [MOD-PP-MSG-8] / [MOD-PP-MSG-14].period(duration) (optional): reset period forspend_limitandfee_spend_limitin the context of thisParticipantentry.
§ ExchangeRate
Represents an on-chain exchange rate between two assets.
ExchangeRate:
base_asset_type(PricingAssetType, mandatory): Type of the base asset.base_asset(string, mandatory ifbase_asset_typeis COIN or FIAT, null ifbase_asset_typeis TU): Identifier of the base asset.quote_asset_type(PricingAssetType, mandatory): Type of the quote asset.quote_asset(string, mandatory): Identifier of the quote asset.rate(string, mandatory): Fixed-point integer representing the exchange rate from base asset to quote asset.rate_scale(uint32, mandatory): Number of decimal digits used to scale rate.validity_duration(duration, mandatory): when updated, setexpiresto block time plusvalidity_duration.updated(timestamp, mandatory): Timestamp of the last exchange rate update.expires(timestamp, mandatory): Timestamp after which the exchange rate is considered invalid.state(boolean, mandatory): true means enabled, false means disabled.
§ ExchangeRateAuthorization
Represents the authorization granted by network governance to a specific operator account to execute [MOD-XR-MSG-2] Update Exchange Rate on a given ExchangeRate entry.
Exchange rates are a protocol-level oracle: they are consumed by [MOD-XR-QRY-3] Get Price and used across the protocol (trust deposit pricing, fees). Therefore, ownership and update permission of an ExchangeRate is scoped to the network (governance), not to a corporation. ExchangeRateAuthorization is the on-chain record that designates which operator account is authorized to push fresh values for a given ExchangeRate, and under what runtime constraints.
ExchangeRateAuthorization:
xr_id(uint64, mandatory): id of theExchangeRatethis authorization applies to. Together withoperator, forms the composite key.operator(account, mandatory): account authorized to execute [MOD-XR-MSG-2] onxr_id. Together withxr_id, forms the composite key.expiration(timestamp, mandatory): authorization end-of-life. Whennow() >= expiration, the authorization is dead and [MOD-XR-MSG-2] MUST be rejected.min_interval(duration, optional): anti-spam guard. If set, two successive successful [MOD-XR-MSG-2] calls under this authorization MUST be separated by at leastmin_interval.max_deviation_bps(uint32, optional): circuit breaker, expressed in basis points (1 bps = 0.01%). If set, [MOD-XR-MSG-2] MUST be rejected if the relative change between the newrateand the currentxr.rateexceedsmax_deviation_bps / 10000. A larger move requires a fresh governance proposal (typically a new [MOD-XR-MSG-1] or an updated authorization).
§ GlobalVariables
GlobalVariables:
Credential Schema:
credential_schema_schema_max_size(number) (mandatory): maximum size of theschemastring attribute for aCredentialSchema.credential_schema_issuer_grantor_validation_validity_period_max_days(number) (mandatory): maximum number of days an issuer grantor validation can be valid for.credential_schema_verifier_grantor_validation_validity_period_max_days(number) (mandatory): maximum number of days an verifier grantor validation can be valid for.credential_schema_issuer_validation_validity_period_max_days(number) (mandatory): maximum number of days an issuer validation can be valid for.credential_schema_verifier_validation_validity_period_max_days(number) (mandatory): maximum number of days an verifier validation can be valid for.credential_schema_holder_validation_validity_period_max_days(number) (mandatory): maximum number of days an holder validation can be valid for.
Trust Deposit:
trust_deposit_share_value(number) (mandatory): Value of one share of trust deposit, in native denom. Default an initial value: 1. Increase over time, when yield is produced.trust_deposit_rate(number) (mandatory): Rate used for dynamically calculating trust deposits from trust fees. Default value: 20% (0.20)trust_deposit_max_yield_rate(number) (mandatory): Maximum yearly yield, in percent, that a trust deposit holder can obtain by receiving block rewards.trust_deposit_block_reward_share(number) (mandatory): Percentage of block reward that must be distributed to trust deposit holders. Default value: 20% (0.20)wallet_user_agent_reward_rate(number) (mandatory): Rate used for dynamically calculating wallet user agent rewards from trust fees. Default value: 20% (0.20)user_agent_reward_rate(number) (mandatory): Rate used for dynamically calculating user agent rewards from trust fees. Default value: 20% (0.20)
§ Module Requirements
All VPR modules MUST, at least, provide:
- A keeper(s), used to access the module’s store(s) and update the state.
- A Msg service, used to process messages when they are routed to the module by BaseApp and trigger state-transitions.
- A query service, used to process user queries.
- Interfaces, for end users to query the subset of the state defined by the module and create messages of the custom types defined in the module.
Note about Query REST API:
- all query methods MUST return valid JSON.
- objects MUST be nested when needed, such as when returning an ecosystem.
- JSON formatting MUST obey to data model regarding attribute names. A method that returns a
Ecosystementry MUST return an entry called “ecosystem”. A method that returns a list of Ecosystems MUST return an entry called “ecosystems” that contain a list ofEcosystementries.
Examples:
Get an Ecosystem
"ecosystem": {
{
"active_version": 0,
"corporation": "string",
"created": "2025-01-14T19:40:37.967Z",
"deposit": "string",
"did": "string",
"id": "string",
"language": "string",
"modified": "2025-01-14T19:40:37.967Z",
"versions": [
{
"active_since": "2025-01-14T19:40:37.967Z",
"created": "2025-01-14T19:40:37.967Z",
"id": "string",
"ecosystem_id": "string",
"version": 0,
"documents": [
{
"created": "2025-01-14T19:40:37.967Z",
"gfv_id": "string",
"digest_sri": "string",
"id": "string",
"language": "string",
"url": "string"
}
]
}
]
}
"ecosystems": [ {
{
"active_version": 0,
"corporation": "string",
"created": "2025-01-14T19:40:37.967Z",
"deposit": "string",
"did": "string",
"id": "string",
"language": "string",
"modified": "2025-01-14T19:40:37.967Z",
"versions": [
{
"active_since": "2025-01-14T19:40:37.967Z",
"created": "2025-01-14T19:40:37.967Z",
"id": "string",
"ecosystem_id": "string",
"version": 0,
"documents": [
{
"created": "2025-01-14T19:40:37.967Z",
"gfv_id": "string",
"digest_sri": "string",
"id": "string",
"language": "string",
"url": "string"
}
]
}
]
}, {
"active_version": 0,
"corporation": "string",
"created": "2025-01-14T19:40:37.967Z",
"deposit": "string",
"did": "string",
"id": "string",
"language": "string",
"modified": "2025-01-14T19:40:37.967Z",
"versions": [
{
"active_since": "2025-01-14T19:40:37.967Z",
"created": "2025-01-14T19:40:37.967Z",
"id": "string",
"ecosystem_id": "string",
"version": 0,
"documents": [
{
"created": "2025-01-14T19:40:37.967Z",
"gfv_id": "string",
"digest_sri": "string",
"id": "string",
"language": "string",
"url": "string"
}
],
}
]
}
]
For Msg methods, all precondition checks MUST be verified first for accepting the Msg, and MUST be verified again upon method execution
A VPR implementation MUST implement all the following requirements.
The relative REST path is the path suffix. Implementer can set any prefix, like https://example/verana/ec/v1/get.
§ Authorization and Fee Grants
§ Delegable Module Messages
Most VPR module messages (Msg) support delegation and follow the pattern described below.
Delegable messages are defined as messages that can be executed by an operator account on behalf of a corporation group, provided that the appropriate authorization has been granted.
Such messages conceptually involve two roles:
-
corporation(group):
Thegroupthat owns the created or manipulated resource.
The corporation is represented in the Msg through an authorization granted to anoperatoraccount. -
operator(account):
Theaccountthat executes the Msg on behalf of thecorporation.
The operator MUST be explicitly authorized for the given message type.
When a delegable message is executed directly by an operator account, both roles are authenticated and enforced by the authorization system.
Using this model makes it possible to:
- identify, within the Msg, both the authenticated
corporationand the executingoperator, - allow network fees to be paid either by the
operatoraccount or by thecorporationaccount via a fee grant.
For the execution of delegable messages:
- the
operatoraccount MUST have a valid authorization from thecorporationgroup for the specific message type being executed.
A corporation group is not required to delegate all message types to the same operator.
It is entirely up to the corporation group to decide which accounts may execute which messages.
- Authorizations MUST be granted to individual
accounts through group proposals. - Authorizations MAY include an optional
spend_limitand an optionalexpirationdate.
§ Not Delegable Module Messages
Some module messages specify only a corporation:
corporation(group):
Thegroupthat owns the manipulated resource.
Such messages cannot be delegated and MUST be executed exclusively through a corporation proposal.
§ Governance-Signed Module Messages
Some module messages can be executed only through a VPR council governance proposal.
These messages do not support delegation and are not executable by accounts, whether directly or via group authorization.
§ Fee Grants
A corporation MAY allow its operators to pay network transaction fees using the corporation’s funds.
Fee grants are not created directly.
They are created, updated, and revoked exclusively by Authorization module messages.
When an authorization is created or updated, it MAY optionally include an associated fee grant.
§ [AUTHZ-CHECK] Common Authorization and Fee Grant Precondition Checks
For any delegable message executed by an operator on behalf of a corporation, the following precondition checks MUST be performed before any method-specific checks. If any check fails, the transaction MUST abort.
§ [AUTHZ-CHECK-1] Operator Authorization checks
- An
OperatorAuthorizationoauthzMUST exist whereoauthz.corporation=corporation,oauthz.operator=operator, andoauthz.msg_typesincludes the current message type. - If
oauthz.expirationis set:- if
oauthz.periodis set andnow() >= oauthz.expiration:- if
oauthz.spend_limitis set, setoauthz.remaining_spend := oauthz.spend_limit. - if
oauthz.fee_spend_limitis set, setoauthz.remaining_fee_spend := oauthz.fee_spend_limit. - set
oauthz.expiration := now() + oauthz.period.
- if
- else,
oauthz.expirationMUST be strictly greater thannow(). Abort otherwise.
- if
- If
oauthz.spend_limitis set,oauthz.remaining_spendMUST be sufficient for the operation. After successful execution, the consumed amount MUST be deducted fromoauthz.remaining_spend(per matchingdenomentry).
§ [AUTHZ-CHECK-2] Fee Grant checks
If the transaction fees are paid by the corporation account (via fee grant) instead of the operator account:
- A
FeeGrantfgMUST exist wherefg.grantor=corporation,fg.grantee=operator, andfg.msg_typesincludes the current message type. - If
fg.expirationis set:- if
fg.periodis set andnow() >= fg.expiration:- if
fg.spend_limitis set, setfg.remaining_spend := fg.spend_limit. - set
fg.expiration := now() + fg.period.
- if
- else,
fg.expirationMUST be strictly greater thannow(). Abort otherwise.
- if
- If
fg.spend_limitis set,fg.remaining_spendMUST be sufficient for the estimated transaction fees. After successful execution, the consumed fee amount MUST be deducted fromfg.remaining_spend(per matchingdenomentry).
§ [AUTHZ-CHECK-3] VS Operator Authorization checks
A second authorization grant mode exists for vs-agents. It is used when a corporation delegates a specific permission (and a specific set of message types, scoped to that permission) to a vs_operator account. The authorization model differs from other delegable messages: it relies on VSOperatorAuthorization / ParticipantAuthorizationRecord instead of OperatorAuthorization.
Note: the set of messages a
vs_operatoris authorized to execute in the context of a permission is declared by the applicant at permission creation time (see [MOD-PP-MSG-1-1] and [MOD-PP-MSG-14-1]) and stored inrecord.msg_types. It is frozen for the lifetime of the record and can only be changed by revoking the permission and starting a new one.
Given a corporation, an operator (the vs_operator), a primary permission id participant_id (determined by the calling method), and the current message type msg_type:
- A
ParticipantAuthorizationRecordrecordMUST exist forparticipant_id. Abort if not found. recordMUST belong toVSOperatorAuthorization[corporation, operator], that is: the containingVSOperatorAuthorizationMUST havecorporationas itscorporationandoperatoras itsvs_operator. Abort otherwise.msg_typeMUST be inrecord.msg_types. Abort otherwise.- Cycle / expiration check:
- if
record.periodis set andnow() >= record.expiration:- if
record.spend_limitis set, setrecord.remaining_spend := record.spend_limit. - if
record.fee_spend_limitis set, setrecord.remaining_fee_spend := record.fee_spend_limit. - set
record.expiration := now() + record.period.
- if
- else,
record.expirationMUST be strictly greater thannow(). Abort otherwise.
- if
- If
record.spend_limitis set,record.remaining_spendMUST be sufficient for the operation. After successful execution, the consumed amount MUST be deducted fromrecord.remaining_spend(per matchingdenomentry).
§ [AUTHZ-CHECK-4] VS Operator Fee Grant checks
If the transaction fees are paid by the corporation account (via fee grant) instead of the operator account, using the same ParticipantAuthorizationRecord record looked up in [AUTHZ-CHECK-3]:
record.with_feegrantMUST be true, else abort.- The cycle / expiration check from [AUTHZ-CHECK-3] step 4 has already been performed against the same
record;record.remaining_fee_spendis therefore current. - If
record.fee_spend_limitis set,record.remaining_fee_spendMUST be sufficient for the estimated transaction fees. After successful execution, the consumed fee amount MUST be deducted fromrecord.remaining_fee_spend(per matchingdenomentry).
§ [AUTHZ-CHECK-5] Corporation Registration check
A Corporation entry MUST exist for the signing corporation (i.e., keyed by its underlying Cosmos SDK group). If none exists, the transaction MUST abort with an error indicating that the underlying group has not yet been registered as a corporation (see [MOD-CO-MSG-1]).
Exception: this check MUST NOT be applied for [MOD-CO-MSG-1], whose explicit purpose is to register a Cosmos SDK group as a new
Corporation. That method enforces the inverse precondition (the entry MUST NOT yet exist) in its own basic checks.
This check applies to every delegable message that invokes [AUTHZ-CHECK]. As a result, all Create-* methods (and every other delegable Msg) implicitly require the signing corporation to be a registered Corporation.
§ Example
A corporation group corporationABC wants to authorize an operator account accountABC to execute the
mod-pp-msg-10-create-or-update-participant-session,
mod-pp-msg-3-set-participant-op-to-validated, and
mod-pp-msg-15-trigger-resolver
messages.
Additionally, the corporation wants accountABC to pay the transaction fees for this message using the corporation’s funds.
To achieve this, corporationABC MUST:
- create an authorization from
corporationABCtoaccountABCfor the
mod-pp-msg-10-create-or-update-participant-session,mod-pp-msg-3-set-participant-op-to-validated, andmod-pp-msg-15-trigger-resolvermessage types, optionally enabling an associated fee grant.
As a result, accountABC is authorized to:
- execute the specified messages type on behalf of
corporationABC, including any state changes and fund movements that are a direct consequence of that message, and - pay the network transaction fees for that message using the funds of
corporationABC, via the associated fee grant.
§ Method List
| Module | Method Name | Relative REST API path | Type | Requirements | Signers |
|---|---|---|---|---|---|
| Corporation | Create New Corporation | N/A (Tx) | Msg | [MOD-CO-MSG-1] | corporation + operator |
| Update Corporation | N/A (Tx) | Msg | [MOD-CO-MSG-2] | corporation + operator | |
| Archive Corporation | N/A (Tx) | Msg | [MOD-CO-MSG-3] | corporation + operator | |
| Update Corporation Module Parameters | N/A (Tx) | Msg | [MOD-CO-MSG-4] | governance proposal | |
| Get Corporation | /co/v1/get | Query | [MOD-CO-QRY-1] | N/A | |
| List Corporations | /co/v1/list | Query | [MOD-CO-QRY-2] | N/A | |
| List Corporation Module Parameters | /co/v1/params | Query | [MOD-CO-QRY-3] | N/A | |
| Ecosystem | Create an Ecosystem | N/A (Tx) | Msg | [MOD-ES-MSG-1] | corporation + operator |
| Update Ecosystem | N/A (Tx) | Msg | [MOD-ES-MSG-2] | corporation + operator | |
| Archive Ecosystem | N/A (Tx) | Msg | [MOD-ES-MSG-3] | corporation + operator | |
| Update Ecosystem Module Parameters | N/A (Tx) | Msg | [MOD-ES-MSG-4] | governance proposal | |
| Get Ecosystem | /ec/v1/get | Query | [MOD-ES-QRY-1] | N/A | |
| List Ecosystems | /ec/v1/list | Query | [MOD-ES-QRY-2] | N/A | |
| List Ecosystem Module Parameters | /ec/v1/params | Query | [MOD-ES-QRY-3] | N/A | |
| Governance Framework | Add Governance Framework Document | N/A (Tx) | Msg | [MOD-GF-MSG-1] | corporation + operator |
| Increase Active Governance Framework Version | N/A (Tx) | Msg | [MOD-GF-MSG-2] | corporation + operator | |
| Get Governance Framework Version | /gf/v1/get | Query | [MOD-GF-QRY-1] | N/A | |
| List Governance Framework Versions | /gf/v1/list | Query | [MOD-GF-QRY-2] | N/A | |
| Credential Schema | Create a Credential Schema | N/A (Tx) | Msg | [MOD-CS-MSG-1] | corporation + operator |
| Update a Credential Schema | N/A (Tx) | Msg | [MOD-CS-MSG-2] | corporation + operator | |
| Archive Credential Schema | N/A (Tx) | Msg | [MOD-CS-MSG-3] | corporation + operator | |
| Update CS Module Parameters | N/A (Tx) | Msg | [MOD-CS-MSG-4] | governance proposal | |
| Create Schema Authorization Policy | N/A (Tx) | Msg | [MOD-CS-MSG-5] | corporation + operator | |
| Increase Active Schema Authorization Policy Version | N/A (Tx) | Msg | [MOD-CS-MSG-6] | corporation + operator | |
| Revoke Schema Authorization Policy | N/A (Tx) | Msg | [MOD-CS-MSG-7] | corporation + operator | |
| List Credential Schemas | /cs/v1/list | Query | [MOD-CS-QRY-1] | N/A | |
| Get a Credential Schema | /cs/v1/get | Query | [MOD-CS-QRY-2] | N/A | |
| Render Json Schema | /cs/v1/js/ | Query | [MOD-CS-QRY-3] | N/A | |
| List CS Module Parameters | /cs/v1/params | Query | [MOD-CS-QRY-4] | N/A | |
| Get Schema Authorization Policy | /cs/v1/sap/get | Query | [MOD-CS-QRY-5] | N/A | |
| List Schema Authorization Policies | /cs/v1/sap/list | Query | [MOD-CS-QRY-6] | N/A | |
| Participant | Start Participant OP | N/A (Tx) | Msg | [MOD-PP-MSG-1] | corporation + operator |
| Renew a Participant OP | N/A (Tx) | Msg | [MOD-PP-MSG-2] | corporation + operator | |
| Set Participant OP to Validated | N/A (Tx) | Msg | [MOD-PP-MSG-3] | corporation + operator | |
| Cancel Participant OP Last Request | N/A (Tx) | Msg | [MOD-PP-MSG-6] | corporation + operator | |
| Create Root Participant | N/A (Tx) | Msg | [MOD-PP-MSG-7] | corporation + operator | |
| Set Participant Effective Until | N/A (Tx) | Msg | [MOD-PP-MSG-8] | corporation + operator | |
| Revoke Participant | N/A (Tx) | Msg | [MOD-PP-MSG-9] | corporation + operator | |
| Create or update Participant Session | N/A (Tx) | Msg | [MOD-PP-MSG-10] | corporation + operator | |
| Update Participant Module Parameters | N/A (Tx) | Msg | [MOD-PP-MSG-11] | governance proposal | |
| Slash Participant Trust Deposit | N/A (Tx) | Msg | [MOD-PP-MSG-12] | corporation + operator | |
| Repay Participant Slashed Trust Deposit | N/A (Tx) | Msg | [MOD-PP-MSG-13] | corporation + operator | |
| Self Create Participant (OPEN mode) | N/A (Tx) | Msg | [MOD-PP-MSG-14] | corporation + operator | |
| Trigger Resolver | N/A (Tx) | Msg | [MOD-PP-MSG-15] | corporation + operator | |
| List Participants | /pp/v1/list | Query | [MOD-PP-QRY-1] | N/A | |
| Get a Participant | /pp/v1/get | Query | [MOD-PP-QRY-2] | N/A | |
| Find Beneficiaries | /pp/v1/beneficiaries | Query | [MOD-PP-QRY-4] | N/A | |
| Get Participant Session | /pp/v1/session/get | Query | [MOD-PP-QRY-5] | N/A | |
| List Participant Module Parameters | /pp/v1/params | Query | [MOD-PP-QRY-6] | N/A | |
| Trust Deposit | Adjust Trust Deposit | N/A (Tx) | Msg | [MOD-TD-MSG-1] | module call |
| Reclaim Trust Deposit Yield | N/A (Tx) | Msg | [MOD-TD-MSG-2] | corporation + operator | |
| Update TD Module Parameters | N/A (Tx) | Msg | [MOD-TD-MSG-4] | governance proposal | |
| Slash Trust Deposit | N/A (Tx) | Msg | [MOD-TD-MSG-5] | governance proposal | |
| Repay Slashed Trust Deposit | N/A (Tx) | Msg | [MOD-TD-MSG-6] | corporation + operator | |
| Burn Ecosystem Slashed Trust Deposit | N/A (Tx) | Msg | [MOD-TD-MSG-7] | module call | |
| Get Trust Deposit | /td/v1/get | Query | [MOD-TD-QRY-1] | N/A | |
| List TD Module Parameters | /td/v1/params | Query | [MOD-TD-QRY-2] | N/A | |
| Delegation | Grant Fee Allowance | N/A (Tx) | Msg | [MOD-DE-MSG-1] | module call |
| Revoke Fee Allowance | N/A (Tx) | Msg | [MOD-DE-MSG-2] | module call | |
| Grant Operator Authorization | N/A (Tx) | Msg | [MOD-DE-MSG-3] | corporation (group proposal) OR corporation + operator OR module call | |
| Revoke Operator Authorization | N/A (Tx) | Msg | [MOD-DE-MSG-4] | corporation (group proposal) OR corporation + operator OR module call | |
| Grant VS Operator Authorization | N/A (Tx) | Msg | [MOD-DE-MSG-5] | module call | |
| Revoke VS Operator Authorization | N/A (Tx) | Msg | [MOD-DE-MSG-6] | module call | |
| List Operator Authorizations | /de/v1/authz/list | Query | [MOD-DE-QRY-1] | N/A | |
| List VS Operator Authorizations | /de/v1/vs-authz/list | Query | [MOD-DE-QRY-2] | N/A | |
| Digests | Store Digest | N/A (Tx) | Msg | [MOD-DI-MSG-1] | corporation + operator OR module call |
| Get Digest | /di/v1/get | Query | [MOD-DI-QRY-1] | N/A | |
| Exchange Rate | Create Exchange Rate | Msg | [MOD-XR-MSG-1] | governance proposal | |
| Update Exchange Rate | Msg | [MOD-XR-MSG-2] | operator | ||
| Toggle Exchange Rate State | Msg | [MOD-XR-MSG-3] | governance proposal | ||
| Grant Exchange Rate Authorization | N/A (Tx) | Msg | [MOD-XR-MSG-4] | governance proposal | |
| Revoke Exchange Rate Authorization | N/A (Tx) | Msg | [MOD-XR-MSG-5] | governance proposal | |
| Get Exchange Rate | /xr/v1/get | Query | [MOD-XR-QRY-1] | N/A | |
| List Exchange Rates | /xr/v1/list | Query | [MOD-XR-QRY-2] | N/A | |
| Get Price | /xr/v1/price | Query | [MOD-XR-QRY-3] | N/A |
Any method failure in the precondition/basic checks SHOULD lead to a CLI ERROR / HTTP BAD REQUEST error with a human readable message giving a clue of the reason why method failed.
§ Corporation Module
This module manages corporation entries — the VPR-level entity that extends a Cosmos SDK group with a DID, a governance framework, and lifecycle attributes. A Corporation entry MUST exist before its underlying group can be referenced as the corporation (group) in any other VPR Create-* method (see [MOD-CO-MSG-1]).
§ [MOD-CO-MSG-1] Create New Corporation
Any authorized operator CAN execute this method on behalf of a Cosmos SDK group to register a new Corporation entry for that group.
§ [MOD-CO-MSG-1-1] Create New Corporation parameters
An authorized operator that would like to register a Cosmos SDK group as a Corporation MUST call this method by specifying:
corporation(group): (Signer) the signing corporation on whose behalf this message is executed. For this method specifically, the underlying Cosmos SDK group ofcorporationis the group that wants to register itself — noCorporationentry exists for that group yet.operator(account): (Signer) the account authorized by thecorporationto run this Msg.did(string) (mandatory): the DID of the Corporation.language(string) (mandatory): primary language tag (BCP 47) of this Corporation.doc_url(string) (mandatory): URL where the v1 CGF document is published.doc_digest_sri(string) (mandatory): digest_sri of the v1 CGF document.
Provided document MUST be of the same language as the primary language of the Corporation.
§ [MOD-CO-MSG-1-2] Create New Corporation precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-CO-MSG-1-2-1] Create New Corporation basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
A
Corporationentry for the signing group MUST NOT exist; if one exists, method MUST abort (a group MAY register itself as aCorporationat most once). -
did(string) (mandatory): MUST conform to the DID Syntax, as specified [DID-CORE]. -
didMUST NOT already be thedidof any existingCorporationentry; if someCorporationentry already holds thisdid, method MUST abort (per-Corporationdiduniqueness invariant: a DID is thedidof at most oneCorporation). -
language(string(17)) (mandatory): MUST be a language tag (BCP 47). -
doc_url(string) (mandatory): MUST be a valid URL. -
doc_digest_sri(string) (mandatory): MUST be a valid digest_sri as specified in integrity of related resources spec. Example:sha384-MzNNbQTWCSUSi0bbz7dbua+RcENv7C6FvlmYJ1Y+I727HsPOHdzwELMYO9Mz68M26.
§ [MOD-CO-MSG-1-2-2] Create New Corporation fee checks
Fee payer MUST have the required estimated transaction fees in its account.
§ [MOD-CO-MSG-1-3] Create New Corporation execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
create and persist a new
Corporationentrycokeyed by the signing Cosmos SDK group (1:1): -
co.did:did -
co.created: current timestamp -
co.modified:co.created -
co.archived: null -
co.language:language -
co.active_version: 1 -
create and persist a new
GovernanceFrameworkVersionentrygfv: -
gfv.id: auto-incremented uint64 -
gfv.ecosystem_id: null -
gfv.corporation: the signingcorporation(i.e., the underlying group ofco) -
gfv.created: current timestamp -
gfv.version: 1 -
gfv.active_since: current timestamp -
create and persist a new
GovernanceFrameworkDocumententrygfd: -
gfd.id: auto-incremented uint64 -
gfd.gfv_id:gfv.id -
gfd.created: current timestamp -
gfd.language:language -
gfd.url:doc_url -
gfd.digest_sri:doc_digest_sri
Subsequent governance framework documents and version activations for this
CorporationMUST be managed through [MOD-GF-MSG-1] and [MOD-GF-MSG-2].
§ [MOD-CO-MSG-2] Update Corporation
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-CO-MSG-2-1] Update Corporation parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.did(string) (mandatory): the new DID of the Corporation.
Note:
languageis set at creation time by [MOD-CO-MSG-1] and is immutable thereafter; it cannot be updated through this method.
§ [MOD-CO-MSG-2-2] Update Corporation precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-CO-MSG-2-2-1] Update Corporation basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
A
Corporationentrycofor the signingcorporationMUST exist; if none exists, method MUST abort. -
did(string) (mandatory): MUST conform to the DID Syntax, as specified [DID-CORE]. -
didMUST NOT already be thedidof any otherCorporationentry (i.e., anyCorporationentry whose underlying group differs from the signingcorporation); if some otherCorporationentry already holds thisdid, method MUST abort (per-Corporationdiduniqueness invariant). Rotating to the same valueco.didalready holds is a no-op and MUST be allowed.
§ [MOD-CO-MSG-2-2-2] Update Corporation fee checks
Fee payer MUST have available balance in its account to cover the required transaction fees.
§ [MOD-CO-MSG-2-3] Update Corporation execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
load
Corporationentrycofor the signingcorporationand set: -
co.did:did -
co.modified: current timestamp
§ [MOD-CO-MSG-3] Archive Corporation
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-CO-MSG-3-1] Archive Corporation parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.archive(boolean) (mandatory): true means archive, false means unarchive.
§ [MOD-CO-MSG-3-2] Archive Corporation precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-CO-MSG-3-2-1] Archive Corporation basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
load
Corporationcofrom the id of the signingcorporation. If none exists, MUST abort. -
archive(boolean) (mandatory) MUST be a boolean.- If
archiveis true andco.archivedis not null, MUST abort asCorporationis already archived. - If
archiveis false andco.archivedis null, MUST abort asCorporationis already not archived.
- If
§ [MOD-CO-MSG-3-2-2] Archive Corporation fee checks
Fee payer MUST have an available balance in its account to cover the required transaction fees.
§ [MOD-CO-MSG-3-3] Archive Corporation execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- update
Corporationentryco: - if
archiveis true: setco.archivedto current timestamp. - if
archiveis false: setco.archivedto null. co.modified: current timestamp
§ [MOD-CO-MSG-4] Update Module Parameters
Update Module Parameters.
Can only be executed through a governance proposal.
§ [MOD-CO-MSG-4-1] Update Module Parameters parameters
params(KeySet<String, String>): the parameters to update and their values.
§ [MOD-CO-MSG-4-2] Update Module Parameters precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-CO-MSG-4-2-1] Update Module Parameters basic checks
params: size ofparamsMUST be greater than 0. For eachparam<key,value>,keyMUST exist, else abort.
§ [MOD-CO-MSG-4-2-2] Update Module Parameters fee checks
provided transaction fees MUST be sufficient for execution.
§ [MOD-CO-MSG-4-3] Update Module Parameters execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
for each parameter param <key, value> in parameters:
- update parameter set value =
valuewhere key =key.
§ [MOD-CO-QRY-1] Get Corporation
Anyone CAN execute this method.
§ [MOD-CO-QRY-1-1] Get Corporation query parameters
corporation(group) (mandatory): the corporation to fetch (i.e., the underlying Cosmos SDK group whoseCorporationentry is keyed by it).active_gf_only(boolean) (optional): if true, include only current governance framework data. If false or null, returns everything.preferred_language(string) (optional): if set, return only one document per version, preferringpreferred_language.
§ [MOD-CO-QRY-1-2] Get Corporation query checks
If any of these checks fail, query MUST fail.
corporation(group) (mandatory): MUST be a valid group id.
§ [MOD-CO-QRY-1-3] Get Corporation execution
Return the Corporation entry keyed by corporation (if any), as well as all its nested GovernanceFrameworkVersion and GovernanceFrameworkDocument entries. If active_gf_only is true, return only nested GovernanceFrameworkVersion and GovernanceFrameworkDocument entries for the active version.
§ [MOD-CO-QRY-2] List Corporations
§ [MOD-CO-QRY-2-1] List Corporations query parameters
The following parameters are optional:
modified_after(timestamp) (optional): if specified, returns onlyCorporationentries withCorporation.modifiedgreater thanmodified_after.active_gf_only(boolean) (optional): if true, include only current governance framework data. If false or null, returns everything.preferred_language(string) (optional): if set, return only one document per version, preferringpreferred_language.response_max_size(small number) (optional): default to 64. Max 1,024.
§ [MOD-CO-QRY-2-2] List Corporations query checks
If any of these checks fail, query MUST fail.
response_max_sizemust be between 1 and 1,024. Default to 64 if unspecified.
§ [MOD-CO-QRY-2-3] List Corporations execution
If all precondition checks passed, query is executed and result (may be empty) returned. If modified_after is specified, order by modified desc.
§ [MOD-CO-QRY-3] List Module Parameters
Anyone CAN run this query.
§ [MOD-CO-QRY-3-3] List Module Parameters execution
Return the list of parameters of this module as a json file:
{
"params": {
"key1": "value1",
"key2": "value2",
...
...
}
}
§ Ecosystem Module
§ [MOD-ES-MSG-1] Create New Ecosystem
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-ES-MSG-1-1] Create New Ecosystem parameters
An authorized operator that would like to create a ecosystem MUST call this method by specifying:
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.did(string) (mandatory): the did of the ecosystem that is creating the ecosystem.language(string) (mandatory): primary language tag (BCP 47) of this ecosystem.doc_url(string) (mandatory): URL where the document is published.doc_digest_sri(string) (mandatory): digest_sri of the document.
Provided document must be of the same language that the primary language of the ecosystem.
§ [MOD-ES-MSG-1-2] Create New Ecosystem precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-ES-MSG-1-2-1] Create New Ecosystem basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
did(string) (mandatory): MUST conform to the DID Syntax, as specified [DID-CORE]. -
if any existing
Ecosystementry hasdidequal to the provideddid, itscorporationMUST equal the signingcorporation; else method MUST abort (per-Ecosystem(did, corporation)consistency invariant: at any block height, allEcosystementries sharing adidare controlled by the sameCorporation). -
language(string(17)) (mandatory): MUST be a language tag (BCP 47). -
doc_url(string) (mandatory): MUST be a valid URL . -
doc_digest_sri(string) (mandatory): MUST be a valid digest_sri as specified in integrity of related resources spec. Example:sha384-MzNNbQTWCSUSi0bbz7dbua+RcENv7C6FvlmYJ1Y+I727HsPOHdzwELMYO9Mz68M26.
Several Ecosystem entries MAY share the same ecosystem DID. The identifier of an Ecosystem is its id, and the Verifiable Trust Spec includes the id of the Ecosystem in the DID Document. Per-Ecosystem DID uniqueness is therefore NOT required: proof of control of the DID is verified by resolving the DID outside of the context of the VPR. However, all Ecosystem entries sharing the same did MUST be controlled by the same corporation — see the basic-check bullet above. Proof of control of the shared DID is, by construction, held by that single controlling Corporation, and the corresponding Corporation entry (if any whose own did equals this value) is unique by the per-Corporation did uniqueness invariant (although the Corporation that owns the DID per Corp.did and the Corporation that controls the Ecosystems claiming it need not coincide).
§ [MOD-ES-MSG-1-2-2] Create New Ecosystem fee checks
Fee payer MUST have an available balance to cover the estimated transaction fees.
§ [MOD-ES-MSG-1-3] Create New Ecosystem execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
create and persist a new
Ecosystementryecosystem: -
ecosystem.id: auto-incremented uint64 -
ecosystem.did:did -
ecosystem.corporation:corporation -
ecosystem.created: current timestamp -
ecosystem.modified:ecosystem.created -
ecosystem.language:language -
ecosystem.active_version: 1 -
create and persist a new
GovernanceFrameworkVersionentrygfv: -
gfv.id: auto-incremented uint64 -
gfv.ecosystem_id:ecosystem.id -
gfv.corporation: null -
gfv.created: current timestamp -
gfv.version: 1 -
gfv.active_since: current timestamp -
create and persist a new
GovernanceFrameworkDocumententrygfd: -
gfd.id: auto-incremented uint64 -
gfd.gfv_id:gfv.id -
gfd.created: current timestamp -
gfd.language:language -
gfd.url:doc_url -
gfd.digest_sri:doc_digest_sri
Subsequent governance framework documents and version activations for this ecosystem MUST be managed through [MOD-GF-MSG-1] and [MOD-GF-MSG-2].
§ [MOD-ES-MSG-2] Update Ecosystem
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-ES-MSG-2-1] Update Ecosystem parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory): the id of the ecosystem.did(string) (mandatory): the did of the ecosystem.
§ [MOD-ES-MSG-2-2] Update Ecosystem precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-ES-MSG-2-2-1] Update Ecosystem basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
id(uint64) (mandatory): aEcosystementryecosystemwith ididMUST exist andcorporationexecuting the method MUST be thecorporationof theEcosystementryecosystem. -
did(string) (mandatory): MUST conform to the DID Syntax, as specified [DID-CORE]. -
if any other
Ecosystementry (i.e., anyEcosystementry whoseiddiffers from the suppliedid) hasdidequal to the provideddid, itscorporationMUST equal the signingcorporation; else method MUST abort (per-Ecosystem(did, corporation)consistency invariant). Rotatingecosystem.didto a value already held by anotherEcosystemcontrolled by a differentcorporationis forbidden.
§ [MOD-ES-MSG-2-2-2] Update Ecosystem fee checks
Fee payer must have available balance in its account to cover the required transaction fees.
§ [MOD-ES-MSG-2-3] Update Ecosystem execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
load
Ecosystementryecosystemfromidand set: -
ecosystem.did:did -
ecosystem.modified: current timestamp
§ [MOD-ES-MSG-3] Archive Ecosystem
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-ES-MSG-3-1] Archive Ecosystem parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory) id of the ecosystem (mandatory);archive(boolean) (mandatory), true means archive, false means unarchive.
§ [MOD-ES-MSG-3-2] Archive Ecosystem precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-ES-MSG-3-2-1] Archive Ecosystem basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
load
Ecosystemecosystemfromid.ecosystem.corporationMUST be the corporation executing the method, else MUST abort. -
archive(boolean) (mandatory) MUST be a boolean.- If
archiveis true andecosystem.archivedis not null, MUST abort asEcosystemis already archived. - If
archiveis false andecosystem.archivedis null, MUST abort asEcosystemis already not archived.
- If
§ [MOD-ES-MSG-3-2-2] Archive Ecosystem fee checks
Fee payer MUST have an available balance in its account to cover the required transaction fees.
§ [MOD-ES-MSG-3-3] Archive Ecosystem execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- update
Ecosystementryecosystemwithecosystem.idequal toid: - if
archivedis true: setecosystem.archivedto current timestamp. - if
archivedis false: setecosystem.archivedto null. ecosystem.modified: current timestamp
§ [MOD-ES-MSG-4] Update Module Parameters
Update Module Parameters.
Can only be executed through a governance proposal.
§ [MOD-ES-MSG-4-1] Update Module Parameters parameters
params(KeySet<String, String>): the parameters to update and their values.
§ [MOD-ES-MSG-4-2] Update Module Parameters precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-ES-MSG-4-2-1] Update Module Parameters basic checks
params: size ofparamsMUST be greater than 0. For eachparam<key,value>keyMUST exist, else abort.
§ [MOD-ES-MSG-4-2-2] Update Module Parameters fee checks
provided transaction fees MUST be sufficient for execution
§ [MOD-ES-MSG-4-3] Update Module Parameters execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
for each parameter param <key, value> in parameters:
- update parameter set value =
valuewhere key =key.
§ [MOD-ES-QRY-1] Get Ecosystem
Anyone CAN execute this method.
§ [MOD-ES-QRY-1-1] Get Ecosystem parameters
id(uint64) (mandatory): id of the ecosystem.active_gf_only(boolean) (optional): if true, include only current governance framework data. If false or null, returns everything.preferred_language(string) (optional): if set, return only one document per version, with language=preferred_languagewhen possible, else if no document exist with this language, return language. If not set, return all documents of all languages.
§ [MOD-ES-QRY-1-2] Get Ecosystem checks
§ [MOD-ES-QRY-1-3] Get Ecosystem execution
return found Ecosystem entry (if any), as well as all its nested GovernanceFrameworkVersion and GovernanceFrameworkDocument entries. If active_gf_only is true, return only nested GovernanceFrameworkVersion and GovernanceFrameworkDocument entries for the active version.
§ [MOD-ES-QRY-2] List Ecosystems
§ [MOD-ES-QRY-2-1] List Ecosystems query parameters
The following parameters are optional:
corporation(group) (optional): if specified, filter by corporation.modified_after(timestamp) (optional): if specified, returns onlyEcosystementries withEcosystem.modifiedgreater thanmodified.active_gf_only(boolean) (optional): if true, include only current governance framework data. If false or null, returns everything.preferred_language(string) (optional): if set, return only one document per version, with language=preferred_languagewhen possible, else if no document exist with this language, return language. If not set, return all documents of all languages.response_max_size(small number) (optional): default to 64. Max 1,024.
§ [MOD-ES-QRY-2-2] List Ecosystems query checks
If any of these checks fail, query MUST fail.
response_max_sizemust be between 1 and 1,024. Default to 64 if unspecified.
§ [MOD-ES-QRY-2-3] List Ecosystems execution of the query
If all precondition checks passed, query is executed and result (may be empty) returned. If modified_after is specified, order by modified desc.
§ [MOD-ES-QRY-3] List Module Parameters
Anyone CAN run this query.
§ [MOD-ES-QRY-3-2] List Module Parameters parameters
§ [MOD-ES-QRY-3-2] List Module Parameters query checks
§ [MOD-ES-QRY-3-3] List Module Parameters execution of the query
Return the list of the existing parameters and their values.
§ [MOD-ES-QRY-3-4] List Module Parameters API result example
{
"params": {
"key1": "value1",
"key2": "value2",
...
...
}
}
§ Governance Framework Module
This module handles governance framework documents and version activation for both ecosystems and corporations. Methods are polymorphic over the owning subject: every message takes an optional ecosystem_id parameter to designate whose governance framework is being modified — if set, the target subject is that Ecosystem (and the signing corporation MUST be its controller); if not set, the target subject is the signing corporation’s own CGF (a Corporation may only edit its own CGF, so no extra parameter is needed).
The initial GovernanceFrameworkVersion and its first GovernanceFrameworkDocument are created atomically by Create New Ecosystem (and, by parallel construction, by Create New Corporation). After that, subsequent versions and documents are added through this module.
§ [MOD-GF-MSG-1] Add Governance Framework Document
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-GF-MSG-1-1] Add Governance Framework Document parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.ecosystem_id(uint64) (optional): id of the target ecosystem whose governance framework will be modified. If set, the signingcorporationMUST be the controller of the targetEcosystem. If not set, the target subject is the signingcorporation’s own CGF.doc_language(string) (mandatory): language tag (BCP 47) of the governance framework document.doc_url(string) (mandatory): URL where the document is published.doc_digest_sri(string) (mandatory): digest_sri of the document.version(int) (mandatory): targeted version.
If for a given language, a document already exists, the execution of this transaction will replace the corresponding entry. Else, a new entry is created. It is only possible to edit future versions. Active version cannot be modified.
§ [MOD-GF-MSG-1-2] Add Governance Framework Document precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-GF-MSG-1-2-1] Add Governance Framework Document basic checks
if a mandatory parameter is not present, method MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. - Define
subjectas:- if
ecosystem_idis set: theEcosystementry with this id. The entry MUST exist andsubject.corporationMUST be equal to the signingcorporation. - if
ecosystem_idis not set: theCorporationentry whose underlying group is the signingcorporation. The entry MUST exist (a Corporation may only edit its own governance framework, so no further check is required).
- if
version: there MUST exist aGovernanceFrameworkVersionentrygfvwhose owner matchessubject(i.e.,gfv.ecosystem_id = ecosystem_idif subject is an Ecosystem, elsegfv.corporation = corporation) andgfv.version = version, ORversionMUST be exactly equal to the biggestgfv.version+ 1 of allGovernanceFrameworkVersionentries owned bysubject.versionMUST be greater thansubject.active_version.doc_language(string) (mandatory): MUST be a language tag (BCP 47).doc_url(string) (mandatory): MUST be a valid URL.doc_digest_sri(string) (mandatory): MUST be a valid digest_sri as specified in integrity of related resources spec. Example:sha384-MzNNbQTWCSUSi0bbz7dbua+RcENv7C6FvlmYJ1Y+I727HsPOHdzwELMYO9Mz68M26.
§ [MOD-GF-MSG-1-2-2] Add Governance Framework Document fee checks
Fee payer MUST have the required estimated transaction fees in its account.
§ [MOD-GF-MSG-1-3] Add Governance Framework Document execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
if a
GovernanceFrameworkVersionentrygfvmatchingsubjectandversiondoes not exist, create and persist a new one:gfv.id: auto-incremented uint64gfv.ecosystem_id:ecosystem_id(or null if subject is a Corporation)gfv.corporation: the signingcorporation(or null if subject is an Ecosystem)gfv.created: current timestampgfv.version:versiongfv.active_since: null
-
if a
GovernanceFrameworkDocumententrygfdexists withgfd.gfv_id = gfv.idandgfd.language = doc_language, update it:gfd.url:doc_urlgfd.digest_sri:doc_digest_sri
-
else, create and persist a new
GovernanceFrameworkDocumententrygfd:gfd.id: auto-incremented uint64gfd.gfv_id:gfv.idgfd.created: current timestampgfd.language:doc_languagegfd.url:doc_urlgfd.digest_sri:doc_digest_sri
§ [MOD-GF-MSG-2] Increase Active Governance Framework Version
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-GF-MSG-2-1] Increase Active Governance Framework Version parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.ecosystem_id(uint64) (optional): id of the target ecosystem. If set, the signingcorporationMUST be its controller. If not set, the target subject is the signingcorporation’s own CGF.
§ [MOD-GF-MSG-2-2] Increase Active Governance Framework Version precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-GF-MSG-2-2-1] Increase Active Governance Framework Version basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
Define
subjectas:- if
ecosystem_idis set: theEcosystementry with this id. The entry MUST exist andsubject.corporationMUST be equal to the signingcorporation. - if
ecosystem_idis not set: theCorporationentry whose underlying group is the signingcorporation. The entry MUST exist.
- if
-
Find a
GovernanceFrameworkVersionentrygfvowned bysubject(matchinggfv.ecosystem_idorgfv.corporationas appropriate) whosegfv.versionis equal tosubject.active_version+ 1. If none is found, transaction MUST abort. -
Find a
GovernanceFrameworkDocumentgfdforgfd.gfv_id=gfv.idandgfd.language=subject.language. If no document is found (and thus no document exists for the default language of this version for this subject), transaction MUST abort.
§ [MOD-GF-MSG-2-2-2] Increase Active Governance Framework Version fee checks
Fee payer MUST have the required estimated transaction fees in its account.
§ [MOD-GF-MSG-2-3] Increase Active Governance Framework Version execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- Load
subject(EcosystemorCorporationas identified above). - Find a
GovernanceFrameworkVersionentrygfvowned bysubjectwhosegfv.versionis equal tosubject.active_version+ 1. - Update
subject.active_versiontosubject.active_version+ 1. - Set
subject.modifiedto current timestamp. - Set
gfv.active_sinceto current timestamp. - Persist changes.
§ [MOD-GF-QRY-1] Get Governance Framework Version
Anyone CAN execute this method.
§ [MOD-GF-QRY-1-1] Get Governance Framework Version query parameters
id(uint64) (mandatory): the id of theGovernanceFrameworkVersion.preferred_language(string) (optional): if set, return only one document per version, preferringpreferred_language. If not set, return all documents of all languages.
§ [MOD-GF-QRY-1-2] Get Governance Framework Version query checks
If any of these checks fail, query MUST fail.
id(uint64) (mandatory): MUST be a valid uint64.
§ [MOD-GF-QRY-1-3] Get Governance Framework Version execution
Return the GovernanceFrameworkVersion entry with id, including its owning subject reference (ecosystem_id or corporation) and its nested GovernanceFrameworkDocument entries (filtered by preferred_language if set).
§ [MOD-GF-QRY-2] List Governance Framework Versions
Anyone CAN execute this method.
§ [MOD-GF-QRY-2-1] List Governance Framework Versions query parameters
Exactly one of ecosystem_id and corporation MUST be set:
ecosystem_id(uint64) (conditional): filter by ecosystem. MUST be set ifcorporationis null.corporation(group) (conditional): filter by corporation (the underlying Cosmos SDK group of the targetCorporation). MUST be set ifecosystem_idis null.active_only(boolean) (optional): if true, return only the entry corresponding to the subject’sactive_version.preferred_language(string) (optional): if set, return only one document per version, preferringpreferred_language.response_max_size(small number) (optional): default to 64. Max 1,024.
§ [MOD-GF-QRY-2-2] List Governance Framework Versions query checks
If any of these checks fail, query MUST fail.
- Exactly one of
ecosystem_idandcorporationMUST be set. response_max_sizemust be between 1 and 1,024. Default to 64 if unspecified.
§ [MOD-GF-QRY-2-3] List Governance Framework Versions execution
Return the list of GovernanceFrameworkVersion entries matching the filter, with their nested GovernanceFrameworkDocument entries (filtered as above). Entries MUST be ordered by ascending version.
§ Credential Schema Module
§ [MOD-CS-MSG-1] Create New Credential Schema
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-CS-MSG-1-1] Create New Credential Schema parameters
An account that would like to create a credential schema MUST call this method by specifying:
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.ecosystem_idid of the ecosystem (mandatory);json_schemathe Json Schema of the credential (mandatory).issuer_grantor_validation_validity_period(mandatory), default to 0 (days).verifier_grantor_validation_validity_period(mandatory), default to 0 (days).issuer_validation_validity_period(mandatory), default to 0 (days).verifier_validation_validity_period(mandatory), default to 0 (days).holder_validation_validity_period(mandatory), default to 0 (days).issuer_onboarding_mode(IssuerOnbpardingMode) (mandatory).verifier_onboarding_mode(VerifierOnboardingMode) (mandatory).holder_onboarding_mode(HolderOnboardingMode) (mandatory).pricing_asset_type(PricingAssetType) (mandatory).pricing_asset(string) (mandatory).digest_algorithm(string) (mandatory): valid values are defined in the Verifiable Trust spec.
§ [MOD-CS-MSG-1-2] Create New Credential Schema precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-CS-MSG-1-2-1] Create New Credential Schema basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
ecosystem_idMUST represent an existingEcosystementryecosystemandecosystem.corporationMUST be thecorporationexecuting the method. -
json_schemaMUST be a valid Json Schema, and size must not be greater thanGlobalVariables.credential_schema_schema_max_size.$idof the Json Schema is ignored and will be replaced during execution by the auto-generated id of thisCredentialSchema. -
issuer_grantor_validation_validity_periodmust be between 0 (never expire) andGlobalVariables.credential_schema_issuer_grantor_validation_validity_period_max_daysdays. -
verifier_grantor_validation_validity_periodmust be between 0 (never expire) andGlobalVariables.credential_schema_verifier_grantor_validation_validity_period_max_daysdays. -
issuer_validation_validity_periodmust be between 0 (never expire) andGlobalVariables.credential_schema_issuer_validation_validity_period_max_daysdays. -
verifier_validation_validity_periodmust be between 0 (never expire) andGlobalVariables.credential_schema_verifier_validation_validity_period_max_daysdays. -
holder_validation_validity_periodmust be between 0 (never expire) andGlobalVariables.credential_schema_holder_validation_validity_period_max_daysdays. -
issuer_onboarding_mode(IssuerOnbpardingMode) (mandatory). MUST be a valid IssuerOnboardingMode. -
verifier_onboarding_mode(VerifierOnboardingMode) (mandatory). MUST be a valid VerifierOnboardingMode. -
holder_onboarding_mode(HolderOnboardingMode) (mandatory). MUST be a valid HolderOnboardingMode. -
digest_algorithm(string) (mandatory) MUST be a valid digest algorithm as defined in the Verifiable Trust spec. -
pricing_asset_type(PricingAssetType) (mandatory): used asset for paying business fees. Can be TU (Trust Unit), COIN (a token available on the VPR chain), FIAT (means chain is used for settlement only and payment is done off-chain). Not that in all cases, trust deposits are always handled indenom. -
pricing_asset(string) (mandatory):"tu"ifpricing_asset_typeis set to TU, else examples: COIN:denom"uvna","ufoo","ibc/3A0F9C2E4E2A9B7D6F...","factory/verana1.../ueurv", FIAT:"EUR","GBP",…
When pricing_currency is set to FIAT, pricing_asset MUST be an ISO-4217 currency code. The number of decimals and minor unit semantics MUST follow the ISO-4217 standard for that currency. FIAT amounts MUST be expressed in minor units and MUST NOT be represented as on-chain coins. FIAT metadata SHOULD be pulled from a standard library. It MUST NOT be stored on chain.
§ [MOD-CS-MSG-1-2-2] Create New Credential Schema fee checks
Fee payer MUST have an available balance in its account, to cover the required estimated transaction fees.
§ [MOD-CS-MSG-1-3] Create New Credential Schema execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
create and persist a new
CredentialSchemaentrycs:cs.id: auto-incremented uint64.cs.ecosystem_id: id of theEcosystementry that will be the owner ofcs.cs.json_schema:json_schema, with VPR_CREDENTIAL_SCHEMA_ID string replaced by generatedcs.id, and then canonicalize it using the JSON Canonicalization Scheme (JCS) as defined in RFC 8785. Schema MUST be saved canonized.cs.issuer_grantor_validation_validity_period:issuer_grantor_validation_validity_periodcs.verifier_grantor_validation_validity_period:verifier_grantor_validation_validity_periodcs.issuer_validation_validity_period:issuer_validation_validity_periodcs.verifier_validation_validity_period:verifier_validation_validity_periodcs.holder_validation_validity_period:holder_validation_validity_periodcs.issuer_onboarding_mode:issuer_onboarding_modecs.verifier_onboarding_mode:verifier_onboarding_modecs.holder_onboarding_mode:holder_onboarding_modecs.created: current timestampcs.modified:cs.created.cs.pricing_asset_type:pricing_asset_typecs.pricing_asset:pricing_assetcs.digest_algorithm:digest_algorithm
If needed, depending on configuration mode, Ecosystem controller MAY need to create a ECOSYSTEM Participant so that onboarding processes can be run.
§ [MOD-CS-MSG-2] Update Credential Schema
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-CS-MSG-2-1] Update Credential Schema parameters
An account that would like to update a credential schema MUST call this method by specifying:
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.idid of the credential schema (mandatory);issuer_grantor_validation_validity_period(mandatory), default to 0 (days).verifier_grantor_validation_validity_period(mandatory), default to 0 (days).issuer_validation_validity_period(mandatory), default to 0 (days).verifier_validation_validity_period(mandatory), default to 0 (days).holder_validation_validity_period(mandatory), default to 0 (days).
other attributes are immutables and cannot be updated.
§ [MOD-CS-MSG-2-2] Update Credential Schema precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-CS-MSG-2-2-1] Update Credential Schema basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
idMUST represent an existingCredentialSchemaentrycs. -
load
Ecosystemecosystemfromcs.ecosystem_id.ecosystem.corporationMUST be thecorporationexecuting the method, else MUST abort. -
issuer_grantor_validation_validity_periodMUST be between 0 (never expire) andGlobalVariables.credential_schema_issuer_grantor_validation_validity_period_max_daysdays. -
verifier_grantor_validation_validity_periodMUST be between 0 (never expire) andGlobalVariables.credential_schema_verifier_grantor_validation_validity_period_max_daysdays. -
issuer_validation_validity_periodMUST be between 0 (never expire) andGlobalVariables.credential_schema_issuer_validation_validity_period_max_daysdays. -
verifier_validation_validity_periodMUST be between 0 (never expire) andGlobalVariables.credential_schema_verifier_validation_validity_period_max_daysdays. -
holder_validation_validity_periodMUST be between 0 (never expire) andGlobalVariables.credential_schema_holder_validation_validity_period_max_daysdays.
§ [MOD-CS-MSG-2-2-2] Update Credential Schema fee checks
Fee payer MUST have an available balance in its account to cover the required transaction fees.
§ [MOD-CS-MSG-2-3] Update Credential Schema execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
update
CredentialSchemaentrycswithcs.idequal toid:cs.issuer_grantor_validation_validity_period:issuer_grantor_validation_validity_periodcs.verifier_grantor_validation_validity_period:verifier_grantor_validation_validity_periodcs.issuer_validation_validity_period:issuer_validation_validity_periodcs.verifier_validation_validity_period:verifier_validation_validity_periodcs.holder_validation_validity_period:holder_validation_validity_periodcs.modified: current timestamp.
§ [MOD-CS-MSG-3] Archive Credential Schema
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-CS-MSG-3-1] Archive Credential Schema parameters
An account that would like to archive or unarchive a credential schema MUST call this method by specifying:
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory) id of the credential schema (mandatory);archive(boolean) (mandatory), true means archive, false means unarchive.
§ [MOD-CS-MSG-3-2] Archive Credential Schema precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-CS-MSG-3-2-1] Archive Credential Schema basic checks
-
if a mandatory parameter is not present, method MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
idMUST represent an existingCredentialSchemaentrycs. -
load
Ecosystemecosystemfromcs.ecosystem_id.ecosystem.corporationMUST be thecorporationexecuting the method, else MUST abort. -
archive(boolean) (mandatory) MUST be a boolean.- If
archiveis true andcs.archivedis not null, MUST abort as Credential Schema is already archived. - If
archiveis false andcs.archivedis null, MUST abort as Credential Schema is already not archived.
- If
§ [MOD-CS-MSG-3-2-2] Archive Credential Schema fee checks
Fee payer MUST have an available balance in its account to cover the required transaction fees.
§ [MOD-CS-MSG-3-3] Archive Credential Schema execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
update
CredentialSchemaentrycswithcs.idequal toid: -
if
archivedis true: setcs.archivedto current timestamp. -
if
archivedis false: setcs.archivedto null. -
set
cs.modifiedto current timestamp.
§ [MOD-CS-MSG-4] Update Module Parameters
Update Module Parameters.
Can only be executed through a governance proposal.
§ [MOD-CS-MSG-4-1] Update Module Parameters parameters
params(KeySet<String, String>): the parameters to update and their values.
§ [MOD-CS-MSG-4-2] Update Module Parameters precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-CS-MSG-4-2-1] Update Module Parameters basic checks
params: size ofparamsMUST be greater than 0. For eachparam<key,value>keyMUST exist, else abort.
§ [MOD-CS-MSG-4-2-2] Update Module Parameters fee checks
provided transaction fees MUST be sufficient for execution
§ [MOD-CS-MSG-4-3] Update Module Parameters execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
for each parameter param <key, value> in parameters:
- update parameter set value =
valuewhere key =key.
§ [MOD-CS-MSG-5] Create Schema Authorization Policy
Any authorized operator CAN execute this method on behalf of a corporation.
This message creates a draft SchemaAuthorizationPolicy for a given (schema_id, role), or overwrites the existing draft policy if one already exists.
A draft policy is defined as a policy with effective_from == null and MUST NOT be revoked.
Accordingly, if a credential schema defines one or more active policies for the ISSUER or VERIFIER role, the corresponding corporation that grants the ISSUER or VERIFIER role for this schema (ISSUER_GRANTOR, VERIFIER_GRANTOR, or ECOSYSTEM, depending on how schema issuer and verifier modes have been configured) MUST issue an IAC or VAC credential to the candidate upon successful completion of the onboarding process. Refer to the Verifiable Trust spec for more information.
§ [MOD-CS-MSG-5-1] Create Schema Authorization Policy parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.schema_id(uint64): id of the relatedCredentialSchema(mandatory).role(SchemaAuthorizationPolicyRole):ISSUERorVERIFIER(mandatory).url(string): URL where the policy document is published (mandatory).digest_sri(string): SRI digest of the policy document (mandatory).
§ [MOD-CS-MSG-5-2] Create Schema Authorization Policy precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-CS-MSG-5-2-1] Create Schema Authorization Policy basic checks
- if a mandatory parameter is not present, method MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. schema_idMUST reference an existingCredentialSchemaentry controlled bycorporation.roleMUST be a validSchemaAuthorizationPolicyRole.urlMUST be a non-empty valid URI.digest_sriMUST be non-empty.- there MUST NOT exist more than one policy for
(schema_id, role)witheffective_from == nullandrevoked == false.
§ [MOD-CS-MSG-5-2-2] Create Schema Authorization Policy fee checks
Fee payer MUST have an available balance in its account to cover the required estimated transaction fees.
§ [MOD-CS-MSG-5-3] Create Schema Authorization Policy execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs:
- if a draft policy exists for
(schema_id, role):- update the existing policy by setting:
url = urldigest_sri = digest_sri
- update the existing policy by setting:
- otherwise, create and persist a new
SchemaAuthorizationPolicyentrysap:sap.id: auto-incremented uint64sap.schema_id:schema_idsap.role:rolesap.version: max existing version for(schema_id, role)+ 1, or1if none existsap.url:urlsap.digest_sri:digest_srisap.created: current timestampsap.effective_from:nullsap.effective_until:nullsap.revoked:false
§ [MOD-CS-MSG-6] Increase Active Schema Authorization Policy Version
Any authorized operator CAN execute this method on behalf of a corporation.
This message activates the current draft SchemaAuthorizationPolicy for the given (schema_id, role) and deactivates any previously active version. Deactivation does not constitute revocation; credentials issued under earlier policies MAY continue to be considered valid.
§ [MOD-CS-MSG-6-1] Increase Active Schema Authorization Policy Version parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.schema_id(uint64): id of the relatedCredentialSchema(mandatory).role(SchemaAuthorizationPolicyRole):ISSUERorVERIFIER(mandatory).
§ [MOD-CS-MSG-6-2] Increase Active Schema Authorization Policy Version precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-CS-MSG-6-2-1] Basic checks
- if a mandatory parameter is not present, method MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. schema_idMUST reference an existingCredentialSchemaentry controlled bycorporation.- exactly one draft policy MUST exist for
(schema_id, role)witheffective_from == nullandrevoked == false. - the draft policy MUST have non-empty
urlanddigest_sri.
§ [MOD-CS-MSG-6-2-2] Fee checks
Fee payer MUST have an available balance in its account to cover the required estimated transaction fees.
§ [MOD-CS-MSG-6-3] Increase Active Schema Authorization Policy Version execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks atomically in a transaction:
- let
draftbe the unique policy witheffective_from == nullandrevoked == false. - let
prev_activebe the active policy for(schema_id, role), if any. - set
draft.effective_from = now. - if
prev_activeexists:- set
prev_active.effective_until = now.
- set
§ [MOD-CS-MSG-7] Revoke Schema Authorization Policy
Any authorized operator CAN execute this method on behalf of a corporation.
This message revokes a previously enabled SchemaAuthorizationPolicy version. Revoked means previously issued credential that refer to this policy are automatically considered revoked.
§ [MOD-CS-MSG-7-1] Revoke Schema Authorization Policy parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.schema_id(uint64): id of the relatedCredentialSchema(mandatory).role(SchemaAuthorizationPolicyRole):ISSUERorVERIFIER(mandatory).version(integer): policy version to revoke (mandatory).
§ [MOD-CS-MSG-7-2] Revoke Schema Authorization Policy precondition checks
If any of these precondition checks fail, method MUST abort.
§ [MOD-CS-MSG-7-2-1] Basic checks
- if a mandatory parameter is not present, method MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. - a policy MUST exist for
(schema_id, role, version). - the targeted policy MUST have
effective_from != null(a policy that has never been enabled MUST NOT be revoked). - the targeted policy MUST NOT already be revoked.
§ [MOD-CS-MSG-7-2-2] Fee checks
Fee payer MUST have an available balance in its account to cover the required estimated transaction fees.
§ [MOD-CS-MSG-7-3] Revoke Schema Authorization Policy execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following task in a transaction:
- set
revoked = trueon the targetedSchemaAuthorizationPolicyentry.
§ [MOD-CS-QRY-1] List Credential Schemas
§ [MOD-CS-QRY-1-1] List Credential Schemas parameters
ecosystem_id(uint64) (optional): to filter by ecosystem id.modified_after(timestamp) (optional): show schemas modified after this timestamp.response_max_size(small number) (optional): default to 64. Max 1,024.only_active(boolean): if set to true, returns only not archived entries.issuer_onboarding_mode(IssuerOnboardingMode): if set, filter byissuer_onboarding_mode.verifier_onboarding_mode(VerifierOnboardingMode): if set, filter byverifier_onboarding_mode.holder_onboarding_mode(HolderOnboardingMode): if set, filter byholder_onboarding_mode.
§ [MOD-CS-QRY-1-2] List Credential Schemas checks
modified_aftermust be a timestamp.response_max_sizemust be between 1 and 1,024.
§ [MOD-CS-QRY-1-3] List Credential Schemas execution
return a list of found entry, or an empty list if nothing found. Results MUST be ordered by modified DESC.
§ [MOD-CS-QRY-2] Get Credential Schema
Anyone CAN execute this method.
§ [MOD-CS-QRY-2-1] Get Credential Schema parameters
idof the credential schema (mandatory);
§ [MOD-CS-QRY-2-2] Get Credential Schema checks
idmust be a uint64.
§ [MOD-CS-QRY-2-3] Get Credential Schema execution
return found entry (if any).
§ [MOD-CS-QRY-3] Render Json Schema
Anyone CAN execute this method.
§ [MOD-CS-QRY-3-1] Render Json Schema parameters
idof the credential schema (mandatory);
§ [MOD-CS-QRY-3-2] Render Json Schema checks
idmust be a uint64.
§ [MOD-CS-QRY-3-3] Render Json Schema execution
Render found entry (if any). In case value is returned by a REST API, content type MUST be set to “application/schema+json”.
Schema MUST be rendered cononized, even if it was not created canonized using the JSON Canonicalization Scheme (JCS) as defined in RFC 8785.
§ [MOD-CS-QRY-4] List Module Parameters
Anyone CAN run this query.
§ [MOD-CS-QRY-4-2] List Module Parameters parameters
§ [MOD-CS-QRY-4-2] List Module Parameters query checks
§ [MOD-CS-QRY-4-3] List Module Parameters execution of the query
Return the list of the existing parameters and their values.
§ [MOD-CS-QRY-4-4] List Module Parameters API result example
{
"params": {
"key1": "value1",
"key2": "value2",
...
...
}
}
§ [MOD-CS-QRY-5] Get Schema Authorization Policy
This query returns a single SchemaAuthorizationPolicy identified by its unique id.
§ [MOD-CS-QRY-5-1] Get Schema Authorization Policy parameters
id(uint64): unique identifier of theSchemaAuthorizationPolicy(mandatory).
§ [MOD-CS-QRY-5-2] Get Schema Authorization Policy precondition checks
If any of these precondition checks fail, query MUST abort.
idMUST be provided.- a
SchemaAuthorizationPolicyentry with the givenidMUST exist.
§ [MOD-CS-QRY-5-3] Get Schema Authorization Policy execution
If all precondition checks pass, the query MUST return the corresponding
SchemaAuthorizationPolicy entry:
idschema_idroleversionurldigest_sricreatedeffective_fromeffective_untilrevoked
§ [MOD-CS-QRY-6] List Schema Authorization Policies
This query returns the list of SchemaAuthorizationPolicy entries associated
with a given (schema_id, role) pair.
§ [MOD-CS-QRY-6-1] List Schema Authorization Policies parameters
schema_id(uint64): id of the relatedCredentialSchema(mandatory).role(SchemaAuthorizationPolicyRole):ISSUERorVERIFIER(mandatory).
§ [MOD-CS-QRY-6-2] List Schema Authorization Policies precondition checks
If any of these precondition checks fail, query MUST abort.
schema_idMUST be provided.roleMUST be a validSchemaAuthorizationPolicyRole.schema_idMUST reference an existingCredentialSchemaentry.
§ [MOD-CS-QRY-6-3] List Schema Authorization Policies execution
If all precondition checks pass, the query MUST return the list of
SchemaAuthorizationPolicy entries matching (schema_id, role).
Returned entries MUST include at least the following fields:
idschema_idroleversionurldigest_sricreatedeffective_fromeffective_untilrevoked
Entries MUST be ordered by ascending version.
§ Participant Module
§ Participant Module Overview
This section is non-normative.
Participants are linked to a Credential Schema and representable as a tree.
ECOSYSTEM Participants are created directly by the credential schema owner. All other Participants are created by running an onboarding process — except when onboarding mode is set to OPEN for ISSUER and/or VERIFIER Participants, which any account CAN create directly:
ISSUERParticipants whenissuer_onboarding_modeisOPEN;VERIFIERParticipants whenverifier_onboarding_modeisOPEN.
An onboarding process (OP) involves an applicant (the corporation of a given Participant entry) and a validator Participant. It MAY require the applicant to pay validation_fees in addition to transaction fees.
An onboarding process is run by applicants that want to:
- be an issuer of a specific credential schema;
- be a verifier of a specific credential schema;
- be an issuer grantor of a specific credential schema;
- be a verifier grantor of a specific credential schema;
- get issued a credential of a specific credential schema;
- obtain a
HOLDERParticipant entry from an issuer of a specific credential schema and be issued a verifiable credential of that schema (theHOLDERParticipant entry carries credential status — revoked, etc.).
In all cases, the process is very similar. Example execution of an onboarding process:
- The applicant starts an onboarding process by running [MOD-PP-MSG-1]. The process MAY be subject to paying
validation_fees, as defined in the validator's Participant entry. - The applicant connects to the validator's VS (identified by its DID) and executes the validation steps required for the onboarding process to conclude.
- If the applicant qualifies, the validator runs [MOD-PP-MSG-3] to update the Participant entry; the applicant is then granted the new
Participantentries and/or issued a credential.
Once in the VALIDATED state, a Participant entry remains valid for a specific period (e.g., 365 days), configured in the credential schema for credential-schema-related onboarding, or set by the ecosystem for user-agent onboarding.
Even when the Participant entry remains in the VALIDATED state for the configured period, the resulting Participant entry or issued credential MAY have a shorter expiration timestamp because the validated attribute(s) might expire earlier. In this case, the applicant MUST provide updated information to the validator before attribute expiration in order to be issued an updated Participant entry and/or credential.
If the VALIDATED state is set to expire, an applicant that wishes to extend the expiration timestamp MUST renew its onboarding process (see [MOD-PP-MSG-2]).
At any time, the applicant CAN cancel the onboarding process (see [MOD-PP-MSG-6]).
Some unexpected situations may arise and MUST be mitigated. Examples:
- if the selected validator Participant entry is revoked while the applicant is in
PENDINGstate: applicant CAN cancel the onboarding process (see [MOD-PP-MSG-6]); - if the selected validator Participant entry is revoked while the applicant is in
VALIDATEDstate: applicant CAN renew the onboarding process by choosing a new validator (see [MOD-PP-MSG-2]).
§ [MOD-PP-MSG-1] Start Participant OP
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-PP-MSG-1-1] Start Participant OP parameters
An Applicant that would like to start an onboarding process MUST execute this method by specifying:
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.vs_operator(account) (optional): the account of the Veriable Service we want to authorize to create participant sessions linked to this participant. If not specified, Verifiable Service will not be able to use the payment delegation feature. Required to use the payment delegation feature.role(ParticipantRole) (mandatory): (ISSUER_GRANTOR, VERIFIER_GRANTOR, ISSUER, VERIFIER, HOLDER): the Participant role that the applicant would like to get;validator_participant_id(uint64) (mandatory): the validator participant (parent participant in the tree), chosen by the applicant.validation_fees(number) (optional): Requested validation_fees for this participant (can be modified by validator).issuance_fees(number) (optional): Requested issuance_fees for thisParticipantentry (can be modified by validator).verification_fees(number) (optional): Requested verification_fees for thisParticipantentry (can be modified by validator).did(string) (required): MUST conform to the DID Syntax, as specified [DID-CORE].
The following VS Operator Authorization parameters are optional and collectively define the initial ParticipantAuthorizationRecord that will be created for this Participant entry. Presence of vs_operator_authz_msg_types is the trigger: if it is not provided, no authorization record is created and the Participant entry operates in manual mode (the corporation signs and pays for its own Participant-related transactions directly). VSOA configuration is frozen at creation time and cannot be modified later; to change it, the Participant entry MUST be revoked and re-created.
vs_operator_authz_msg_types[](msg_type[]) (optional): list of VPR delegable message typesvs_operatoris authorized to execute on behalf ofcorporationin the context of thisParticipantentry. If provided, aParticipantAuthorizationRecordis created (see execution below) andvs_operatorMUST be specified. The permitted list of message types is provided below.vs_operator_authz_spend_limit(DenomAmount[]) (optional): maximum amount of fundsvs_operatoris allowed to spend in the context of thisParticipantentry as a direct consequence of executing authorized messages.vs_operator_authz_with_feegrant(bool) (optional, default: false): if true,corporationpays transaction fees forvs_operatorvia an on-chainFeeGrantwhen executing authorized messages in the context of thisParticipantentry.vs_operator_authz_fee_spend_limit(DenomAmount[]) (optional): maximum total amount of transaction fees that can be spent byvs_operator(paid bycorporationvia fee grant) in the context of thisParticipantentry.vs_operator_authz_period(duration) (optional): reset period forvs_operator_authz_spend_limitandvs_operator_authz_fee_spend_limitin the context of thisParticipantentry.
Permitted message types to be set in vs_operator_authz_msg_types depends on role.
| Participant role | Permitted Messages |
|---|---|
| HOLDER | TriggerResolver |
| ISSUER | CreateOrUpdateParticipantSession, SetParticipantOPtoValidated |
| VERIFIER | CreateOrUpdateParticipantSession |
| ISSUER_GRANTOR | SetParticipantOPtoValidated |
| VERIFIER_GRANTOR | SetParticipantOPtoValidated |
| ECOSYSTEM | SetParticipantOPtoValidated |
Available compatible perms can be found by using an indexer and presented in a front-end so applicant can choose its validator.
§ [MOD-PP-MSG-1-2] Start Participant OP precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-1-2-1] Start Participant OP basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. role(ParticipantRole) (mandatory) MUST be a valid ParticipantRole: ISSUER_GRANTOR, VERIFIER_GRANTOR, ISSUER, VERIFIER, HOLDER.validator_participant_id(uint64) (mandatory): see MOD-PP-MSG-1-2-2.validation_fees(number) (optional): Requested validation_fees for thisParticipantentry (can be modified by validator).issuance_fees(number) (optional): Requested issuance_fees for thisParticipantentry (can be modified by validator).verification_fees(number) (optional): Requested verification_fees for thisParticipantentry (can be modified by validator).did, if specified, MUST conform to the DID Syntax, as specified [DID-CORE].- if
didis specified and any existingParticipantentry has non-nulldidequal to the provideddid, itscorporationMUST equal the signingcorporation; else method MUST abort (per-Participant(did, corporation)consistency invariant: at any block height, allParticipantentries sharing a non-nulldidare owned by the sameCorporation). - VS Operator Authorization parameters: if any of
vs_operator_authz_*parameters is provided,vs_operator_authz_msg_typesMUST also be provided andvs_operatorMUST NOT be null, else abort. Ifvs_operator_authz_msg_typesis provided, it MUST be a non-empty list of VPR delegable message types, and match the permitted messages defined in MOD-PP-MSG-1-1.
A holder MAY directly connect to the DID VS of an issuer in order to get issued a credential. It’s up to the issuer to decide if running the onboarding process is REQUIRED or not.
§ [MOD-PP-MSG-1-2-2] Start Participant OP permission checks
-
Load
Participantentryvalidator_participantfromvalidator_participant_id. It MUST be a active participant else transaction MUST abort. -
Load
CredentialSchemaentrycsfromvalidator_participant.schema_id. It MUST exist. -
if
role(ParticipantRole) is equal to ISSUER:-
if
cs.issuer_onboarding_modeis equal to GRANTOR_ONBOARDING_PROCESS:validator_participant.roleMUST be ISSUER_GRANTOR, else MUST abort. -
else if
cs.issuer_onboarding_modeis equal to ECOSYSTEM_ONBOARDING_PROCESS:validator_participant.roleMUST be ECOSYSTEM, else MUST abort. -
else MUST abort.
-
-
else if
role(ParticipantRole) is equal to ISSUER_GRANTOR:-
if
cs.issuer_onboarding_modeis equal to GRANTOR_ONBOARDING_PROCESS:validator_participant.roleMUST be ECOSYSTEM, else MUST abort. -
else abort.
-
-
else if
role(ParticipantRole) is equal to VERIFIER:-
if
cs.verifier_onboarding_modeis equal to GRANTOR_ONBOARDING_PROCESS:validator_participant.roleMUST be VERIFIER_GRANTOR, else MUST abort. -
else if
cs.verifier_onboarding_modeis equal to ECOSYSTEM_ONBOARDING_PROCESS:validator_participant.roleMUST be ECOSYSTEM, else MUST abort. -
else abort.
-
-
else if
role(ParticipantRole) is equal to VERIFIER_GRANTOR:-
if
cs.verifier_onboarding_modeis equal to GRANTOR_ONBOARDING_PROCESS:validator_participant.roleMUST be ECOSYSTEM, else MUST abort. -
else abort.
-
-
else if
role(ParticipantRole) is equal to HOLDER:-
if
cs.holder_onboarding_modeis equal to ISSUER_ONBOARDING_PROCESS:validator_participant.roleMUST be ISSUER, else MUST abort. -
else abort.
-
At the end, if a active participant validator_participant is not found, transaction MUST abort.
§ [MOD-PP-MSG-1-2-3] Start Participant OP fee checks
-
Load
Participantentryvalidator_participantfromvalidator_participant_id. -
Load
CredentialSchemaentrycsfromvalidator_participant.schema_id. -
Fee payer MUST have an available balance in its account, to cover the estimated transaction fees;
If a conversion is needed below, use Get Price to convert amounts to native denom:
- For trust fees:
if (cs.pricing_asset_type, cs.pricing_asset) is set to (COIN, [[ref: native denom]]):
corporationMUST have an available balance in its account, to cover the following trust fees.- the required
validation_fees_in_denom=validator_participant.validation_feesin native denom. - the required
validation_trust_deposit_in_native_denom:validation_fees_in_denom*GlobalVariables.trust_deposit_ratein native denom.
- the required
else if (cs.pricing_asset_type, cs.pricing_asset) is set to (TU, "tu"):
corporationMUST have an available balance in its account, to cover the following trust fees.- the required
validation_fees_in_denom= getPrice(cs.pricing_asset_type,cs.pricing_asset,COIN,[[ref: native denom]],validator_participant.validation_fees) in native denom; - the required
validation_trust_deposit_in_native_denom:validation_fees_in_denom*GlobalVariables.trust_deposit_ratein native denom.
- the required
else if (cs.pricing_asset_type, cs.pricing_asset) is set to an arbitrary coin (COIN, [[ref: denom]]):
corporationMUST have an available balance in its account, to cover the following trust fees.- the required
validation_fees_in_denom=validator_participant.validation_feesin specified (cs.pricing_asset_type, cs.pricing_asset) - the required
validation_trust_deposit_in_native_denom: getPrice(cs.pricing_asset_type,cs.pricing_asset,COIN,[[ref: native denom]],validation_fees_in_denom) *GlobalVariables.trust_deposit_ratein native denom.
- the required
else if (cs.pricing_asset_type, cs.pricing_asset) is set to an arbitrary coin (FIAT, [[ref: denom]]):
corporationMUST have an available balance in its account, to cover the following trust fees.- the required
validation_fees_in_denom= 0 in native denom. - the required
validation_trust_deposit_in_native_denom: getPrice(cs.pricing_asset_type,cs.pricing_asset,COIN,[[ref: native denom]],validator_participant.validation_fees) *GlobalVariables.trust_deposit_ratein native denom.
- the required
Trust deposit MUST always be paid in native denom
§ [MOD-PP-MSG-1-2-4] Start Participant OP overlap checks
We want to make sure that 2 onboarding processes cannot be active at the same time in the same context. This does not prevent a corporation from running different OP with differents validators for the same schema_id, role.
Find all Participant entries participants[] for schema_id, role, validator_participant_id, corporation with op_state = VALIDATED or PENDING.
if size of participants[] > 0, it means there is already an existing onboarding process in this context, so MUST abort.
note: this check was not present in v3.
§ [MOD-PP-MSG-1-3] Start Participant OP execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
Load
Participantentryvalidator_participantof the selected validator. -
calculate
validation_fees_in_denomandvalidation_trust_deposit_in_native_denomas explained above in fee checks. -
use [MOD-TD-MSG-1] to increase by
validation_trust_deposit_in_native_denomthe trust deposit ofcorporationrunning the method and transfer the corresponding amount toTrustDepositmodule. -
send
validation_fees_in_denomto validation escrow account, if greater than 0. -
define
now: current timestamp. -
create an persist a new
Participantentryapplicant_participant:applicant_participant.id: auto-incremented uint64.applicant_participant.schema_id=validator_participant.schema_idapplicant_participant.corporation:corporation.applicant_participant.vs_operator:vs_operator.applicant_participant.role:role.applicant_participant.created:nowapplicant_participant.modified:nowapplicant_participant.deposit:validation_trust_deposit_in_native_denom.applicant_participant.validation_fees:validation_fees.applicant_participant.issuance_fees:issuance_fees.applicant_participant.verification_fees:verification_fees.applicant_participant.validator_participant_id:validator_participant_id.applicant_participant.op_last_state_change:nowapplicant_participant.op_state: PENDING.applicant_participant.op_current_fees(number):validation_fees_in_denom.applicant_participant.op_current_deposit(number):validation_trust_deposit_in_native_denom.applicant_participant.op_summary_digest: null.applicant_participant.op_validator_deposit: 0.
If vs_operator_authz_msg_types is provided, create the ParticipantAuthorizationRecord in disabled state (expiration = now) by calling [MOD-DE-MSG-5] Grant VS Operator Authorization with:
corporation:corporationvs_operator:vs_operatorrecord:record.participant_id:applicant_participant.idrecord.msg_types:vs_operator_authz_msg_typesrecord.spend_limit:vs_operator_authz_spend_limitrecord.fee_spend_limit:vs_operator_authz_fee_spend_limitrecord.with_feegrant:vs_operator_authz_with_feegrant(default: false)record.expiration:nowrecord.period:vs_operator_authz_period
Note: the record is created with
expiration = nowso authorization is not yet active. [AUTHZ-CHECK-3] will reject any attempt to use it until [MOD-PP-MSG-3] updatesexpirationtoapplicant_participant.effective_until. No on-chainFeeGrantobject is created at this stage even ifwith_feegrantis true (the recompute subroutine in [MOD-DE-MSG-5-5] requiresexpiration > now).
§ Connecting to the VS of the Validator
This section is non-normative, and provided for understanding only.
This action must be initiated by the applicant.
During an onboarding process, if the associated validator_participant includes a specific did, the applicant should establish a secure connection with the validator’s VS (Verifiable Service) using a secure communication protocol such as DIDComm.
Upon connecting to the VS, the applicant should be required by the validator to complete one or more of the following tasks:
- Prove control over the
vs_operatoraccount specified in theParticipantentry (e.g., via blind signature or cryptographic challenge). - Provide requested information, such as filling out forms, submitting documents, or other forms of disclosure as required by the validation VS.
- If the requested
Participantentry includes a VS DID, the applicant should prove control over the corresponding DID to the validator’s VS.
Once the validator determines that the process is complete, they may terminate the onboarding process and create the Participant entry accordingly. This Participant-entry configuration usually includes:
validation_feesissuance_feesverification_feesParticipantexpiration
The validator may compile a summary file of the onboarding process, documenting exchanged data, proofs, and decisions, and share it with the applicant via the VS connection or another secure channel.
For audit or governance purposes, the validator should register a digest (e.g., hash or SRI) of this summary in applicant_participant.op_summary_digest.
§ [MOD-PP-MSG-2] Renew Participant OP
Any authorized operator CAN execute this method on behalf of a corporation.
This section is non-normative.
- Requesting a renewal has no effect on
Participantexpiration or issued credentials. - Renewal is only possible with the same validator.
- If validator
Participantis not valid anymore, applicant MUST perform a new onboarding process with another validator. - Renewal does not allow changing the
participant.validation_fees,participant.issuance_fees,participant.verification_fees. To change these values, applicant MUST start a new onboarding process. - if
applicant_participantis revoked, slashed, or repaid, method MUST fail.
§ [MOD-PP-MSG-2-1] Renew Participant OP parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory): id of theParticipantentry for which applicant would like to renew the onboarding process;
§ [MOD-PP-MSG-2-2] Renew Participant OP precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-2-2-1] Renew Participant OP basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. idMUST be a valid uint64 and aParticipantentry with the same id MUST exist.
§ [MOD-PP-MSG-2-2-2] Renew Participant OP permission checks
- Load
Participantentryapplicant_participant.corporationrunning the operation MUST beapplicant_participant.corporation, else MUST abort.applicant_participantMUST be a active participant. - Load
Participantentryvalidator_participantfromapplicant_participant.validator_participant_id. It MUST exist, and be a active participant, else MUST abort.
§ [MOD-PP-MSG-2-2-3] Renew Participant OP fee checks
-
Load
Participantentryvalidator_participantfromapplicant_participant.validator_participant_id. -
Load
CredentialSchemaentrycsfromvalidator_participant.schema_id. -
Fee payer MUST have an available balance in its account, to cover the estimated transaction fees;
If a conversion is needed below, use Get Price to convert amounts to native denom:
- For trust fees:
if (cs.pricing_asset_type, cs.pricing_asset) is set to (COIN, [[ref: native denom]]):
corporationMUST have an available balance in its account, to cover the following trust fees.- the required
validation_fees_in_denom=validator_participant.validation_feesin native denom. - the required
validation_trust_deposit_in_native_denom:validation_fees_in_denom*GlobalVariables.trust_deposit_ratein native denom.
- the required
else if (cs.pricing_asset_type, cs.pricing_asset) is set to (TU, "tu"):
corporationMUST have an available balance in its account, to cover the following trust fees.- the required
validation_fees_in_denom= getPrice(cs.pricing_asset_type,cs.pricing_asset,COIN,[[ref: native denom]],validator_participant.validation_fees) in native denom; - the required
validation_trust_deposit_in_native_denom:validation_fees_in_denom*GlobalVariables.trust_deposit_ratein native denom.
- the required
else if (cs.pricing_asset_type, cs.pricing_asset) is set to an arbitrary coin (COIN, [[ref: denom]]):
corporationMUST have an available balance in its account, to cover the following trust fees.- the required
validation_fees_in_denom=validator_participant.validation_feesin specified (cs.pricing_asset_type, cs.pricing_asset) - the required
validation_trust_deposit_in_native_denom: getPrice(cs.pricing_asset_type,cs.pricing_asset,COIN,[[ref: native denom]],validation_fees_in_denom) *GlobalVariables.trust_deposit_ratein native denom.
- the required
else if (cs.pricing_asset_type, cs.pricing_asset) is set to an arbitrary coin (FIAT, [[ref: denom]]):
corporationMUST have an available balance in its account, to cover the following trust fees.- the required
validation_fees_in_denom= 0 in native denom. - the required
validation_trust_deposit_in_native_denom: getPrice(cs.pricing_asset_type,cs.pricing_asset,COIN,[[ref: native denom]],validator_participant.validation_fees) *GlobalVariables.trust_deposit_ratein native denom.
- the required
Trust deposit MUST always be paid in native denom
§ [MOD-PP-MSG-2-3] Renew Participant OP execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
Load
Participantentryapplicant_participant. -
Load
Participantentryvalidator_participantfromapplicant_participant.validator_participant_id. -
calculate
validation_fees_in_denomandvalidation_trust_deposit_in_native_denomas explained above in fee checks. -
use [MOD-TD-MSG-1] to increase by
validation_trust_deposit_in_native_denomthe trust deposit ofcorporationrunning the method and transfer the corresponding amount toTrustDepositmodule. -
send
validation_fees_in_denomto validation escrow account, if greater than 0. -
define
now: current timestamp. -
update
Participantentry:applicant_participant.op_state: PENDING.applicant_participant.op_last_state_change: current timestamp.applicant_participant.deposit:applicant_participant.deposit+validation_trust_deposit_in_native_denom.applicant_participant.op_current_fees(number):validation_fees_in_denom.applicant_participant.op_current_deposit(number):validation_trust_deposit_in_native_denom.applicant_participant.modified:now
§ [MOD-PP-MSG-3] Set Participant OP to Validated
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-PP-MSG-3-1] Set Participant OP to Validated parameters
An account that would like to set a validation entry to VALIDATED MUST execute this method by specifying:
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory): id of the onboarding process;effective_until(timestamp) (optional): timestamp until when (exclusive) thisParticipantis effective, null if no time limit should been set for thisParticipantentry or if we want it to be aligned with the onboarding process expiration timestamp calculated by this method.validation_fees(number) (mandatory): Agreed validation_fees for thisParticipantentry. Can be set only the first time this method is called (cannot be set for renewals). Use 0 for no fees.issuance_fees(number) (mandatory): Agreed issuance_fees for thisParticipantentry. Can be set only the first time this method is called (cannot be set for renewals). Use 0 for no fees.verification_fees(number) (mandatory): Agreed verification_fees for thisParticipantentry. Can be set only the first time this method is called (cannot be set for renewals). Use 0 for no fees.op_summary_digest(string) (optional): an optional digest, set by validator, of a summary of the information, proofs… provided by the applicant.issuance_fee_discount: (number) (mandatory): use 0 for no discount. Maximum 1 (100% discount). Can be set to an ISSUER_GRANTOR or ISSUERParticipantentry (if GRANTOR_ONBOARDING_PROCESS mode) or to an ISSUERParticipantentry (ECOSYSTEM_ONBOARDING_PROCESS mode) to reduce (or void) calculated issuance fees for the subtree ofParticipantentries. Note: this should generally not be used because it reduces or void commission of all related ecosystem participants.verification_fee_discount: (number) (mandatory): use 0 for no discount. Maximum 1 (100% discount). Can be set to a VERIFIER_GRANTOR or VERIFIERParticipantentry (if GRANTOR_ONBOARDING_PROCESS mode) and/or to a VERIFIERParticipantentry (ECOSYSTEM_ONBOARDING_PROCESS mode) to reduce (or void) calculated fees for the subtree ofParticipantentries. Note: this should generally not be used because it reduces or void commission of all related ecosystem participants.
§ [MOD-PP-MSG-3-2] Set Participant OP to Validated precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-3-2-1] Set Participant OP to Validated basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.idMUST be a valid uint64.- Load
Participantentryapplicant_participantfromid. If no entry found, abort. - Load
Participantentryvalidator_participantfromapplicant_participant_validator_participant_id. - Authorization:
either (executed by any operator of corporation):
[AUTHZ-CHECK-1] MUST pass for this (corporation, operator) tuple and SetParticipantOPtoValidated message.
[AUTHZ-CHECK-2] MUST pass for this (corporation, operator) tuple and SetParticipantOPtoValidated message.
OR (executed by vs-agent account defined in validator Participant):
[AUTHZ-CHECK-3] MUST pass for this (corporation, operator, validator_participant) tuple.
[AUTHZ-CHECK-4] MUST pass for this (corporation, operator, validator_participant) tuple.
else MUST abort.
-
applicant_participant.op_stateMUST be equal to PENDING, else abort. -
validation_fees(number) (mandatory): MUST be zero or a positive integer. Ifapplicant_participant.effective_fromis not null (we are in renewal)validation_feesMUST be equal toapplicant_participant.validation_fees, else abort. -
issuance_fees(number) (mandatory): MUST be zero or a positive integer. Ifapplicant_participant.effective_fromis not null (we are in renewal)issuance_feesMUST be equal toapplicant_participant.issuance_feesor, else abort. -
verification_fees(number) (mandatory): MUST be zero or a positive integer. Ifapplicant_participant.effective_fromis not null (we are in renewal)verification_feesMUST be equal toapplicant_participant.verification_fees, else abort. -
op_summary_digest(string) (optional): MUST be a valid digest. Example:sha384-MzNNbQTWCSUSi0bbz7dbua+RcENv7C6FvlmYJ1Y+I727HsPOHdzwELMYO9Mz68M26. -
Load
CredentialSchemacsfromapplicant_participant.schema_id. -
Load
Participantvalidator_participantfromapplicant_participant.validator_participant_id. -
issuance_fee_discount: (number) (mandatory):- if
applicant_participant.effective_fromis not null (renewal), thenissuance_fee_discountmust be equal toapplicant_participant.issuance_fee_discountelse MUST abort. - if
cs.issuer_onboarding_modeis set to GRANTOR_ONBOARDING_PROCESS:- if
applicant_participant.role== ISSUER_GRANTOR:issuance_fee_discountcan be set between 0 (no discount) and 1 (100% discount) inclusive. - if
applicant_participant.role== ISSUER: ifvalidator_participant.issuance_fee_discountis defined,issuance_fee_discountcan be set between 0 (no discount) andvalidator_participant.issuance_fee_discount(100% discount) inclusive.
- if
- if
cs.issuer_onboarding_modeis set to ECOSYSTEM_ONBOARDING_PROCESS:- if
applicant_participant.role== ISSUER:issuance_fee_discountcan be set between 0 (no discount) and 1 (100% discount) inclusive.
- if
- else MUST abort.
- if
-
verification_fee_discount: (number) (mandatory):- if
applicant_participant.effective_fromis not null (renewal), thenverification_fee_discountmust be equal toapplicant_participant.verification_fee_discountelse MUST abort. - if
cs.verifier_onboarding_modeis set to GRANTOR_ONBOARDING_PROCESS:- if
applicant_participant.role== VERIFIER_GRANTOR:verification_fee_discountcan be set between 0 (no discount) and 1 (100% discount) inclusive. - if
applicant_participant.role== VERIFIER: ifvalidator_participant.verification_fee_discountis defined,verification_fee_discountcan be set between 0 (no discount) andvalidator_participant.verification_fee_discount(100% discount) inclusive.
- if
- if
cs.verifier_onboarding_modeis set to ECOSYSTEM_ONBOARDING_PROCESS:- if
applicant_participant.role== VERIFIER:verification_fee_discountcan be set between 0 (no discount) and 1 (100% discount) inclusive.
- if
- else MUST abort.
- if
Calculation of op_exp, the onboarding process expiration timestamp, required to verify provided effective_until:
-
let’s define
validity_period=cs.issuer_grantor_validation_validity_period(ifapplicant_participant.roleis ISSUER_GRANTOR),cs.verifier_grantor_validation_validity_period(ifapplicant_participant.roleis VERIFIER_GRANTOR),cs.issuer_validation_validity_period(ifapplicant_participant.roleis ISSUER),cs.verifier_validation_validity_period(ifapplicant_participant.roleis VERIFIER), orcs.holder_validation_validity_period(ifapplicant_participant.roleis HOLDER). -
if
validity_periodis NULL:op_exp= NULL. -
else if
applicant_participant.op_expis null,op_exp= timestamp of now() plusvalidity_period. -
else
op_exp=applicant_participant.op_expplusvalidity_period
Now, let’s verify effective_until:
- if
effective_untilis NULL, no issue. - else if
applicant_participant.effective_untilis NULL,effective_untilMUST be greater than current current timestamp AND, ifop_expis not null, lower or equal toop_exp. - else
effective_untilMUST be greater thanapplicant_participant.effective_untilAND, ifop_expis not null, lower or equal toop_exp.
§ [MOD-PP-MSG-3-2-2] Set Participant OP to Validated validator perms
- load
validator_participantfromapplicant_participant.validator_participant_id.validator_participantMUST be a active participant. corporationrunning the method MUST bevalidator_participant.corporation.
If validator_participant is not a active participant (expired, revoked, slashed…) then applicant MUST start a new onboarding process.
§ [MOD-PP-MSG-3-2-3] Set Participant OP to Validated fee checks
- Fee payer MUST have the required estimated transaction fees in its account, else transaction MUST abort.
- if
applicant_participant.op_current_feesis not in native denom,corporationaccount MUST haveapplicant_participant.op_current_depositavailable in native denom on its account for paying the trust deposit.
§ [MOD-PP-MSG-3-2-4] Set Participant OP to Validated overlap checks
We want to make sure that 2 Participant entries cannot be active at the same time for the same validator_participant_id. That should not occur in this method, but better do the check anyway.
Find all active participants participants[] (not revoked, not slashed, not repaid) for schema_id, role, validator_participant_id, corporation.
for each Participant entry p from participants[]:
- if
p.effective_untilis greater thaneffective_from, method execution MUST abort. - if
p.effective_fromis lower thaneffective_until, method execution MUST abort. - if
p.effective_untilis NULL (never expire), creation of a newParticipantentry doesn’t make any sense and method execution MUST abort.
note: this check was not present in v3.
§ [MOD-PP-MSG-3-3] Set Participant OP to Validated execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- Load
Participantentryapplicant_participantfromid. - Load
Participantentryvalidator_participantfromapplicant_participant.validator_participant_id. - define
nowtimestamp of now().
Calculate op_exp:
-
Load
CredentialSchemacsfromapplicant_participant.schema_id. -
let’s define
validity_period=cs.issuer_grantor_validation_validity_period(ifapplicant_participant.roleis ISSUER_GRANTOR),cs.verifier_grantor_validation_validity_period(ifapplicant_participant.roleis VERIFIER_GRANTOR),cs.issuer_validation_validity_period(ifapplicant_participant.roleis ISSUER),cs.verifier_validation_validity_period(ifapplicant_participant.roleis VERIFIER), orcs.holder_validation_validity_period(ifapplicant_participant.roleis HOLDER). -
if
validity_periodis NULL:op_exp= NULL. -
else if
applicant_participant.op_expis null,op_exp= timestamp of now() plusvalidity_period. -
else
op_exp=applicant_participant.op_expplusvalidity_period.
Change value of provided effective_until if needed, and abort if needed:
-
if provided
effective_untilis NULL:- change value of provided
effective_untiltoop_exp.
- change value of provided
-
else if
applicant_participant.effective_untilis NULL:- verify that provided
effective_untilis greater thannowelse MUST abort - if
op_expis not null, verify that providedeffective_untilis lower or equal toop_expelse MUST abort
- verify that provided
-
else:
effective_untilMUST be greater thanapplicant_participant.effective_untilelse MUST abort- if
op_expis not null, verify that providedeffective_untilis lower or equal toop_expelse MUST abort.
Fees and Trust Deposits:
- transfer the full amount
applicant_participant.op_current_feesin the proper denom from escrow account to validatorcorporationaccountvalidator_participant.corporation; - Increase validator perm trust deposit: use [MOD-TD-MSG-1] to increase by
applicant_participant.op_current_depositthe trust deposit ofcorporationrunning the method and transfer the corresponding amount toTrustDepositmodule. Setapplicant_participant.op_validator_deposittoapplicant_participant.op_validator_deposit+applicant_participant.op_current_deposit.
Important: if
applicant_participant.op_current_feesis not in native denom,corporationaccount MUST haveapplicant_participant.op_current_depositavailable for paying the trust deposit.
Update Participant applicant_participant:
- set
applicant_participant.modifiedtonow. - set
applicant_participant.op_stateto VALIDATED. - set
applicant_participant.op_last_state_changetonow. - set
applicant_participant.op_current_feesto 0; - set
applicant_participant.op_current_depositto 0; - set
applicant_participant.op_summary_digesttoop_summary_digest. - set
applicant_participant.op_exptoop_exp. - set
applicant_participant.effective_untiltoeffective_until. - if
applicant_participant.effective_fromIS NULL (first time method is called for this perm, and thus we are not in a renewal):- set
applicant_participant.validation_feestovalidation_fees; - set
applicant_participant.issuance_feestoissuance_fees; - set
applicant_participant.verification_feestoverification_fees; - set
applicant_participant.effective_fromtonow. - set
applicant_participant.issuance_fee_discounttoissuance_fee_discount. - set
applicant_participant.verification_fee_discounttoverification_fee_discount.
- set
Activate VS Operator Authorization, if any. Call [MOD-DE-MSG-9] Update VS Operator Authorization Expiration with:
participant_id:applicant_participant.idnew_expiration:applicant_participant.effective_until
This call is a no-op if no record was created at [MOD-PP-MSG-1] (i.e., the applicant did not declare vs_operator_authz_msg_types). If a record exists, its expiration is updated from now (disabled) to applicant_participant.effective_until, and the on-chain FeeGrant for the containing VSOA is granted for the first time (or refreshed) via [MOD-DE-MSG-5-5].
§ [MOD-PP-MSG-4] Void
§ [MOD-PP-MSG-5] Void
§ [MOD-PP-MSG-6] Cancel Participant OP Last Request
Any authorized operator CAN execute this method on behalf of a corporation.
At any time, applicant of an onboarding process may request cancellation of the process, provided state is PENDING. Upon method execution, the pending validation is cancelled and escrewed trust fees are refunded. If op_exp is not null, op_state is set back to VALIDATED, else op_state is set to TERMINATED.
§ [MOD-PP-MSG-6-1] Cancel Participant OP Last Request parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory): id of theParticipantentry;
§ [MOD-PP-MSG-6-2] Cancel Participant OP Last Request precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-6-2-1] Cancel Participant OP Last Request basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. idMUST be a valid uint64.- Load
Participantentryapplicant_participantwith this id. It MUST exist. corporationrunning the transaction MUST beapplicant_participant.corporation.applicant_participant.op_stateMUST be PENDING.- if
applicant_participant.deposithas been slashed and not repaid, MUST abort
§ [MOD-PP-MSG-6-2-2] Cancel Participant OP Last Request fee checks
Fee payer MUST have the required estimated transaction fees in its account, else transaction MUST abort.
§ [MOD-PP-MSG-6-3] Cancel Participant OP Last Request execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
Load
Participantentryapplicant_participantwithid. It MUST exist. -
define
now: current timestamp. -
set
applicant_participant.modifiedtonow. -
if
applicant_participant.op_expis null (validation never completed), setapplicant_participant.op_stateto TERMINATED, else setapplicant_participant.op_stateto VALIDATED. -
set
applicant_participant.op_last_state_changetonow. -
if
applicant_participant.op_current_fees> 0: -
if
applicant_participant.op_current_deposit> 0:- call [MOD-TD-MSG-1] to reduce trust deposit of
applicant_participant.corporationbyapplicant_participant.op_current_deposit - set
applicant_participant.op_current_depositto 0.
- call [MOD-TD-MSG-1] to reduce trust deposit of
If applicant_participant.op_state was set to TERMINATED (i.e. applicant_participant.op_exp was null so validation never completed), call [MOD-DE-MSG-6] Revoke VS Operator Authorization with participant_id = applicant_participant.id to remove any disabled authorization record created at [MOD-PP-MSG-1]. The call is a no-op if no record exists. If applicant_participant.op_state was set back to VALIDATED, no VSOA changes are needed (the existing record’s expiration remains at the value set by the previous successful validation).
§ [MOD-PP-MSG-7] Create Root Participant
Any authorized operator CAN execute this method on behalf of a corporation.
This method is used by controller authorities of Ecosystems. When they create a Credential Schema, they need to create (a) Participant entry(ies) of role ECOSYSTEM so that other participants can run onboarding processes (if schema mode is ECOSYSTEM) or self create their Participant entries (schema mode set to OPEN).
§ [MOD-PP-MSG-7-1] Create Root Participant parameters
An account that would like to create a Participant entry MUST call this method by specifying:
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.schema_id(uint64) (mandatory)vs_operator(account) (optional): the account we want to authorize to act on behalf ofcorporationin the context of thisParticipantentry. Required for payment delegation.did(string) (mandatory): DID of the VS.effective_from(timestamp) (mandatory): timestamp from when (exclusive) this Perm is effective. MUST be in the future.effective_until(timestamp) (optional): timestamp until when (exclusive) this Perm is effective, null if it doesn’t expire. If not null, MUST be greater thaneffective_from.validation_fees(number) (mandatory): price to pay by applicant to validator for running an onboarding process that uses this perm as validator, for a given validation period, in the denom specified in the credential schema. Default to 0. Note that setting validation fees for OPEN schemas has no effect and does not mean an onboarding process must take place. For enabling onboarding processes, at least one of the two issuer, verifier mode must be different than OPEN.issuance_fees(number) (mandatory): price to pay by the issuer of a credential of this schema to the grantee of this perm when a credential is issued, in the denom specified in the credential schema. Default to 0.verification_fees(number) (mandatory): price to pay by the verifier of a credential of this schema to the grantee of this perm when a credential is verified, in the denom specified in the credential schema. Default to 0.
The following VS Operator Authorization parameters are optional and collectively define the initial ParticipantAuthorizationRecord for this Participant entry. Presence of vs_operator_authz_msg_types is the trigger: if it is not provided, no authorization record is created and the Participant entry operates in manual mode. VSOA configuration is frozen at creation time and cannot be modified later; to change it, the Participant entry MUST be revoked and re-created.
vs_operator_authz_msg_types[](msg_type[]) (optional): list of VPR delegable message typesvs_operatoris authorized to execute on behalf ofcorporationin the context of thisParticipantentry. If provided, aParticipantAuthorizationRecordis created (see execution below) andvs_operatorMUST be specified. The permitted list of message types is provided below.vs_operator_authz_spend_limit(DenomAmount[]) (optional): maximum amount of fundsvs_operatoris allowed to spend in the context of thisParticipantentry as a direct consequence of executing authorized messages.vs_operator_authz_with_feegrant(bool) (optional, default: false): if true,corporationpays transaction fees forvs_operatorvia an on-chainFeeGrantwhen executing authorized messages in the context of thisParticipantentry.vs_operator_authz_fee_spend_limit(DenomAmount[]) (optional): maximum total amount of transaction fees that can be spent byvs_operator(paid bycorporationvia fee grant) in the context of thisParticipantentry.vs_operator_authz_period(duration) (optional): reset period forvs_operator_authz_spend_limitandvs_operator_authz_fee_spend_limitin the context of thisParticipantentry.
Permitted message types to be set in vs_operator_authz_msg_types depends on role. Since Create Root Participant always creates an ECOSYSTEM Participant entry, only the following is allowed:
| Participant role | Permitted Messages |
|---|---|
| ECOSYSTEM | SetParticipantOPtoValidated |
§ [MOD-PP-MSG-7-2] Create Root Participant precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-7-2-1] Create Root Participant basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. schema_idMUST be a valid uint64 and a credential schema entry with this id MUST exist.did, if specified, MUST conform to the DID Syntax, as specified [DID-CORE].- if
didis specified and any existingParticipantentry has non-nulldidequal to the provideddid, itscorporationMUST equal the signingcorporation; else method MUST abort (per-Participant(did, corporation)consistency invariant). effective_frommust be in the future.effective_until, if not null, must be greater thaneffective_fromvalidation_fees(number) (mandatory): MUST be >= 0.issuance_fees(number) (mandatory): MUST be >= 0.verification_fees(number) (mandatory): MUST be >= 0.- VS Operator Authorization parameters: if any of
vs_operator_authz_*parameters is provided,vs_operator_authz_msg_typesMUST also be provided andvs_operatorMUST NOT be null, else abort. Ifvs_operator_authz_msg_typesis provided, it MUST be a non-empty list of VPR delegable message types, and match the permitted messages defined in MOD-PP-MSG-7-1.
§ [MOD-PP-MSG-7-2-2] Create Root Participant permission checks
To execute this method, account MUST match at least one these rules, else transaction MUST abort.
- The related
CredentialSchemaentry is loaded withschema_id, and will be namedcsin this section. - The related
Ecosystementryecosystemis loaded fromcs.ecosystem_id. corporationexecuting the method MUST beecosystem.corporation.- else MUST abort.
§ [MOD-PP-MSG-7-2-3] Create Root Participant fee checks
Fee payer MUST have the required estimated transaction fees available.
§ [MOD-PP-MSG-7-2-4] Create Root Participant overlap checks
We want to make sure that 2 Participant entries cannot be active at the same time. If corporation wishes to create a new Participant entry but the existing one never expires (or expires too far from now), corporation MUST use first the Set Participant Effective Until to set or adjust the effective_until value.
Find all active participants participants[] (not revoked, not slashed, not repaid) for schema_id, ECOSYSTEM, corporation.
Note: unlike overlap checks from other methods, here we do not need to check for
validator_participant_id, as for ECOSYSTEM-roleParticipantentries it is NULL.
for each Participant entry p from participants[]:
- if
p.effective_untilis greater thaneffective_from, method execution MUST abort. - if
p.effective_fromis lower thaneffective_until, method execution MUST abort. - if
p.effective_untilis NULL (never expire), creation of a newParticipantentry doesn’t make any sense and method execution MUST abort.
note: this check was not present in v3.
§ [MOD-PP-MSG-7-3] Create Root Participant execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- define
now: current timestamp.
A new entry Participant perm MUST be created:
participant.id: auto-incremented uint64.participant.schema_id:schema_id.participant.modifiedtonow.participant.role: ECOSYSTEM.participant.did:did.participant.corporation:corporation.participant.vs_operator:vs_operator.participant.created:nowparticipant.effective_from:effective_fromparticipant.effective_until:effective_untilparticipant.validation_fees:validation_feesparticipant.issuance_fees:issuance_feesparticipant.verification_fees:verification_feesparticipant.deposit: 0
If vs_operator_authz_msg_types is provided, create the ParticipantAuthorizationRecord in active state by calling [MOD-DE-MSG-5] Grant VS Operator Authorization with:
corporation:corporationvs_operator:vs_operatorrecord:record.participant_id:participant.idrecord.msg_types:vs_operator_authz_msg_typesrecord.spend_limit:vs_operator_authz_spend_limitrecord.fee_spend_limit:vs_operator_authz_fee_spend_limitrecord.with_feegrant:vs_operator_authz_with_feegrant(default: false)record.expiration:participant.effective_untilrecord.period:vs_operator_authz_period
Note: like [MOD-PP-MSG-14], the record is created with
expiration = participant.effective_untiland is therefore immediately active. Ifwith_feegrantis true andparticipant.effective_until > now, [MOD-DE-MSG-5-5] grants the on-chainFeeGrantas part of this execution.
§ [MOD-PP-MSG-8] Set Participant Effective Until
Any authorized operator CAN execute this method on behalf of a corporation.
This method can be called:
- by
participant.corporation, if theParticipantentry has role ECOSYSTEM. - by
participant.corporation, if it is a self-createdParticipantentry (schema configuration is open). - by a
corporationof a validatorParticipant, if theParticipantentry is managed by an OP.
§ [MOD-PP-MSG-8-1] Set Participant Effective Until parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory): id of theParticipantentry;effective_until(timestamp) (mandatory): timestamp until when (exclusive) thisParticipantwill be effective.
§ [MOD-PP-MSG-8-2] Set Participant Effective Until precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-8-2-1] Set Participant Effective Until basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. idMUST be a valid uint64.- Load
Participantentryapplicant_participantfromid. If no entry found, abort. applicant_participantMUST be a active participantapplicant_participant.effective_untilMUST be greater than now().- else MUST abort.
Note: This method can be used to both Extend or Reduce the
effective_until, or set aneffective_untilif it was null, which was not the case in spec v3.
§ [MOD-PP-MSG-8-2-2] Set Participant Effective Until advanced checks
- ECOSYSTEM
Participantentries
- if
applicant_participant.validator_participant_idis null andapplicant_participant.roleis ECOSYSTEM,corporationrunning the method MUST beapplicant_participant.corporation.
- Self-created
Participantentries
- load
validator_participantfromapplicant_participant.validator_participant_id.validator_participantMUST be a active participant of role ECOSYSTEM.corporationrunning the method MUST beapplicant_participant.corporation.
- OP-managed
Participantentries
effective_untilMUST be lower or equal toapplicant_participant.op_expelse MUST abort.- load
validator_participantfromapplicant_participant.validator_participant_id.validator_participantMUST be a active participant.corporationrunning the method MUST bevalidator_participant.corporation.
§ [MOD-PP-MSG-8-2-3] Set Participant Effective Until fee checks
Fee payer MUST have the required estimated transaction fees in its account, else transaction MUST abort.
§ [MOD-PP-MSG-8-2-4] Set Participant Effective Until overlap checks
We want to make sure that 2 Participant entries cannot be active at the same time for the same validator_participant_id. If corporation wishes to create a new Participant entry but the existing one never expires (or expires too far from now), corporation MUST use first the Set Participant Effective Until to set or adjust the effective_until value.
Find all active participants participants[] (not revoked, not slashed, not repaid) for schema_id, role, validator_participant_id, corporation.
for each Participant entry p from participants[]:
- if
p.effective_untilis greater thaneffective_from, method execution MUST abort. - if
p.effective_fromis lower thaneffective_until, method execution MUST abort. - if
p.effective_untilis NULL (never expire), creation of a newParticipantentry doesn’t make any sense and method execution MUST abort.
note: this check was not present in v3.
§ [MOD-PP-MSG-8-3] Set Participant Effective Until execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
define
now: current timestamp. -
Load
Participantentryapplicant_participantfromid. -
set
applicant_participant.effective_untiltoeffective_until -
set
applicant_participant.adjustedtonow -
set
applicant_participant.modifiedtonow
Synchronise VS Operator Authorization expiration, if any. Call [MOD-DE-MSG-9] Update VS Operator Authorization Expiration with:
participant_id:applicant_participant.idnew_expiration:applicant_participant.effective_until
This call is a no-op if no record exists for applicant_participant.id. If a record exists, its expiration is updated and the on-chain FeeGrant for the containing VSOA is refreshed via [MOD-DE-MSG-5-5]. Set Participant Effective Until does not accept VSOA parameters and cannot modify any other field of the record; VSOA configuration is frozen at record creation (see [MOD-PP-MSG-1] and [MOD-PP-MSG-14]). This method also cannot create a record that does not already exist.
§ [MOD-PP-MSG-9] Revoke Participant
Any authorized operator CAN execute this method on behalf of a corporation.
This method can only be called:
- by an ancestor (
corporationof a validator in theParticipantbranch until the rootParticipantentry (GRANTOR, ECOSYSTEM, OPEN schema mode)). - by the grantee
corporation(OPEN, GRANTOR, ECOSYSTEM schema mode). - by the
Ecosystemcorporation(owner of the credential schema).
§ [MOD-PP-MSG-9-1] Revoke Participant parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory): id of theParticipantentry;
§ [MOD-PP-MSG-9-2] Revoke Participant precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-9-2-1] Revoke Participant basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. idMUST be a valid uint64.- Load
Participantentryapplicant_participantfromid. If no entry found, abort. applicant_participantMUST be a active participant
§ [MOD-PP-MSG-9-2-2] Revoke Participant advanced checks
Either Option #1, #2 or #3 MUST return true, else abort.
Option #1: executed by a validator ancestor
if applicant_participant.validator_participant_id is defined:
- set
validator_participant=applicant_participant - while
validator_participant.validator_participant_idis defined,- load
validator_participantfromvalidator_participant.validator_participant_id. - if
validator_participantis a active participant andvalidator_participant.corporationis who is running the method, => return true.
- load
- end
- return false.
Option #2: executed by Ecosystem controller
- load
CredentialSchemacsfromapplicant_participant.schema_id - load
Ecosystemecosystemfromcs.ecosystem_id - if
corporationrunning the method isecosystem.corporation, return true. - else return false.
Option #3: executed by applicant_participant.corporation: return true.
Example:
In the following Participant tree, the “Verifier E” Participant entry can be revoked:
- by “Verifier E”, if the corresponding
Participantentry is a active participant; - by “Verifier Grantor D”, if the corresponding
Participantentry is a active participant; - by “Ecosystem A”, if the corresponding root
Participantentry is a active participant; - by the
Ecosystemobject controller, obtained by resolving perm => credential schema => ecosystem.
§ [MOD-PP-MSG-9-2-3] Revoke Participant fee checks
Fee payer MUST have the required estimated transaction fees in its account, else transaction MUST abort.
§ [MOD-PP-MSG-9-3] Revoke Participant execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
define
now: current timestamp. -
Load
Participantentryapplicant_participantfromid. -
set
applicant_participant.revokedtonow -
set
applicant_participant.modifiedtonow
Call [MOD-DE-MSG-6] Revoke VS Operator Authorization with participant_id = applicant_participant.id to remove any authorization record for this Participant entry. The call is a no-op if no record exists.
§ [MOD-PP-MSG-10] Create or Update Participant Session
Any authorized operator CAN execute this method on behalf of a corporation.
Any credential exchange that requires issuer or verifier to pay fees, register a digest_sri, or produce a proof implies the creation of a ParticipantSession.
If the peer wants to issue a credential, the agent, the Verifiable User Agent or Verifiable Service that receive the request MUST send to peer:
- a
uuidfor session identification; - optional: the
agent_participant_idParticipantid of the agent that will receive the credential, if peer is a Verifiable User Agent. it MUST NOT be set if peer is a Verifiable Service. - optional: the
wallet_agent_participant_idParticipantid of the agent wallet that will store the credential. If this is the same software than the agent, then it should be equal toagent_participant_id. It MUST NOT be set if peer is a Verifiable Service.
If the peer wants to verify a credential, agent must send to peer:
- a
uuidfor session identification; - optional: the
agent_participant_idParticipantid of the agent that will receive the credential, if peer is a Verifiable User Agent. it MUST NOT be set if peer is a Verifiable Service. - optional: a map of compatible found credentials in available wallets for the requested schema_id: Map<uint64[] issuer_participant_ids, uint64: wallet_agent_participant_id>. wallet_agent_participant_id MUST NOT be set if peer is a Verifiable Service.
In case peer is a Verifiable Service and illegaly set agent_participant_id and/or wallet_agent_participant_id, the other end MUST refuse the request.
payer MUST create a Participant Session using the above information, then, agent MUST check session has been created and is valid before accepting the action (receive and store issued credential, or accept a presentation request).
See VT spec.
§ [MOD-PP-MSG-10-1] Create or Update Participant Session parameters
An account that would like to create or update a ParticipantSession entry MUST send a Msg by specifying:
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uuid) (mandatory): id of theParticipantSession.issuer_participant_id(uint64) (optional): the id of the perm of the issuer, if we are dealing with the issuance of a credential.verifier_participant_id(uint64) (optional): the id of the perm of the verifier, if we are dealing with the verification of a credential.agent_participant_id(uint64) (optional): the agent credential issuerParticipantid (extracted from the agent credential that VUA has in its wallet) of the agent that received the request (credential offer for issuance, presentation request for verification). Only set by VUAs, MUST NOT be specified when peer is a VS.wallet_agent_participant_id(uint64) (optional): the wallet credential issuerParticipantid of the VUA where the credential will be or is stored. Can be the same perm thanagent_participant_idif agent and wallet_agent are the same agent. Only set by VUAs, MUST NOT be specified when peer is a VS.digest(string) (optional): digest derived from an issued or verified credential.
§ [MOD-PP-MSG-10-2] Create or Update Participant Session precondition checks
If any of these precondition checks fail, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.idMUST be a valid uuid. If an entryexisting_entrywithidalready exist, thenexisting_entry.corporationMUST be equal tocorporationANDexisting_entry.vs_operatorMUST be equal tooperator, else abort.
if issuer_participant_id is null AND verifier_participant_id is null, MUST abort.
- define
issuer_participantas null. - define
verifier_participantas null.
if issuer_participant_id is not null:
- Load
issuer_participantfromissuer_participant_id. - if
issuer_participant.roleis not ISSUER, abort. - if
issuer_participantis not a active participant, abort. - if
issuer_participant.vs_operatoris not equal tooperator, abort. - if
issuer_participant.corporationis not equal tocorporation, abort. - if
digest_sriis present but not a valid digest SRI, abort.
if verifier_participant_id is not null:
- Load
verifier_participantfromverifier_participant_id. - if
verifier_participant.roleis not VERIFIER, abort. - if
verifier_participantis not a active participant, abort. - if
verifier_participant.vs_operatoris not equal tooperator, abort. - if
verifier_participant.corporationis not equal tocorporation, abort. - if
digest_sriis present but not a valid digest SRI, abort.
Define the primary Participant perm: if verifier_participant is not null, perm = verifier_participant (the caller is the vs_operator of the verifier). Else, perm = issuer_participant (the caller is the vs_operator of the issuer).
[AUTHZ-CHECK-3] MUST pass for this (corporation, operator, perm) tuple.
[AUTHZ-CHECK-4] MUST pass for this (corporation, operator, perm) tuple.
agent:
- Load
agent_participantfromagent_participant_id. - if
agent_participant.roleis not ISSUER, abort. - if
agent_participantis not a active participant, abort.
wallet_agent:
- Load
wallet_agent_participantfromwallet_agent_participant_id. - if
wallet_agent_participant.roleis not ISSUER, abort. - if
wallet_agent_participantis not a active participant, abort.
we might want to check that credential schema of agent and wallet_agent perms is an Essential Credential Schema of type UserAgent. At the moment there is no way of doing it. We consider User Agent will not report a Participant entry that is not controlled by its owner.
§ [MOD-PP-MSG-10-3] Create or Update Participant Session fee checks
- Load
CredentialSchemaentrycsfromissuer_participant.schema_idifissuer_participantis not null, else fromverifier_participant.schema_id. - Fee payer MUST have sufficient available balance for the required estimated transaction fees.
For trust fees, corporation account MUST have sufficient available balance as explained below.
Step 1: Calculate total beneficiary fees in credential schema pricing asset
Use “Find Beneficiaries” query method to get the set of beneficiary Participant entries found_participant_set (all ancestors in the Participant tree).
- define
total_beneficiary_fees= 0
If Credential Issuance (issuer_participant is NOT null):
- for each
perminfound_participant_set:total_beneficiary_fees=total_beneficiary_fees+participant.issuance_fees× (1 -issuer_participant.issuance_fee_discount)
If Credential Verification (verifier_participant is NOT null):
- for each
perminfound_participant_set:total_beneficiary_fees=total_beneficiary_fees+participant.verification_fees× (1 -verifier_participant.verification_fee_discount)
Note:
total_beneficiary_feesis expressed in the credential schema pricing asset(cs.pricing_asset_type, cs.pricing_asset).
Step 2: Calculate amounts payer must have available
Based on the credential schema pricing configuration, calculate the total amounts the payer (corporation) must have available.
Define the following variables:
| Variable | Description |
|---|---|
total_fees_in_pricing_asset |
Total fees to be distributed to beneficiaries (in pricing asset) |
total_fees_in_native_denom |
Total fees converted to native denom (if needed) |
total_payer_trust_deposit |
Trust deposit payer must stake for themselves |
total_payees_trust_deposit |
Trust deposit payer must stake on behalf of payees |
total_payees_fees_to_account |
Fees to be transferred to payees’ accounts |
total_user_agent_reward |
Reward for user agent (in native denom) |
total_wallet_agent_reward |
Reward for wallet agent (in native denom) |
Initialize:
total_fees_in_pricing_asset=total_beneficiary_feestotal_fees_in_native_denom= 0total_payer_trust_deposit= 0total_payees_trust_deposit= 0total_payees_fees_to_account= 0total_user_agent_reward= 0total_wallet_agent_reward= 0
If a conversion is needed below, use Get Price to convert amounts.
Case A: (cs.pricing_asset_type, cs.pricing_asset) = (COIN, [[ref: native denom]])
Pricing is in native token. No conversion needed.
Calculate:
total_fees_in_native_denom=total_fees_in_pricing_assettotal_payer_trust_deposit=total_fees_in_native_denom×GlobalVariables.trust_deposit_ratetotal_payees_trust_deposit=total_payer_trust_deposittotal_payees_fees_to_account=total_fees_in_native_denom× (1 -GlobalVariables.trust_deposit_rate)
if agent_participant_id is set:
total_user_agent_reward=total_fees_in_native_denom×GlobalVariables.user_agent_reward_rate
if wallet_agent_participant_id is set:
total_wallet_agent_reward=total_fees_in_native_denom×GlobalVariables.wallet_user_agent_reward_rate
Required balance check:
corporationMUST have available balance ≥total_fees_in_native_denom+total_payer_trust_deposit+total_user_agent_reward+total_wallet_agent_rewardin native denom.
Case B: (cs.pricing_asset_type, cs.pricing_asset) = (TU, "tu")
Pricing is in Trust Units. Convert to native denom for all on-chain payments.
Calculate:
total_fees_in_native_denom= getPrice(TU,"tu",COIN,[[ref: native denom]],total_fees_in_pricing_asset)total_payer_trust_deposit=total_fees_in_native_denom×GlobalVariables.trust_deposit_ratetotal_payees_trust_deposit=total_payer_trust_deposittotal_payees_fees_to_account=total_fees_in_native_denom× (1 -GlobalVariables.trust_deposit_rate)
if agent_participant_id is set:
total_user_agent_reward=total_fees_in_native_denom×GlobalVariables.user_agent_reward_rate
if wallet_agent_participant_id is set:
total_wallet_agent_reward=total_fees_in_native_denom×GlobalVariables.wallet_user_agent_reward_rate
Required balance check:
corporationMUST have available balance ≥total_fees_in_native_denom+total_payer_trust_deposit+total_user_agent_reward+total_wallet_agent_rewardin native denom.
Case C: (cs.pricing_asset_type, cs.pricing_asset) = (COIN, <arbitrary_denom>)
Pricing is in an arbitrary on-chain coin (e.g., USDC). Fees to payees are paid in that coin; deposits and agent rewards are converted to native denom.
Calculate:
total_fees_in_native_denom= getPrice(COIN,<arbitrary_denom>,COIN,[[ref: native denom]],total_fees_in_pricing_asset)total_payer_trust_deposit=total_fees_in_native_denom×GlobalVariables.trust_deposit_ratetotal_payees_trust_deposit=total_payer_trust_deposittotal_payees_fees_to_account=total_fees_in_pricing_asset× (1 -GlobalVariables.trust_deposit_rate)
if agent_participant_id is set:
total_user_agent_reward=total_fees_in_native_denom×GlobalVariables.user_agent_reward_rate
if wallet_agent_participant_id is set:
total_wallet_agent_reward=total_fees_in_native_denom×GlobalVariables.wallet_user_agent_reward_rate
Required balance check:
corporationMUST have available balance ≥total_payer_trust_deposit+total_payees_trust_deposit+total_user_agent_reward+total_wallet_agent_rewardin native denom.- AND
corporationMUST have available balance ≥total_payees_fees_to_accountin<arbitrary_denom>.
Case D: (cs.pricing_asset_type, cs.pricing_asset) = (FIAT, <fiat_denom>)
Pricing is in fiat currency (e.g., USD). Fiat fees are settled off-chain; only deposits and agent rewards are paid on-chain in native denom.
Calculate:
total_fees_in_native_denom= getPrice(FIAT,<fiat_denom>,COIN,[[ref: native denom]],total_fees_in_pricing_asset)total_payer_trust_deposit=total_fees_in_native_denom×GlobalVariables.trust_deposit_ratetotal_payees_trust_deposit=total_payer_trust_deposittotal_payees_fees_to_account= 0 (FIAT payments are managed off-chain)
if agent_participant_id is set:
total_user_agent_reward=total_fees_in_native_denom×GlobalVariables.user_agent_reward_rate
if wallet_agent_participant_id is set:
total_wallet_agent_reward=total_fees_in_native_denom×GlobalVariables.wallet_user_agent_reward_rate
Required balance check:
corporationMUST have available balance ≥total_payer_trust_deposit+total_payees_trust_deposit+total_user_agent_reward+total_wallet_agent_rewardin native denom.
- Trust deposits MUST always be paid in native denom.
- When paying with COIN ≠ native denom or with FIAT, payer pays trust deposits on behalf of payees (since payees receive non-native assets that cannot be directly staked).
§ [MOD-PP-MSG-10-4] Create or Update Participant Session execution
If all precondition checks passed, method is executed.
- Load all
Participantentries as in basic checks. - Load
CredentialSchemaentrycsfromissuer_participant.schema_idifissuer_participantis not null, else fromverifier_participant.schema_id. - define
now: current timestamp. - use “Find Beneficiaries” to build
found_participant_set.
Note: All funds are transferred from the
corporationaccount executing the method. The steps below describe what each recipient must receive. Implementation details (batching, order of transfers) are left to the implementer.
Step 1: Process fee distribution to each beneficiary
Initialize accumulators for agent rewards:
accumulated_user_agent_reward= 0accumulated_wallet_agent_reward= 0
Determine the operation type and applicable discount:
-
If Credential Issuance (
issuer_participantis NOT null):fee_field=issuance_feesdiscount=issuer_participant.issuance_fee_discountpayer_participant=issuer_participant
-
Else if Credential Verification (
verifier_participantis NOT null):fee_field=verification_feesdiscount=verifier_participant.verification_fee_discountpayer_participant=verifier_participant
For each beneficiary Participant perm in found_participant_set:
If participant.[fee_field] > 0:
-
Calculate the discounted fee for this beneficiary:
beneficiary_fee_in_pricing_asset=participant.[fee_field]× (1 -discount)
-
Calculate amounts based on pricing configuration (same logic as fee checks):
Case A:
(cs.pricing_asset_type, cs.pricing_asset)=(COIN, [[ref: native denom]])fee_in_native_denom=beneficiary_fee_in_pricing_assetpayer_trust_deposit=fee_in_native_denom×GlobalVariables.trust_deposit_ratepayee_trust_deposit=payer_trust_depositpayee_fees_to_account=fee_in_native_denom× (1 -GlobalVariables.trust_deposit_rate)
if agent_participant_id is set:
- user_agent_reward_portion = fee_in_native_denom × GlobalVariables.user_agent_reward_rate
if wallet_agent_participant_id is set:
- wallet_agent_reward_portion = fee_in_native_denom × GlobalVariables.wallet_user_agent_reward_rate
Case B: (cs.pricing_asset_type, cs.pricing_asset) = (TU, "tu")
fee_in_native_denom= getPrice(TU,"tu",COIN,[[ref: native denom]],beneficiary_fee_in_pricing_asset)payer_trust_deposit=fee_in_native_denom×GlobalVariables.trust_deposit_ratepayee_trust_deposit=payer_trust_depositpayee_fees_to_account=fee_in_native_denom× (1 -GlobalVariables.trust_deposit_rate)
if agent_participant_id is set:
- user_agent_reward_portion = fee_in_native_denom × GlobalVariables.user_agent_reward_rate
if wallet_agent_participant_id is set:
- wallet_agent_reward_portion = fee_in_native_denom × GlobalVariables.wallet_user_agent_reward_rate
Case C: (cs.pricing_asset_type, cs.pricing_asset) = (COIN, <arbitrary_denom>)
fee_in_native_denom= getPrice(COIN,<arbitrary_denom>,COIN,[[ref: native denom]],beneficiary_fee_in_pricing_asset)payer_trust_deposit=fee_in_native_denom×GlobalVariables.trust_deposit_ratepayee_trust_deposit=payer_trust_depositpayee_fees_to_account=beneficiary_fee_in_pricing_asset× (1 -GlobalVariables.trust_deposit_rate) (in<arbitrary_denom>)
if agent_participant_id is set:
- user_agent_reward_portion = fee_in_native_denom × GlobalVariables.user_agent_reward_rate
if wallet_agent_participant_id is set:
- wallet_agent_reward_portion = fee_in_native_denom × GlobalVariables.wallet_user_agent_reward_rate
Case D: (cs.pricing_asset_type, cs.pricing_asset) = (FIAT, <fiat_denom>)
fee_in_native_denom= getPrice(FIAT,<fiat_denom>,COIN,[[ref: native denom]],beneficiary_fee_in_pricing_asset)payer_trust_deposit=fee_in_native_denom×GlobalVariables.trust_deposit_ratepayee_trust_deposit=payer_trust_depositpayee_fees_to_account= 0 (FIAT payments are managed off-chain)
if agent_participant_id is set:
- user_agent_reward_portion = fee_in_native_denom × GlobalVariables.user_agent_reward_rate
if wallet_agent_participant_id is set:
- wallet_agent_reward_portion = fee_in_native_denom × GlobalVariables.wallet_user_agent_reward_rate
-
Execute transfers and deposits for this beneficiary:
- If
payee_fees_to_account> 0: transferpayee_fees_to_accounttoparticipant.corporation(in the appropriate denom). - Use [MOD-TD-MSG-1] to increase the trust deposit of
participant.corporationbypayee_trust_deposit. Increaseparticipant.depositby the same value. - Use [MOD-TD-MSG-1] to increase the trust deposit of
corporation(payer) bypayer_trust_deposit. Increasepayer_participant.depositby the same value.
- If
-
Accumulate agent rewards:
accumulated_user_agent_reward=accumulated_user_agent_reward+user_agent_reward_portionaccumulated_wallet_agent_reward=accumulated_wallet_agent_reward+wallet_agent_reward_portion
Step 2: Process agent rewards
After processing all beneficiaries, distribute accumulated rewards to agents.
User Agent Reward:
If agent_participant_id is set AND accumulated_user_agent_reward > 0:
agent_trust_deposit=accumulated_user_agent_reward×GlobalVariables.trust_deposit_rateagent_fees_to_account=accumulated_user_agent_reward-agent_trust_deposit- Transfer
agent_fees_to_accounttoagent_participant.corporationin native denom. - Use [MOD-TD-MSG-1] to increase the trust deposit of
agent_participant.corporationbyagent_trust_deposit. Increaseagent_participant.depositby the same value.
Wallet Agent Reward:
If wallet_agent_participant_id is set AND accumulated_wallet_agent_reward > 0:
wallet_agent_trust_deposit=accumulated_wallet_agent_reward×GlobalVariables.trust_deposit_ratewallet_agent_fees_to_account=accumulated_wallet_agent_reward-wallet_agent_trust_deposit- Transfer
wallet_agent_fees_to_accounttowallet_agent_participant.corporationin native denom. - Use [MOD-TD-MSG-1] to increase the trust deposit of
wallet_agent_participant.corporationbywallet_agent_trust_deposit. Increasewallet_agent_participant.depositby the same value.
Step 3: Create or update session records
Now that all transfers have been done, we can create the entries
Create a ParticipantSessionRecord cspsr:
cspsr.created:nowcspsr.issuer_participant_id:issuer_participant_idcspsr.verifier_participant_id:verifier_participant_idcspsr.agent_participant_id:agent_participant_idcspsr.wallet_agent_participant_id:wallet_agent_participant_id
If new, create entry ParticipantSession session:
session.id:idsession.corporation:corporationsession.vs_operator:operatorsession.modified::nowsession.created::now
Else update:
session.modified::now
then, add the cspsr to session.session_records
if current transaction if for issuance of a credential, persist the digest SRI by calling [MOD-DI-MSG-1].
session.authz[] can contain null issuer_participant_id OR verifier_participant_id
§ [MOD-PP-MSG-11] Update Participant Module Parameters
Update Participant Module Parameters.
Can only be executed through a governance proposal.
§ [MOD-PP-MSG-11-1] Update Participant Module Parameters parameters
params(KeySet<String, String>): the parameters to update and their values.
§ [MOD-PP-MSG-11-2] Update Participant Module Parameters precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-11-2-1] Update Participant Module Parameters basic checks
params: size ofparamsMUST be greater than 0. For eachparam<key,value>keyMUST exist, else abort.
§ [MOD-PP-MSG-11-2-2] Update Participant Module Parameters fee checks
provided transaction fees MUST be sufficient for execution
§ [MOD-PP-MSG-11-3] Update Participant Module Parameters execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
for each parameter param <key, value> in parameters:
- update parameter set value =
valuewhere key =key.
§ [MOD-PP-MSG-12] Slash Participant Trust Deposit
This method can only be called by either:
- a
corporationancestor validator of thisParticipantentry; - the
corporationcontroller of theEcosystemobject, owner of the corresponding credential schema.
§ [MOD-PP-MSG-12-1] Slash Participant Trust Deposit parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory): id of theParticipantentry;amount(number) (mandatory): the amount to slash
§ [MOD-PP-MSG-12-2] Slash Participant Trust Deposit precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-12-2-1] Slash Participant Trust Deposit basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. idMUST be a valid uint64.- Load
Participantentryapplicant_participantfromid. If no entry found, abort. amountMUST be lower or equal toapplicant_participant.depositelse MUST abort.
Even if the Participant entry has expired or is revoked, it is still possible to slash it.
§ [MOD-PP-MSG-12-2-2] Slash Participant Trust Deposit validator perms
Either Option #1, or #2 MUST return true, else abort.
Option #1: executed by a validator ancestor
if applicant_participant.validator_participant_id is defined:
- set
validator_participant=applicant_participant - while
validator_participant.validator_participant_idis defined,- load
validator_participantfromvalidator_participant.validator_participant_id. - if
validator_participantis a active participant andvalidator_participant.corporationis who is running the method, => return true.
- load
- end
- return false.
Option #2: executed by Ecosystem controller
- load
CredentialSchemacsfromapplicant_participant.schema_id - load
Ecosystemecosystemfromcs.ecosystem_id - if
corporationrunning the method isecosystem.corporation, return true. - else return false.
§ [MOD-PP-MSG-12-2-3] Slash Participant Trust Deposit fee checks
Fee payer MUST have the required estimated transaction fees in its account, else transaction MUST abort.
§ [MOD-PP-MSG-12-3] Slash Participant Trust Deposit execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
define
now: current timestamp. -
Load
Participantentryapplicant_participantfromid. -
Load
Participantentryvalidator_participantfromapplicant_participant.validator_participant_id. -
set
applicant_participant.slashedtonow -
set
applicant_participant.modifiedtonow -
set
applicant_participant.slashed_deposittoapplicant_participant.slashed_deposit+amount
use MOD-TD-MSG-7 to burn the slashed amount from the trust deposit of applicant_participant.corporation.
Call [MOD-DE-MSG-6] Revoke VS Operator Authorization with participant_id = applicant_participant.id to remove any authorization record for this Participant entry. The call is a no-op if no record exists.
§ [MOD-PP-MSG-13] Repay Participant Slashed Trust Deposit
This method can only be called by the corporation that wants to repay the deposit of a slashed Participant entry they own. This won’t make the Participant entry re-usable: it will be needed for the corporation associated to this Participant entry to request a new Participant entry, as slashed Participant entries cannot be revived (same happens for revoked, etc.).
Nevertheless, to get a new Participant entry for a given ecosystem, it is needed, using this method, to repay the deposit of a slashed Participant entry first.
§ [MOD-PP-MSG-13-1] Repay Participant Slashed Trust Deposit parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory): id of theParticipantentry
§ [MOD-PP-MSG-13-2] Repay Participant Slashed Trust Deposit precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-13-2-1] Repay Participant Slashed Trust Deposit basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. idMUST be a valid uint64.- Load
Participantentryapplicant_participantfromid. If no entry found, abort. - if
applicant_participant.corporationis not equal tocorporation, abort.
§ [MOD-PP-MSG-13-2-2] Repay Participant Slashed Trust Deposit fee checks
- Fee payer MUST have the required estimated transaction fees in its account;
corporationMUST have at leastapplicant_participant.slashed_depositin its account balance, else transaction MUST abort.
§ [MOD-PP-MSG-13-3] Repay Participant Slashed Trust Deposit execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- define
now: current timestamp.
use Adjust Trust Deposit to transfer applicant_participant.slashed_deposit to trust deposit of applicant_participant.corporation.
- Load
Participantentryapplicant_participantfromid. - set
applicant_participant.repaidtonow - set
applicant_participant.modifiedtonow - set
applicant_participant.repaid_deposittoapplicant_participant.slashed_deposit.
§ [MOD-PP-MSG-14] Self Create Participant
Any authorized operator CAN execute this method on behalf of a corporation.
This simple Participant-creation method can be used to self-create an ISSUER (resp. VERIFIER) Participant entry if issuance mode (resp. verification mode) is set to OPEN for a given schema. As Participant entries are the anchor of ecosystem trust deposit operations, it is required for an issuer/verifier candidate to self-create a Participant entry for being issuer or verifier of a given schema.
Even if a schema is OPEN, candidate MUST make sure they comply with the EGF else their Participant entry may be revoked by ecosystem governance authority and their deposit slashed.
§ [MOD-PP-MSG-14-1] Self Create Participant parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.role(ParticipantRole) (mandatory): ISSUER or VERIFIER.validator_participant_id(uint64) (mandatory): MUST be an ECOSYSTEM active participant or future participant.vs_operator(account) (optional): the account we want to authorize to createParticipantSessionentries linked to thisParticipantentry. Required for payment delegation.did(string) (mandatory): DID of the VS grantee service.effective_from(timestamp) (optional): timestamp from when (exclusive) this Perm is effective. MUST be in the future.effective_until(timestamp) (optional): timestamp until when (exclusive) this Perm is effective, null if it doesn’t expire. If not null, MUST be greater thaneffective_from.verification_fees(number) (optional): price to pay by the verifier of a credential of this schema to the grantee of this ISSUER perm when a credential is verified, in the denom specified in the credential schema. Default to 0.validation_fees(number) (optional): price to pay by the holder of a credential of this schema to the issuer when executing an onboarding process to obtain a credential, in the denom specified in the credential schema. Default to 0.
The following VS Operator Authorization parameters are optional and collectively define the initial ParticipantAuthorizationRecord for this Participant entry. Presence of vs_operator_authz_msg_types is the trigger: if it is not provided, no authorization record is created and the Participant entry operates in manual mode. VSOA configuration is frozen at creation time and cannot be modified later; to change it, the Participant entry MUST be revoked and re-created.
vs_operator_authz_msg_types[](msg_type[]) (optional): list of VPR delegable message typesvs_operatoris authorized to execute on behalf ofcorporationin the context of thisParticipantentry. If provided, aParticipantAuthorizationRecordis created (see execution below) andvs_operatorMUST be specified.vs_operator_authz_spend_limit(DenomAmount[]) (optional): maximum amount of fundsvs_operatoris allowed to spend in the context of thisParticipantentry as a direct consequence of executing authorized messages.vs_operator_authz_with_feegrant(bool) (optional, default: false): if true,corporationpays transaction fees forvs_operatorvia an on-chainFeeGrantwhen executing authorized messages in the context of thisParticipantentry.vs_operator_authz_fee_spend_limit(DenomAmount[]) (optional): maximum total amount of transaction fees that can be spent byvs_operator(paid bycorporationvia fee grant) in the context of thisParticipantentry.vs_operator_authz_period(duration) (optional): reset period forvs_operator_authz_spend_limitandvs_operator_authz_fee_spend_limitin the context of thisParticipantentry.
Permitted message types to be set in vs_operator_authz_msg_types depends on role.
| Participant role | Permitted Messages |
|---|---|
| HOLDER | TriggerResolver |
| ISSUER | CreateOrUpdateParticipantSession, SetParticipantOPtoValidated |
| VERIFIER | CreateOrUpdateParticipantSession |
§ [MOD-PP-MSG-14-2] Self Create Participant precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-14-2-1] Self Create Participant basic checks
if a mandatory parameter is not present, transaction MUST abort.
Load Participant validator_participant from validator_participant_id.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. role(ParticipantRole) (mandatory): MUST be ISSUER or VERIFIER, else abort.validator_participant_id(uint64) (mandatory):validator_participantMUST be an ECOSYSTEM active participant or future participant.vs_operator(account) (optional): no check required.did, MUST conform to the DID Syntax, as specified [DID-CORE].- if any existing
Participantentry has non-nulldidequal to the provideddid, itscorporationMUST equal the signingcorporation; else method MUST abort (per-Participant(did, corporation)consistency invariant: at any block height, allParticipantentries sharing a non-nulldidare owned by the sameCorporation). effective_fromMUST be in the future AND- MUST be greater or equal to
validator_participant.effective_fromAND - if
validator_participant.effective_untilis not null, MUST be lower thanvalidator_participant.effective_until
- MUST be greater or equal to
effective_until:- if null,
validator_participant.effective_untilMUST be NULL - else if not null, must be greater than
effective_fromAND ifvalidator_participant.effective_untilis not null, MUST be lower or equal tovalidator_participant.effective_until
- if null,
verification_fees(number) (optional): If specified, MUST be >= 0 and theParticipantentry MUST be an ISSUER.validation_fees(number) (optional): If specified, MUST be >= 0 and theParticipantentry MUST be an ISSUER.- VS Operator Authorization parameters: if any of
vs_operator_authz_*parameters is provided,vs_operator_authz_msg_typesMUST also be provided andvs_operatorMUST NOT be null, else abort. Ifvs_operator_authz_msg_typesis provided, it MUST be a non-empty list of VPR delegable message types, and match the permitted messages defined in MOD-PP-MSG-14-1.
§ [MOD-PP-MSG-14-2-2] Self Create Participant permission checks
To execute this method, account MUST match at least one these rules, else transaction MUST abort.
- The related
CredentialSchemaentry is loaded withvalidator_participant.schema_id, and will be namedcsin this section. - if
roleis equal to ISSUER: ifcs.issuer_onboarding_modeis not equal to OPEN, MUST abort. - if
roleis equal to VERIFIER: ifcs.verifier_onboarding_modeis not equal to OPEN, MUST abort. - if
roleis equal to VERIFIER andvalidation_feesis specified and different than 0, MUST abort. - if
roleis equal to VERIFIER andverification_feesis specified and different than 0, MUST abort.
§ [MOD-PP-MSG-14-2-3] Self Create Participant fee checks
Fee payer MUST have the required estimated transaction fees available.
§ [MOD-PP-MSG-14-2-4] Self Create Participant overlap checks
We want to make sure that 2 Participant entries cannot be active at the same time for the same validator_participant_id. If corporation wishes to create a new Participant entry but the existing one never expires (or expires too far from now), corporation MUST use first the Set Participant Effective Until to set or adjust the effective_until value.
Find all active participants participants[] (not revoked, not slashed, not repaid) for cs.id, role, validator_participant_id, corporation.
for each Participant entry p from participants[]:
- if
p.effective_untilis greater thaneffective_from, method execution MUST abort. - if
p.effective_fromis lower thaneffective_until, method execution MUST abort. - if
p.effective_untilis NULL (never expire), creation of a newParticipantentry doesn’t make any sense and method execution MUST abort.
note: this check was not present in v3.
§ [MOD-PP-MSG-14-3] Self Create Participant execution
If all precondition checks passed, method is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- define
now: current timestamp. - Load
Participantvalidator_participantfromvalidator_participant_id.
A new entry Participant perm MUST be created:
participant.id: auto-incremented uint64.participant.validator_participant_id:validator_participant_idparticipant.schema_id:validator_participant.schema_idparticipant.modifiedtonow.participant.role:role.participant.did:did.participant.corporation:corporation.participant.vs_operator:vs_operator.participant.created:nowparticipant.effective_from:effective_fromparticipant.effective_until:effective_untilparticipant.validation_fees:validation_feesif specified androleis ISSUER, else 0.participant.issuance_fees: 0participant.verification_fees:verification_feesif specified androleis ISSUER, else 0.participant.deposit: 0
If vs_operator_authz_msg_types is provided, create the ParticipantAuthorizationRecord in active state by calling [MOD-DE-MSG-5] Grant VS Operator Authorization with:
corporation:corporationvs_operator:vs_operatorrecord:record.participant_id:participant.idrecord.msg_types:vs_operator_authz_msg_typesrecord.spend_limit:vs_operator_authz_spend_limitrecord.fee_spend_limit:vs_operator_authz_fee_spend_limitrecord.with_feegrant:vs_operator_authz_with_feegrant(default: false)record.expiration:participant.effective_untilrecord.period:vs_operator_authz_period
Note: unlike [MOD-PP-MSG-1], the record is created with
expiration = participant.effective_untiland is therefore immediately active. Ifwith_feegrantis true andparticipant.effective_until > now, [MOD-DE-MSG-5-5] grants the on-chainFeeGrantas part of this execution.
§ [MOD-PP-MSG-15] Trigger Resolver
This method CAN be executed by:
- the
vs_operatorof theParticipantentry, acting on behalf ofparticipant.corporation; or - any ancestor validator of the
Participantentry in theParticipanttree (from the direct parent up to the rootParticipantentry). For an ancestor validatorv, the method CAN be executed by thevs_operatordefined inv, or by anyoperatorauthorized byv.corporationfor this message type.
This method is intended to be used by external services (such as the Verana indexer) to be notified that a trust resolution must be performed for the did registered in the Participant entry. Typical use cases include:
- a new verifiable service has been onboarded and its credentials are now present in the DID Document, so trust can be (re-)evaluated;
- an issuer has revoked a credential issued to a holder: the issuer (acting as the validator of the corresponding HOLDER
Participantentry) notifies the trust resolver to re-evaluate trust for the revoked HOLDERParticipantentry; - an issuer is no longer operating: a parent issuer grantor or root ecosystem
Participantentry triggers a re-evaluation.
The method does not modify the VPR state; it only emits an event that off-chain components MAY consume.
§ [MOD-PP-MSG-15-1] Trigger Resolver parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.id(uint64) (mandatory): id of theParticipantentry for which a trust resolution must be triggered.
§ [MOD-PP-MSG-15-2] Trigger Resolver precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-PP-MSG-15-2-1] Trigger Resolver basic checks
if a mandatory parameter is not present, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.idMUST be a valid uint64.- Load
Participantentrypermfromid. If no entry found, abort. permMUST be an active participant, else abort.participant.didMUST NOT be null, else abort.
§ [MOD-PP-MSG-15-2-2] Trigger Resolver authorization checks
At least one of the two authorization paths below MUST pass, else transaction MUST abort.
Path 1 — vs_operator of the target Participant entry
corporationMUST be equal toparticipant.corporation.operatorMUST be equal toparticipant.vs_operator.- [AUTHZ-CHECK-3] MUST pass for this (
corporation,operator,perm) tuple. - [AUTHZ-CHECK-4] MUST pass for this (
corporation,operator,perm) tuple.
Path 2 — ancestor validator in the Participant tree
The target perm itself is excluded from this walk; only its ancestors (from the direct parent up to the root) are considered. Walk the tree:
- set
v=perm. - while
v.validator_participant_idis defined and !=participant.id:- load
vfromv.validator_participant_id. - if
vis not an active participant, continue with the next iteration. - if corporation != v.corporation, continue with the next iteration.
- if AUTHZ-CHECK-1 pass for this (
corporation,operator) tuple and messageTriggerResolverAND AUTHZ-CHECK-2 pass for this (corporation,operator) tuple and messageTriggerResolver, then authorization is granted => match.
- load
If the walk terminates without a match, Path 2 fails.
§ [MOD-PP-MSG-15-2-3] Trigger Resolver fee checks
Fee payer MUST have the required estimated transaction fees in its account, else transaction MUST abort.
§ [MOD-PP-MSG-15-3] Trigger Resolver execution
If all precondition checks passed, transaction is executed.
This method does not modify the state of the VPR. It MUST emit an event signaling that a trust resolution has been triggered for perm. The event MUST include at least:
participant_id: equal toid.
Note: the identity of the signers (
corporation,operator), the fee payer, the block height and timestamp, and the full Msg payload are already observable from the transaction itself. Indexers MAY use theParticipantentry queried byparticipant_idto resolvedid,corporation,vs_operator, and ancestor chain without duplicating them in the event payload.
§ [MOD-PP-QRY-1] List Participants
Anyone CAN execute this method.
Generic query used for (at least):
- find all
Participantentries (all or limit to active) of a given schema; - for a given validator, get PENDING onboarding processes;
- find all
Participantentries of a given grantee; - find all
Participantentries of a given did; - find all ISSUER_GRANTOR active participants, so that I can apply to an ISSUER
Participantentry; …
§ [MOD-PP-QRY-1-1] List Participants parameters
schema_id(number) (optional): the schema id.grantee(account) (optional): the grantee account.did(string) (optional): the did theParticipantentry refers to.participant_id(number) (optional): limit toParticipantentries where thevalidator_participant_idisparticipant_id.role(ParticipantRole) (optional): if we want to limit to a specificParticipantrole.only_valid(boolean) (optional): if set to true, only return active participants.only_slashed(boolean) (optional): if set to true, only return slashedParticipantentries.only_repaid(boolean) (optional): if set to true, only return repaid slashedParticipantentries.modified_after(timestamp) (optional): limit toParticipantentries modified after (or equal to)modified_after.op_state(OnboardingState) (optional): limit toParticipantentries with aop_statenot null and equal toop_state.response_max_size(small number) (optional): limit toresponse_max_sizeresults. Must be min 1, max 1,024. Default to 64.when(timestamp) (optional): if set, query atwhen, else query at now(). Used to query the VPR state at a previous datetime.
§ [MOD-PP-QRY-1-2] List Participants checks
Basic type check arg SHOULD be applied.
If any of these checks fail, query MUST fail.
response_max_sizemust be between 1 and 1,024. Default to 64 if unspecified.
§ [MOD-PP-QRY-1-3] List Participants execution
return a list of found entries, or an empty list if nothing found. Ordered by modified asc.
§ [MOD-PP-QRY-2] Get Participant
Anyone CAN execute this method.
§ [MOD-PP-QRY-2-1] Get Participant parameters
idof the credential schema participant (mandatory);
§ [MOD-PP-QRY-2-2] Get Participant checks
idmust be a uint64.
§ [MOD-PP-QRY-2-3] Get Participant execution
return found entry (if any).
§ [MOD-PP-QRY-3] Void
Obsoleted by [MOD-PP-QRY-1].
§ [MOD-PP-QRY-4] Find Beneficiaries
Anyone can execute this method.
To calculate the fees required for paying the beneficiaries, it is needed to recurse all involved perms until the root of the Participant tree (which is the ecosystem perm), starting from the 2 branches issuer_participant and verifier_participant. As both branches may have common ancestors, we can create a Set (unordered collection with no duplicates), and recurse over the 2 branches, adding found perms. If verifier_participant is null, issuer_participant is never added to the set. If verifier_participant is NOT null, issuer_participant is added to the set if it exists but verifier_participant is not added to the set.
Example 1: verifier_participant: is not set: it’s a credential offer, schema configured to have Issuer Grantors.
Example 2: verifier_participant: is not set: it’s a credential offer. Schema configured to NOT have Issuer Grantors.
Example 3: verifier_participant is set, it’s a presentation request. Schema configured to have Verifier and Issuer Grantors.
§ [MOD-PP-QRY-4-1] Find Beneficiaries parameters
issuer_participant_id(uint64) (optional): id of issuerParticipantentry.verifier_participant_id(uint64) (optional): id of verifierParticipantentry.
§ [MOD-PP-QRY-4-2] Find Beneficiaries checks
- if
issuer_participant_idandverifier_participant_idare unset then MUST abort. - if
issuer_participant_idis specified, loadissuer_participantfromissuer_participant_id, Participant MUST exist and MUST be a active participant. - if
verifier_participant_idis specified, loadverifier_participantfromverifier_participant_id, Participant MUST exist and MUST be a active participant.
§ [MOD-PP-QRY-4-3] Find Beneficiaries execution
Example: Let’s build the set. Revoked and slashed Participant entries will not be added to the set. Expired Participant entries, if not revoked/slashed, will be considered.
-
create Set
found_participant_set. -
define
current_participantas null. -
load perms
issuer_participantand optionalverifier_participantas specified in basic checks above.
if issuer_participant is not null:
- set
current_participant=issuer_participant - while
current_participant.validator_participant_idis not null:- current_participant = load(
current_participant.validator_participant_id) - if
current_participant.revokedis NULL ANDcurrent_participant.slashedis NULL, Addcurrent_participanttofound_participant_set.
- current_participant = load(
Additionally, if verifier_participant is not null:
- if
issuer_participantis not null, addissuer_participanttofound_participant_set - set
current_participant=verifier_participant - while
current_participant.validator_participant_id!= null:- current_participant = load(
current_participant.validator_participant_id) - if
current_participant.revokedis NULL ANDcurrent_participant.slashedis NULL, Addcurrent_participanttofound_participant_set.
- current_participant = load(
return found_perms.
This works even is schema is open to any issuer or open to any verifier.
§ [MOD-PP-QRY-5] Get ParticipantSession
§ [MOD-PP-QRY-5-1] Get ParticipantSession parameters
id(uuid) (mandatory): the id of theParticipantSession.
§ [MOD-PP-QRY-5-2] Get ParticipantSession checks
§ [MOD-PP-QRY-5-3] Get ParticipantSession execution
return ParticipantSession entry if found, else return not found.
§ [MOD-PP-QRY-6] List Participant Module Parameters
§ [MOD-PP-QRY-6-2] List Participant Module Parameters parameters
§ [MOD-PP-QRY-6-2] List Participant Module Parameters query checks
§ [MOD-PP-QRY-6-3] List Participant Module Parameters execution of the query
Return the list of the existing parameters and their values.
§ [MOD-PP-QRY-6-4] List Participant Module Parameters API result example
{
"params": {
"key1": "value1",
"key2": "value2",
...
...
}
}
§ Validation Examples
§ Getting a Credential from an Authorized Issuer
This section is non-normative.
Example of an Applicant that would like to get issued a credential (HOLDER):
§ Add a DID to the List of Granted Issuers of a Credential Schema
This section is non-normative.
§ Trust deposit module
§ Trust deposit module overview
This section is non-normative.
Concept: the trust deposit is used to lock trust value as a stake. To process application messages that perform state changes, several modules methods are requiring a trust deposit to be sent, from the executing account, to the trust deposit module.
We will use a similar method than the one described here to manage trust deposit and yield calculation and easy way.
Example:
In our example, we suppose a VPR is just starting and no trust transaction have taken place yet. For this reason:
TrustDepositmodule has a balance of0:TrustDeposit.deposit:0.GlobalVariables.trust_deposit_share_valuehas a value of1.
Operation #1:
an account account1 wants to create a transaction that requires:
- 10
denomto be sent to theaccount1trust deposit; - 5
denomfor network fees.
First, the Trust Deposit: execution of the method will perform the following (we consider this account had no TrustDeposit entry yet):
-
10
denomare sent to theTrustDepositmodule.TrustDeposit.deposit=TrustDeposit.deposit+10
-
a
TrustDepositentrytd1is created foraccount1running the service with:td1.deposit=10td1.shares=10/GlobalVariables.trust_deposit_share_value=10
Second, fee distribution: let’s suppose that trust_deposit_block_reward_share is set to 0.30 so that 70% of transaction fees are distributed to validators, and 30% of transaction fees are distributed to trust deposit holders. For this specific transaction:
-
30% * 5 = 1.5
denomwill be sent toTrustDepositmodule, which will increase theGlobalVariables.trust_deposit_share_value: -
TrustDeposit.deposit=11.5 -
GlobalVariables.trust_deposit_share_value=1.15.
Now, account1 can (optionally) reclaim the difference between the GlobalVariables.trust_deposit_share_value * tt.share minus tt.denom, which represents the trust (yield) gains.
Operation #2:
Another account account2 wants to create a transaction that requires:
- 20
denomto be sent to theaccount2trust deposit; - 10
denomfor network fees.
First, Trust Deposit:
-
20
denomare sent to theTrustDepositmodule.TrustDeposit.deposit=31.5
-
a
TrustDepositentrytd2is created foraccount2:td2.deposit=20td2.shares=20/GlobalVariables.trust_deposit_share_value=20/1.15~=17.39...
Second, fee distribution: let’s suppose trust_deposit_block_reward_share is set to 0.30 so that 70% of transaction fees are distributed to validators, and 30% of transaction fees are distributed to trust deposit holders. For this specific transaction:
-
30% * 10 = 3
denomwill be sent toTrustDepositmodule, which will increase theGlobalVariables.trust_deposit_share_value: -
TrustDeposit.deposit=34.5 -
GlobalVariables.trust_deposit_share_value=1.15*34.5/31.5~=1.2595...
After the 2 operations:
account1real deposit (based on share) isaccount1.share*GlobalVariables.trust_deposit_share_value~=12.595..., available withdrawable yield isaccount1.share*GlobalVariables.trust_deposit_share_value-account1.deposit~=2.595...account2real deposit (based on share) isaccount2.share*GlobalVariables.trust_deposit_share_value~=21.90..., available withdrawable yield isaccount2.share*GlobalVariables.trust_deposit_share_value-account2.deposit~=1.90...
§ Trust Deposit Yield
The following global parameters are used to tune the Trust Deposit yield generation, in case the VPR is implemented as a ledger:
trust_deposit_max_yield_rate(number) (mandatory): Maximum yearly yield, in percent, that a trust deposit holder can obtain by receiving block rewards.trust_deposit_block_reward_share(number) (mandatory): Percentage of block reward that must be distributed to trust deposit holders. Default value: 20% (0.20)
Each time there is a block reward to be distributed, trust_deposit_block_reward_share percent MUST be directed to trust deposit holders, based on their trust deposit share.
Implementers MUST make sure, for each processed block reward, that the yearly effective yield is lower or equal than trust_deposit_max_yield_rate.
§ [MOD-TD-MSG-1] Adjust Trust Deposit
This method is used to increase or decrease the trust deposit of a specific corporation account.
Only the modules that require trust deposit manipulation CAN call this method. If trust deposit has been slashed and not repaid, method execution MUST abort.
§ [MOD-TD-MSG-1-1] Adjust Trust Deposit method parameters
corporation(group) (mandatory): corporation owner of the trust deposit we want to adjust.augend(number) (mandatory): value to add to the deposit, in denom.
§ [MOD-TD-MSG-1-2] Adjust Trust Deposit precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-TD-MSG-1-2-1] Adjust Trust Deposit basic checks
- if a mandatory parameter is not present, transaction MUST abort.
Value checks:
-
augend(number) (mandatory): MUST be strictly positive or strictly negative. -
load
TrustDepositentrytdforcorporation.- if
tddoes not exist:- if
augendis negative, transaction MUST abort.
- if
- else
- if
augendis negative andtd.refunded-augendis greater thantd.deposittransaction MUST abort. (td.refundedtrust deposit cannot be greater thantd.deposit).
- if
- if
§ [MOD-TD-MSG-1-2-2] Adjust Trust Deposit fee checks
- Fee payer the transaction MUST have the required estimated transaction fees in its account
Additionally:
-
load
TrustDepositentrytdforcorporation. -
if
tdexists:- if
augendis positive:- calculate
needed_deposit=augend-td.refunded. - if
needed_deposit< 0:needed_deposit= 0.
- calculate
- else
needed_deposit= 0.
- if
-
else
needed_deposit=augend. -
corporationMUST haveneeded_depositin its account, else transaction MUST abort.
§ [MOD-TD-MSG-1-3] Adjust Trust Deposit execution of the method
If all precondition checks passed, method is executed in a transaction.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
-
if a
TrustDepositentrytddoes not exist for thiscorporation, create entrytd:- transfer
augendfromcorporationaccount toTrustDepositaccount. - calculate
augend_share=augend/GlobalVariables.trust_deposit_share_value. - set
td.corporationtocorporation; - set
td.deposittoaugend; - set
td.sharetoaugend_share; - set
td.refundedto 0. - set
td.slashed_depositto 0. - set
td.repaid_depositto 0. - set
td.slash_countto 0.
- transfer
-
else if
td.slashed_deposit> 0 andtd.repaid_deposit<td.slashed_deposit=> deposit has been slashed and not repaid, so MUST abort. -
else if
augend> 0:-
if
td.refunded> 0:- if
td.refunded>=augend:- set
td.refundedtotd.refunded-augend
- set
- else
- use bank? to transfer
augend-td.refundedfrom corporation account to corporationTrustDepositaccount. - set
td.deposittotd.deposit+augend-td.refunded - calculate
missing_augend_sharefrom missing tokens :missing_augend_share= (augend-td.refunded) /GlobalVariables.trust_deposit_share_value. - set
td.sharetotd.share+missing_augend_share - set
td.refundedto 0
- use bank? to transfer
- if
-
else
- use bank? to transfer
augendfromaccounttoTrustDepositaccount. - calculate
augend_share=augend/GlobalVariables.trust_deposit_share_value. - set
td.deposittotd.deposit+augend - set
td.sharetotd.share+augend_share
- use bank? to transfer
-
-
else if
augend< 0:- set
td.refundedtotd.refunded-augend
- set
The last case, augend < 0, is to refund trust deposit (e.g. when canceling an onboarding process). The refunded amount is added to td.refunded and is reused for the next trust deposit spending.
§ [MOD-TD-MSG-2] Reclaim Trust Deposit Yield
This method is used to reclaim yield. If trust deposit has been slashed and not repaid, method execution MUST abort.
For a given TrustDeposit entry td, claimable yield is calculated like this:
claimable_yield = td.share * GlobalVariables.trust_deposit_share_value - td.deposit.
If claimable_yield is positive, it can be claimed.
§ [MOD-TD-MSG-2-1] Reclaim Trust Deposit Yield method parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.
§ [MOD-TD-MSG-2-2] Reclaim Trust Deposit Yield precondition checks
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type.
§ [MOD-TD-MSG-2-2-1] Reclaim Trust Deposit Yield basic checks
- Load
TrustDepositentrytdfromcorporation. - if
td.slashed_deposit> 0 andtd.repaid_deposit<td.slashed_deposit=> deposit has been slashed and not repaid, so MUST abort. - calculate
claimable_yield=td.share*GlobalVariables.trust_deposit_share_value-td.deposit. - if
claimable_yield<= 0, transaction MUST abort.
§ [MOD-TD-MSG-2-2-2] Reclaim Trust Deposit Yield fee checks
Fee payer running the transaction MUST have the required estimated transaction fees in its account, else transaction MUST abort.
§ [MOD-TD-MSG-2-3] Reclaim Trust Deposit Yield execution of the method
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
For the TrustDeposit entry td linked to corporation:
- Load
TrustDepositentrytdfromcorporation. - calculate
claimable_yield=td.share*GlobalVariables.trust_deposit_share_value-td.deposit. - update
td.share=td.share-claimable_yield/GlobalVariables.trust_deposit_share_value - transfer
claimable_yieldfromTrustDepositaccount to corporation account.
§ [MOD-TD-MSG-3] Void
§ [MOD-TD-MSG-4] Update Module Parameters
Update Module Parameters.
Can only be executed through a governance proposal.
§ [MOD-TD-MSG-4-1] Update Module Parameters parameters
params(KeySet<String, String>): the parameters to update and their values.
§ [MOD-TD-MSG-4-2] Update Module Parameters precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-TD-MSG-4-2-1] Update Module Parameters basic checks
params: size ofparamsMUST be greater than 0. For eachparam<key,value>keyMUST exist, else abort.
§ [MOD-TD-MSG-4-2-2] Update Module Parameters fee checks
provided transaction fees MUST be sufficient for execution
§ [MOD-TD-MSG-4-3] Update Module Parameters execution
If all precondition checks passed, transaction is executed.
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
for each parameter param <key, value> in parameters:
- update parameter set value =
valuewhere key =key.
§ [MOD-TD-MSG-5] Slash Trust Deposit
This method is used by the network governance authority to globally slash a corporation account trust deposit.
This method can only be called by a governance proposal. A globally slashed account MUST repay the slashed deposit in order to continue to use the services provided by the VPR. When and account is slashed, and while slashed deposit has not been repaid, all account linked permissions MUST be considered non trustable.
This method is for network governance authority slash. For ecosystem slash, see Slash Participant Trust Deposit.
§ [MOD-TD-MSG-5-1] Slash Trust Deposit method parameters
corporation(group) (mandatory): corporation we want to slash.amount(number) (mandatory): value to slash, in denom.
§ [MOD-TD-MSG-5-2] Slash Trust Deposit precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-TD-MSG-5-2-1] Slash Trust Deposit basic checks
if any of these conditions is not satisfied, transaction MUST abort.
amountmust be > 0.TrustDepositentrytdMUST exist for thiscorporation, andtd.depositMUST be greater or equal toamount.
§ [MOD-TD-MSG-5-2-2] Slash Trust Deposit fee checks
Fee payer MUST have the required estimated transaction fees in its account, else transaction MUST abort.
§ [MOD-TD-MSG-5-3] Slash Trust Deposit execution of the method
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- define
now: current timestamp.
For the TrustDeposit entry td linked to corporation:
- set
td.deposittotd.deposit-amount. - set
td.sharetotd.share-amount/GlobalVariables.trust_deposit_share_value - burn
amountfromTrustDepositaccount. - set
td.slashed_deposittotd.slashed_deposit+amount - set
td.last_slashedto now - if
td.slash_countis undefined, set it to1, else set it totd.slash_count+ 1
§ [MOD-TD-MSG-6] Repay Slashed Trust Deposit
Any authorized operator CAN execute this method on behalf of a corporation.
§ [MOD-TD-MSG-6-1] Repay Slashed Trust Deposit method parameters
corporation(group): (Signer) the signing corporation on whose behalf this message is executed.operator(account): (Signer) the account authorized by thecorporationto run this Msg.amount(number) (mandatory): value to repay, in denom.
§ [MOD-TD-MSG-6-2] Repay Slashed Trust Deposit precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-TD-MSG-6-2-1] Repay Slashed Trust Deposit basic checks
if any of these conditions is not satisfied, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. amountmust be > 0.TrustDepositentrytdMUST exist for thiscorporation, andamountMUST be exactly equal totd.slashed_deposit-td.repaid_deposit.
§ [MOD-TD-MSG-6-2-2] Repay Slashed Trust Deposit fee checks
- Fee payer MUST have the required estimated transaction fees in its account;
corporationMUST have the requiredamountin its account, else transaction MUST abort.
§ [MOD-TD-MSG-6-3] Repay Slashed Trust Deposit execution of the method
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- define
now: current timestamp.
For the TrustDeposit entry td linked to corporation account:
- set
td.deposittotd.deposit+amount. - set
td.sharetotd.share+amount/GlobalVariables.trust_deposit_share_value - add
amounttoTrustDepositaccount. - set
td.repaid_deposittotd.repaid_deposit+amount - set
td.last_repaidto now
§ [MOD-TD-MSG-7] Burn Ecosystem Slashed Trust Deposit
Burn the portion of the trust deposit of a given account. This method can only be called by the permission module when performing an ecosystem-related slash.
Make sure to properly protect access to the execution of this method else it may lead to very destructive actions.
§ [MOD-TD-MSG-7-1] Burn Ecosystem Slashed Trust Deposit method parameters
corporation(group) (mandatory): corporation of the trust deposit we want to burn.amount(number) (mandatory): value to burn, in denom.
Alternative approach: For security and consistency, implementers MAY choose to reference the ID of the slashed permission, load it and use its defined slashed_deposit value as the slashing amount.
The decision between this method and specifying the amount directly is left to implementers.
§ [MOD-TD-MSG-7-2] Burn Ecosystem Slashed Trust Deposit precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-TD-MSG-7-2-1] Burn Ecosystem Slashed Trust Deposit basic checks
if any of these conditions is not satisfied, transaction MUST abort.
amountmust be > 0.TrustDepositentrytdMUST exist for thiscorporation, andamountMUST be lower or equal thantd.deposit.
§ [MOD-TD-MSG-7-2-2] Burn Ecosystem Slashed Trust Deposit fee checks
Fee payer running the transaction MUST have the required estimated transaction fees in its account else transaction MUST abort.
§ [MOD-TD-MSG-7-3] Burn Ecosystem Slashed Trust Deposit execution of the method
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- define
now: current timestamp.
For the TrustDeposit entry td linked to account:
- set
td.deposittotd.deposit-amount. - set
td.sharetotd.share-amount/GlobalVariables.trust_deposit_share_value - burn
amountfromTrustDepositaccount.
§ [MOD-TD-QRY-1] Get Trust Deposit
Any account CAN run this query. As this method does not modify data, it does not require a transaction.
§ [MOD-TD-QRY-1-1] Get Trust Deposit query parameters
account(account) (mandatory): the account for which we want to get the trust deposit value.
§ [MOD-TD-QRY-1-2] Get Trust Deposit query checks
If any of these checks fail, query MUST fail.
accountmust be a valid account.
§ [MOD-TD-QRY-1-3] Get Trust Deposit execution of the query
If found, returns trust deposit, else return not found.
§ [MOD-TD-QRY-2] List Module Parameters
Anyone CAN run this query.
§ [MOD-TD-QRY-2-2] List Module Parameters parameters
§ [MOD-TD-QRY-2-2] List Module Parameters query checks
§ [MOD-TD-QRY-2-3] List Module Parameters execution of the query
Return the list of the existing parameters and their values.
§ [MOD-TD-QRY-2-4] List Module Parameters API result example
{
"params": {
"key1": "value1",
"key2": "value2",
...
...
}
}
§ [MOD-DE-MSG-1] Grant Fee Allowance
This method can only be called directly by the following methods:
- Grant Operator Authorization
- the VS Operator Authorization feegrant subroutine [MOD-DE-MSG-5-5] (invoked by [MOD-DE-MSG-5], [MOD-DE-MSG-6] and [MOD-DE-MSG-9])
§ [MOD-DE-MSG-1-1] Grant Fee Allowance method parameters
corporation(group) (mandatory): the corporation that grants the fees.grantee(account) (mandatory): the account that receives the fee grant fromcorporation.msg_types(Msg[]) (mandatory): the type of messages for which we want to grant the fee allowance.expiration(timestamp) (optional): when the grant expires.spend_limit(DenomAmount[]) (optional): maximum spendableperiod(duration) (optional): can be combined withspend_limit
§ [MOD-DE-MSG-1-2] Grant Fee Allowance basic checks
if any of these conditions is not satisfied, transaction MUST abort.
msg_types(Msg[]) (mandatory): MUST be a list of VPR delegable messages only.expiration(timestamp): if specified, MUST be in the futurespend_limit(DenomAmount[]) if specified, MUST be a list of valid DenomAmountsperiod(duration): if specified MUST be a valid period.- if
periodis specified,expirationMUST also be specified.
§ [MOD-DE-MSG-1-3] Grant Fee Allowance fee checks
- Fee payer MUST have the required estimated transaction fees in its account;
§ [MOD-DE-MSG-1-4] Grant Fee Allowance execution of the method
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
Create (or update if it already exist) FeeGrant feegrant:
- set
feegrant.grantortocorporation - set
feegrant.granteetograntee - set
feegrant.msg_typestomsg_types - set
feegrant.expirationtoexpiration - set
feegrant.spend_limittospend_limit - if
spend_limitis set, setfeegrant.remaining_spendtospend_limit - set
feegrant.periodtoperiod
§ [MOD-DE-MSG-2] Revoke Fee Allowance
This method can only be called directly by the following methods:
- Grant Operator Authorization
- Revoke Operator Authorization
- the VS Operator Authorization feegrant subroutine [MOD-DE-MSG-5-5] (invoked by [MOD-DE-MSG-5], [MOD-DE-MSG-6] and [MOD-DE-MSG-9])
§ [MOD-DE-MSG-2-1] Revoke Allowance method parameters
corporation(group) (mandatory): the corporation.grantee(account) (mandatory): the grantee we want to revoke.
§ [MOD-DE-MSG-2-2] Revoke Fee Allowance basic checks
MUST abort if one of these conditions fails:
corporation(group) (mandatory): MUST be specified.grantee(account) (mandatory): MUST be specified.
§ [MOD-DE-MSG-2-3] Revoke Fee Allowance fee checks
- Fee payer MUST have the required estimated transaction fees in its account;
§ [MOD-DE-MSG-2-4] Revoke Fee Allowance execution of the method
If FeeGrant entry for this (corporation, grantee) exist, delete it, else do nothing.
§ [MOD-DE-MSG-3] Grant Operator Authorization
- Any authorized
operatorCAN execute this method on behalf of acorporation. corporationCAN execute this method alone through a group proposal
§ [MOD-DE-MSG-3-1] Grant Operator Authorization method parameters
corporation(group) (mandatory): (Signer) the signing corporation on whose behalf this message is executed.operator(account) (optional): (Signer) the account authorized by thecorporationto run this Msg.grantee(account) (mandatory): the account that receives the authorization fromcorporation.msg_types(Msg[]) (mandatory): the type of messages for which we want to grant the fee allowance.expiration(timestamp) (optional): when the authorization (and its optional feegrant) expires.authz_spend_limit(DenomAmount[]) (optional): maximum spendableauthz_spend_limit_period(duration) (optional): can be combined withspend_limitwith_feegrant(boolean) (mandatory): means this authorization grants feegrant, toofeegrant_spend_limit(DenomAmount[]) (optional): maximum spendablefeegrant_spend_limit_period(duration) (optional): can be combined withfeegrant_spend_limit
§ [MOD-DE-MSG-3-2] Grant Operator Authorization basic checks
if any of these conditions is not satisfied, transaction MUST abort.
-
corporation(group): (Signer) signature must be verified. -
operator(account): (Signer) signature must be verified. -
[AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. -
msg_types(Msg[]) (mandatory): MUST be a list of VPR delegable messages only, exceptedCreateOrUpdateParticipantSessionwhich is not allowed. -
expiration(timestamp): if specified, MUST be in the future -
authz_spend_limit(DenomAmount[]) if specified, MUST be a list of valid DenomAmounts -
authz_spend_limit_period(duration): if specified MUST be a valid period. Ignored ifauthz_spend_limitis not set. -
feegrant_spend_limit(DenomAmount[]) if specified, MUST be a list of valid DenomAmounts. Ignored ifwith_feegrantis false. -
feegrant_spend_limit_period(duration): if specified MUST be a valid period. Ignored iffeegrant_spend_limitis not set or ifwith_feegrantis false. -
if
authz_spend_limit_periodorfeegrant_spend_limit_periodis specified,expirationMUST also be specified. -
Check if a VS Operator Authorization exists for
corporationandgrantee. If this is the case, MUST abort.
An Operator Authorization CAN be granted ONLY IF no VS Operator Authorization exists for participant.corporation and participant.vs_operator. Operator Authorization and VS Operator Authorization are mutually exclusive for a given grantee.
§ [MOD-DE-MSG-3-3] Grant Operator Authorization fee checks
- Fee payer MUST have the required estimated transaction fees in its account;
§ [MOD-DE-MSG-3-4] Grant Operator Authorization execution of the method
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
Create (or update if it already exist) Authorization authz:
- set
authz.corporationtocorporation - set
authz.operatortograntee - set
authz.msg_typestomsg_types - set
authz.expirationtoexpiration - set
authz.spend_limittoauthz_spend_limit - if
authz_spend_limitis set, setauthz.remaining_spendtoauthz_spend_limit - set
authz.periodtoauthz_spend_limit_period
if with_feegrant is false:
- call Revoke Fee Allowance (
corporation,grantee).
else if with_feegrant is true:
- grant Fee Allowance (
corporation,grantee,msg_types,expiration,feegrant_spend_limit,feegrant_spend_limit_period).
§ [MOD-DE-MSG-4] Revoke Operator Authorization
- Any authorized
operatorCAN execute this method on behalf of acorporation. corporationCAN execute this method alone through a group proposal
§ [MOD-DE-MSG-4-1] Revoke Operator Authorization method parameters
corporation(group) (mandatory): (Signer) the signing corporation on whose behalf this message is executed.operator(account) (mandatory): (Signer) the account authorized by thecorporationto run this Msg.grantee(account) (mandatory): the account that will be revoked its authorization`.
§ [MOD-DE-MSG-4-2] Revoke Operator Authorization basic checks
MUST abort if one of these conditions fails:
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. - An Authorization entry MUST exist for this (
corporation,grantee)
§ [MOD-DE-MSG-4-3] Revoke Operator Authorization fee checks
- Fee payer MUST have the required estimated transaction fees in its account;
§ [MOD-DE-MSG-4-4] Revoke Operator Authorization execution of the method
- Delete Authorization entry for this (
corporation,grantee). - revoke Fee Allowance (
corporation,grantee).
§ [MOD-DE-MSG-5] Grant VS Operator Authorization
This method can only be called directly by the following Participant module methods, with no signer check:
It creates a new ParticipantAuthorizationRecord inside VSOperatorAuthorization[corporation, vs_operator] and, if the record enables a fee grant and its expiration is in the future, synchronises the on-chain FeeGrant for the containing VSOA.
This method does NOT read Participant state. All authorization configuration is provided by the caller.
§ [MOD-DE-MSG-5-1] Grant VS Operator Authorization method parameters
corporation(group) (mandatory): the corporation delegating the authorization.vs_operator(account) (mandatory): the account receiving the authorization.record(ParticipantAuthorizationRecord) (mandatory): the full record to store.
§ [MOD-DE-MSG-5-2] Grant VS Operator Authorization basic checks
If any of these conditions is not satisfied, transaction MUST abort.
corporationandvs_operatorMUST NOT be null.record.participant_idMUST NOT match an existingParticipantAuthorizationRecordanywhere in the store (each record is globally unique byparticipant_id).record.msg_typesMUST be non-empty and MUST contain only VPR delegable message types.- No
OperatorAuthorizationoauthzwhereoauthz.corporation=corporationandoauthz.operator=vs_operatorMUST exist. - No other
VSOperatorAuthorizationvsoauthz'wherevsoauthz'.vs_operator=vs_operatorANDvsoauthz'.corporation!=corporationMUST exist. In other words, a vs-agent VPR account cannot be controlled by multiple corporations.
A VS Operator Authorization record CAN be granted ONLY IF no OperatorAuthorization exists for the same (corporation, vs_operator) pair. VS Operator Authorization and Operator Authorization are mutually exclusive for a given grantee.
§ [MOD-DE-MSG-5-3] Grant VS Operator Authorization fee checks
- Fee payer MUST have the required estimated transaction fees in its account.
§ [MOD-DE-MSG-5-4] Grant VS Operator Authorization execution of the method
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- Initialize the runtime balances on
record:- if
record.spend_limitis set, setrecord.remaining_spend := record.spend_limit. - if
record.fee_spend_limitis set, setrecord.remaining_fee_spend := record.fee_spend_limit.
- if
- Load
VSOperatorAuthorizationvsoawith(corporation, vs_operator). If it does not exist, create a newvsoawithvsoa.corporation = corporation,vsoa.vs_operator = vs_operator,vsoa.records = []. - Append
recordtovsoa.records. - Call Recompute VS Operator Fee Allowance for
vsoa.
§ [MOD-DE-MSG-5-5] Recompute VS Operator Fee Allowance
This is a shared subroutine invoked by [MOD-DE-MSG-5], [MOD-DE-MSG-6] and [MOD-DE-MSG-9] after they mutate vsoa.records.
- define
max_expire= null. - define
feegrant_msg_types= empty set. - for each
rinvsoa.records:- if
r.with_feegrantis true ANDr.expiration> now():- if
max_expireis null ORr.expiration>max_expire, setmax_expire=r.expiration. - add all entries of
r.msg_typestofeegrant_msg_types.
- if
- if
- if
max_expireis null (no active feegrant-enabled record remains): call Revoke Fee Allowance(vsoa.corporation,vsoa.vs_operator). - else: call Grant Fee Allowance(
vsoa.corporation,vsoa.vs_operator,feegrant_msg_types,max_expire, null, null).
Note:
max_expireis bounded by the farthestrecord.expirationamong feegrant-enabled records. The chain-levelFeeGrantmsg_typesis the union of all such records’msg_types. Per-record spend limits are enforced at [AUTHZ-CHECK-4] time; they are not replicated on theFeeGrantobject.
§ [MOD-DE-MSG-6] Revoke VS Operator Authorization
This method can only be called directly by the following Participant module methods, with no signer check:
- Cancel Participant OP Last Request (only when the cancellation terminates the permission)
- Revoke Participant
- Slash Participant Trust Deposit
It removes the unique ParticipantAuthorizationRecord identified by participant_id and recomputes the on-chain FeeGrant of its containing VSOA. No-op if no such record exists.
This method does NOT read Participant state.
§ [MOD-DE-MSG-6-1] Revoke VS Operator Authorization method parameters
participant_id(uint64) (mandatory): id of the permission whose authorization record must be removed.
§ [MOD-DE-MSG-6-2] Revoke VS Operator Authorization basic checks
participant_idMUST be a valid uint64.
Note: absence of a record for
participant_idis NOT an error. The method is a no-op in that case (the permission was never VS-operator-authorized, or was already revoked).
§ [MOD-DE-MSG-6-3] Revoke VS Operator Authorization fee checks
- Fee payer MUST have the required estimated transaction fees in its account.
§ [MOD-DE-MSG-6-4] Revoke VS Operator Authorization execution of the method
- Locate the unique
ParticipantAuthorizationRecordrecordwithrecord.participant_id = participant_id. If none exists, EXIT (no-op). - Let
vsoa= theVSOperatorAuthorizationthat containsrecord. - Remove
recordfromvsoa.records. - Call Recompute VS Operator Fee Allowance for
vsoa. - If
vsoa.recordsis now empty, deletevsoa.
§ [MOD-DE-MSG-9] Update VS Operator Authorization Expiration
This method can only be called directly by the following Participant module methods, with no signer check:
It updates the expiration of the unique record identified by participant_id and recomputes the on-chain FeeGrant of its containing VSOA. No-op if no record exists for participant_id.
This method does NOT read Participant state; the caller supplies the new expiration value directly.
§ [MOD-DE-MSG-9-1] Update VS Operator Authorization Expiration method parameters
participant_id(uint64) (mandatory): id of the permission whose authorization record’sexpirationmust be updated.new_expiration(timestamp) (mandatory): the new value ofrecord.expiration.
§ [MOD-DE-MSG-9-2] Update VS Operator Authorization Expiration basic checks
participant_idMUST be a valid uint64.new_expirationMUST be a valid timestamp.
Note: absence of a record for
participant_idis NOT an error. The method is a no-op in that case (the permission does not enable VS operator authorization).
§ [MOD-DE-MSG-9-3] Update VS Operator Authorization Expiration fee checks
- Fee payer MUST have the required estimated transaction fees in its account.
§ [MOD-DE-MSG-9-4] Update VS Operator Authorization Expiration execution of the method
- Locate the unique
ParticipantAuthorizationRecordrecordwithrecord.participant_id = participant_id. If none exists, EXIT (no-op). - Set
record.expiration = new_expiration. - Call Recompute VS Operator Fee Allowance for the VSOA containing
record.
§ [MOD-DE-QRY-1] List Operator Authorizations
Anyone CAN execute this method.
§ [MOD-DE-QRY-1-1] List Operator Authorizations parameters
corporation(group) (optional): filter by the corporation group that granted the authorization.operator(account) (optional): filter by the operator account that received the authorization.response_max_size(small number) (optional): limit toresponse_max_sizeresults. Must be min 1, max 1,024. Default to 64.
§ [MOD-DE-QRY-1-2] List Operator Authorizations checks
Basic type check arg SHOULD be applied.
If any of these checks fail, query MUST fail.
response_max_sizemust be between 1 and 1,024. Default to 64 if unspecified.
§ [MOD-DE-QRY-1-3] List Operator Authorizations execution
Return a list of OperatorAuthorization entries matching the filter criteria, or an empty list if nothing found.
§ [MOD-DE-QRY-2] List VS Operator Authorizations
Anyone CAN execute this method.
§ [MOD-DE-QRY-2-1] List VS Operator Authorizations parameters
corporation(group) (optional): filter by the corporation group that granted the authorization.vs_operator(account) (optional): filter by the VS operator account that received the authorization.response_max_size(small number) (optional): limit toresponse_max_sizeresults. Must be min 1, max 1,024. Default to 64.
§ [MOD-DE-QRY-2-2] List VS Operator Authorizations checks
Basic type check arg SHOULD be applied.
If any of these checks fail, query MUST fail.
response_max_sizemust be between 1 and 1,024. Default to 64 if unspecified.
§ [MOD-DE-QRY-2-3] List VS Operator Authorizations execution
Return a list of VSOperatorAuthorization entries matching the filter criteria, or an empty list if nothing found.
§ [MOD-DI-MSG-1] Store Digest
- Any authorized
operatorCAN execute this method on behalf of acorporation. - This method can be called directly by Create or Update Participant Session module with no checks.
§ [MOD-DI-MSG-1-1] Store Digest method parameters
corporation(group) (mandatory): (Signer) the signing corporation on whose behalf this message is executed.operator(account) (mandatory): (Signer) the account authorized by thecorporationto run this Msg.digest(string) (mandatory): digest to store.
§ [MOD-DI-MSG-1-2] Store Digest precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-DI-MSG-1-2-1] Store Digest basic checks
if any of these conditions is not satisfied, transaction MUST abort.
corporation(group): (Signer) signature must be verified.operator(account): (Signer) signature must be verified.- [AUTHZ-CHECK] MUST pass for this (
corporation,operator) pair and this message type. - if
digestis not present, abort.
§ [MOD-DI-MSG-1-2-2] Store Digest fee checks
- Fee payer MUST have the required estimated transaction fees in its account;
§ [MOD-DI-MSG-1-3] Store Digest execution of the method
Method execution MUST perform the following tasks in a transaction, and rollback if any error occurs.
- define
now: current timestamp.
Create Digest digest:
- set
digest.digestto digest - set
digest.createdto now.
§ [MOD-DI-QRY-1] Get Digest
Anyone CAN execute this method.
§ [MOD-DI-QRY-1-1] Get Digest parameters
digest(string) (mandatory): the digest to look up.
§ [MOD-DI-QRY-1-2] Get Digest checks
If any of these checks fail, query MUST fail.
digestMUST not be empty.
§ [MOD-DI-QRY-1-3] Get Digest execution
If all checks passed, query is executed.
Return found Digest entry (if any) matching digest.
§ [MOD-DI-QRY-1-4] Get Digest API result example
{
"digest": {
"digest": "sha384-MzNNbQTWCSUSi0bbz7dbua+RcENv7C6FvlmYJ1Y+I727HsPOHdzwELMYO9Mz68M26",
"created": "2025-01-14T19:40:37.967Z"
}
}
§ [MOD-XR-MSG-1] Create Exchange Rate
The Create Exchange Rate method allows creating an ExchangeRate entry for a given (base_asset_type, base_asset, quote_asset_type, quote_asset) pair.
- Only a governance proposal CAN execute this method.
§ [MOD-XR-MSG-1] Create Exchange Rate method parameters
base_asset_type(PricingAssetType, mandatory)base_asset(string, mandatory)quote_asset_type(PricingAssetType, mandatory)quote_asset(string, mandatory)rate(string, mandatory)rate_scale(uint32, mandatory)validity_duration(duration, mandatory)
§ [MOD-XR-MSG-1] Create Exchange Rate precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-XR-MSG-1] Create Exchange Rate basic checks
If any of the following conditions is not satisfied, transaction MUST abort.
-
Asset type validity
base_asset_typeMUST be a validPricingAssetTypevalue.quote_asset_typeMUST be a validPricingAssetTypevalue.
-
Asset identifier basic validity
base_assetMUST be non-empty.quote_assetMUST be non-empty.
-
Asset type / identifier consistency
-
If
base_asset_type = TRUST_UNIT:base_assetMUST equal"TU".
-
If
quote_asset_type = TRUST_UNIT:quote_assetMUST equal"TU".
-
If
base_asset_type = COIN:base_assetMUST be a valid Cosmos-SDK denom string.base_assetMUST correspond to an asset that exists on-chain (i.e., denom is recognized by the chain and can be held in balances).- If
base_assetstarts withibc/, a denom trace for this denom MUST exist in the IBC transfer module store. - If
base_assetstarts withfactory/, the denom MUST be a valid tokenfactory denom and the corresponding token MUST exist.
-
If
quote_asset_type = COIN:quote_assetMUST be a valid Cosmos-SDK denom string.quote_assetMUST correspond to an asset that exists on-chain.- If
quote_assetstarts withibc/, a denom trace for this denom MUST exist in the IBC transfer module store. - If
quote_assetstarts withfactory/, the denom MUST be a valid tokenfactory denom and the corresponding token MUST exist.
-
If
base_asset_type = FIAT:base_assetMUST be a valid ISO-4217 currency code.
-
If
quote_asset_type = FIAT:quote_assetMUST be a valid ISO-4217 currency code.
-
-
Pair validity
- The pair
(base_asset_type, base_asset, quote_asset_type, quote_asset)MUST NOT be identical on both sides (base and quote MUST NOT represent the same asset). - The pair
(base_asset_type, base_asset, quote_asset_type, quote_asset)MUST be unique in storage. If an entry already exists, execution MUST abort.
- The pair
-
Rate validity
rateMUST be a base-10 encoded unsigned integer string.rateMUST be strictly greater than"0".rate_scaleMUST be within protocol-defined limits (e.g.,rate_scale <= 18).
-
validity_duration
validity_durationMUST be greater or equal to1 minute.
§ [MOD-XR-MSG-1] Create Exchange Rate fee checks
Fee payer MUST have sufficient estimated transaction fees.
§ [MOD-XR-MSG-1] Create Exchange Rate execution of the method
Create ExchangeRate entry xr:
xr.id= auto generated idxr.base_asset_type=base_asset_typexr.base_asset=base_assetxr.quote_asset_type=quote_asset_typexr.quote_asset=quote_assetxr.rate=ratexr.rate_scale=rate_scalexr.validity_duration=validity_durationxr.expires= block timestamp +validity_durationxr.state= falsexr.updated= block timestamp
§ [MOD-XR-MSG-2] Update Exchange Rate
The Update Exchange Rate method allows an operator authorized by network governance (via an ExchangeRateAuthorization) to push a fresh rate for a given ExchangeRate entry.
- Only the
operatordesignated in anExchangeRateAuthorizationmatching the targetExchangeRateCAN execute this method.
§ [MOD-XR-MSG-2] Update Exchange Rate method parameters
operator(account) (mandatory): (Signer) the account pushing the new rate.id(uint64, mandatory): id of the targetExchangeRateentry.rate(string, mandatory): the new fixed-point integer rate value.
§ [MOD-XR-MSG-2] Update Exchange Rate precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-XR-MSG-2] Update Exchange Rate basic checks
If any of the following conditions is not satisfied, transaction MUST abort.
-
operator(account): (Signer) signature MUST be verified. -
id(uint64, mandatory) MUST refer to an existingExchangeRateentryxrwithxr.state= true. -
rateMUST be strictly greater than"0". -
Authorization:
- An
ExchangeRateAuthorizationxrauthzMUST exist wherexrauthz.xr_id=idandxrauthz.operator=operator. xrauthz.expirationMUST be in the future (now() < xrauthz.expiration).- If
xrauthz.min_intervalis set, thennow() - xr.updatedMUST be greater than or equal toxrauthz.min_interval. - If
xrauthz.max_deviation_bpsis set, then|rate - xr.rate| * 10000MUST be less than or equal toxrauthz.max_deviation_bps * xr.rate(i.e., the relative change between the newrateandxr.rateMUST NOT exceedxrauthz.max_deviation_bpsbasis points). Both values share the samexr.rate_scale, sinceMOD-XR-MSG-2does not update the scale.
- An
§ [MOD-XR-MSG-2] Update Exchange Rate fee checks
Fee payer MUST have sufficient estimated transaction fees.
§ [MOD-XR-MSG-2] Update Exchange Rate execution of the method
Load ExchangeRate xr.
xr.rate=ratexr.expires= block time +xr.validity_durationxr.updated= block time
§ [MOD-XR-MSG-3] Toggle Exchange Rate State
The Toggle Exchange Rate State method allows an authorized actor to enable or disable an exchange rate.
§ [MOD-XR-MSG-3] Toggle Exchange Rate State method parameters
id(uint64, mandatory): id of the exchange ratestate(boolean, mandatory): true to set enabled, false to set disabled
§ [MOD-XR-MSG-3] Toggle Exchange Rate State precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-XR-MSG-3] Toggle Exchange Rate State basic checks
If any of the following conditions is not satisfied, transaction MUST abort.
-
Authorization
- Only a governance proposal can enable or disable an exchange rate.
-
ExchangeRate with id
idMUST exist.
§ [MOD-XR-MSG-3] Toggle Exchange Rate State fee checks
Fee payer MUST have sufficient estimated transaction fees.
§ [MOD-XR-MSG-3] Toggle Exchange Rate State execution of the method
Load ExchangeRate xr.
- set
xr.stateto !xr.state. - set
xr.updatedto block time
§ [MOD-XR-MSG-4] Grant Exchange Rate Authorization
The Grant Exchange Rate Authorization method creates (or updates) an ExchangeRateAuthorization record designating a network-level operator allowed to push fresh rates for a given ExchangeRate via [MOD-XR-MSG-2].
- Only a governance proposal CAN execute this method.
§ [MOD-XR-MSG-4] Grant Exchange Rate Authorization method parameters
xr_id(uint64) (mandatory): id of the targetExchangeRate.operator(account) (mandatory): the account receiving the authorization.expiration(timestamp) (mandatory): authorization end-of-life.min_interval(duration) (optional): minimum time between two successive [MOD-XR-MSG-2] calls under this authorization.max_deviation_bps(uint32) (optional): maximum relative change per update, in basis points.
§ [MOD-XR-MSG-4] Grant Exchange Rate Authorization precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-XR-MSG-4] Grant Exchange Rate Authorization basic checks
If any of the following conditions is not satisfied, transaction MUST abort.
- Authorization
- Only a governance proposal can grant an
ExchangeRateAuthorization.
- Only a governance proposal can grant an
xr_idMUST refer to an existingExchangeRateentry.operatorMUST be a valid account.expirationMUST be in the future.min_interval, if specified, MUST be a valid, strictly positive duration.max_deviation_bps, if specified, MUST be strictly greater than0and less than or equal to10000.
§ [MOD-XR-MSG-4] Grant Exchange Rate Authorization fee checks
Fee payer MUST have sufficient estimated transaction fees.
§ [MOD-XR-MSG-4] Grant Exchange Rate Authorization execution of the method
Create (or update if it already exists) ExchangeRateAuthorization xrauthz keyed by (xr_id, operator):
xrauthz.xr_id=xr_idxrauthz.operator=operatorxrauthz.expiration=expirationxrauthz.min_interval=min_interval(if provided, else unset)xrauthz.max_deviation_bps=max_deviation_bps(if provided, else unset)
§ [MOD-XR-MSG-5] Revoke Exchange Rate Authorization
The Revoke Exchange Rate Authorization method deletes an existing ExchangeRateAuthorization record, immediately preventing the designated operator from executing further [MOD-XR-MSG-2] calls on the target ExchangeRate.
- Only a governance proposal CAN execute this method.
§ [MOD-XR-MSG-5] Revoke Exchange Rate Authorization method parameters
xr_id(uint64) (mandatory): id of the targetExchangeRate.operator(account) (mandatory): the account whose authorization is revoked.
§ [MOD-XR-MSG-5] Revoke Exchange Rate Authorization precondition checks
If any of these precondition checks fail, transaction MUST abort.
§ [MOD-XR-MSG-5] Revoke Exchange Rate Authorization basic checks
If any of the following conditions is not satisfied, transaction MUST abort.
- Authorization
- Only a governance proposal can revoke an
ExchangeRateAuthorization.
- Only a governance proposal can revoke an
- An
ExchangeRateAuthorizationentry MUST exist for (xr_id,operator).
§ [MOD-XR-MSG-5] Revoke Exchange Rate Authorization fee checks
Fee payer MUST have sufficient estimated transaction fees.
§ [MOD-XR-MSG-5] Revoke Exchange Rate Authorization execution of the method
- Delete
ExchangeRateAuthorizationentry for (xr_id,operator).
§ [MOD-XR-QRY-1] Get Exchange Rate
Any account CAN run this query.
§ [MOD-XR-QRY-1-1] Get Exchange Rate query parameters
state(boolean, optional): to force state, enabled or disabledexpire_ts(timestamp, optional): return only if expire_ts is greater thanexpire_ts
AND:
(
id(uint64) (mandatory): the id of the exchange rate to get
OR:
base_asset_type(PricingAssetType, mandatory)base_asset(string, mandatory)quote_asset_type(PricingAssetType, mandatory)quote_asset(string, mandatory)
)
§ [MOD-XR-QRY-1-2] Get Exchange Rate query checks
If any of these checks fail, query MUST fail.
id(uint64) (mandatory): MUST exist,
OR
an ExchangeRate entry with base_asset_type, base_asset, quote_asset_type, quote_asset MUST exist.
§ [MOD-XR-QRY-1-3] Get Exchange Rate execution of the query
If found, returns ExchangeRate entry, else return not found.
§ [MOD-XR-QRY-2] List Exchange Rates
Any account CAN run this query. As this method does not modify data, it does not require a transaction.
§ [MOD-XR-QRY-2-1] List Exchange Rates query parameters
base_asset_type(PricingAssetType, optional)base_asset(string, optional)quote_asset_type(PricingAssetType, optional)quote_asset(string, optional)state(boolean, optional): to force state, enabled or disabledexpire(timestamp, optional): return only if expire is greater thanexpire
§ [MOD-XR-QRY-2-2] List Exchange Rates query checks
§ [MOD-XR-QRY-2-3] List Exchange Rates execution of the query
If found, returns a list of found ExchangeRates, else return an empty list.
§ [MOD-XR-QRY-3] Get Price
Anyone CAN run this query, throgh module call or using the API.
§ [MOD-XR-QRY-3] Get Price Example
base_asset_type = TU base_asset = “tu” quote_asset_type = COIN quote_asset = “uvna” rate = R rate_scale = S
If a valid ExchangeRate entry exists with:
base_asset_type = TUbase_asset = "tu"quote_asset_type = COINquote_asset = "uvna"
then the price of amount Trust Unit expressed in uvna MUST be computed using the following formula:
price_uvna = floor(amount * rate / 10^rate_scale)
Where:
rateandrate_scaleare the values stored in the correspondingExchangeRateentry.price_uvnais expressed in micro-denominated VNA units (uvna).- Rounding MUST always be performed downwards.
If the corresponding ExchangeRate entry is expired or missing, the conversion MUST fail.
§ [MOD-XR-QRY-3-1] Get Price parameters
base_asset_type(PricingAssetType, optional)base_asset(string, optional)quote_asset_type(PricingAssetType, optional)quote_asset(string, optional)amount(number, mandatory)
§ [MOD-XR-QRY-3-2] Get Price query checks
If the corresponding ExchangeRate entry is expired or missing, the conversion MUST fail and an error is returned
§ [MOD-XR-QRY-3-3] Get Price execution of the query
- if (base_asset_type, base_asset) == (quote_asset_type, quote_asset):
price=amount. - else load (base_asset_type, base_asset, quote_asset_type, quote_asset).
- if entry doesn’t exist or is not active or expired, abort and generate an error.
- else return
price= floor(amount * rate / 10^rate_scale)
- Conversions use base units only.
- Integer arithmetic MUST be used.
quote_amount = floor(base_amount × rate / 10^rate_scale).- Expired rates MUST NOT be used.
§ Initial Data Requirements
§ [GLO] Global Variables
Global variables CAN only be changed by the governance authority through proposals.
Default values MUST be set at VPR initialization (genesis). Below you’ll find some possible values. These values will have to be defined in the governance framework.
Credential Schema:
credential_schema_schema_max_size(number) (mandatory): 8192.credential_schema_issuer_grantor_validation_validity_period_max_days(number) (mandatory): 3650.credential_schema_verifier_grantor_validation_validity_period_max_days(number) (mandatory): 3650.credential_schema_issuer_validation_validity_period_max_days(number) (mandatory): 3650.credential_schema_verifier_validation_validity_period_max_days(number) (mandatory): 3650.credential_schema_holder_validation_validity_period_max_days(number) (mandatory): 3650.
Trust Deposit:
-
trust_deposit_share_value(number) (mandatory): 1. -
trust_deposit_rate(number) (mandatory): 0.20. -
trust_deposit_max_yield_rate(number) (mandatory): 0.20 -
trust_deposit_block_reward_share(number) (mandatory): 0.20 -
wallet_user_agent_reward_rate(number) (mandatory): 0.10. -
user_agent_reward_rate(number) (mandatory): 0.10.
§ References
§ Normative References
- DID-CORE
- Decentralized Identifiers (DIDs) v1.0. Manu Sporny; Amy Guy; Markus Sabadello; Drummond Reed; 2022-07-19. Status: REC.
- RFC3986
- Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter; 2005-01. Status: Internet Standard.
- VC-DATA-MODEL
- Verifiable Credentials Data Model v1.1. Manu Sporny; Grant Noble; Dave Longley; Daniel Burnett; Brent Zundel; Kyle Den Hartog; 2022-03-03. Status: REC.