From 5072081d0affc8f4f97d91246b37e0d746c4fea6 Mon Sep 17 00:00:00 2001 From: Alwyn van Wyk Date: Sat, 4 Nov 2023 16:19:22 +0200 Subject: [PATCH 1/7] update to include all chain docs, not only .md --- .github/workflows/pull-docs.yml | 77 ++++++++++++++++++++--------- developers/ixo-blockchain/README.md | 0 2 files changed, 54 insertions(+), 23 deletions(-) delete mode 100644 developers/ixo-blockchain/README.md diff --git a/.github/workflows/pull-docs.yml b/.github/workflows/pull-docs.yml index 15fc72e..cdad0f7 100644 --- a/.github/workflows/pull-docs.yml +++ b/.github/workflows/pull-docs.yml @@ -1,29 +1,60 @@ -name: Pull README.md from the ixo-blockchain repository - -on: - pull_request_review_comment: - branches: - - develop +name: Copy .md from ixo-blockchain +run-name: ${{ github.actor }} pushed a change. +on: [push] jobs: - pull-readme: + copy-docs-from-blockchain-repo: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 + with: + ref: alwyn-ixopatch-1 + + - name: Checkout ixo-blockchain + uses: actions/checkout@v4 + with: + repository: ixofoundation/ixo-blockchain + ref: develop + path: ixo-blockchain + + - name: Checkout ixo-signx + uses: actions/checkout@v4 + with: + repository: ixofoundation/ixo-signx + ref: main + path: ixo-signx + + - name: Checkout ixo-message-relayer + uses: actions/checkout@v4 + with: + repository: ixofoundation/ixo-message-relayer + ref: main + path: ixo-message-relayer - - name: Get *.md files from the ixo-blockchain repository - run: | - curl -O https://raw.githubusercontent.com/ixofoundation/ixo-blocksync/develop/**/*.md + - run: mkdir -p ./developers/ixo-blockchain/bonds + - run: mkdir -p ./developers/ixo-blockchain/claims + - run: mkdir -p ./developers/ixo-blockchain/entity + - run: mkdir -p ./developers/ixo-blockchain/iid + - run: mkdir -p ./developers/ixo-blockchain/token - - name: Move README.md to destination - run: | - mv *.md developers/ixo-blockchain + - run: cp -R ./ixo-blockchain/x/bonds/spec ./developers/ixo-blockchain/bonds + - run: cp -R ./ixo-blockchain/x/claims/spec ./developers/ixo-blockchain/claims + - run: cp -R ./ixo-blockchain/x/entity/spec ./developers/ixo-blockchain/entity + - run: cp -R ./ixo-blockchain/x/iid/spec ./developers/ixo-blockchain/iid + - run: cp -R ./ixo-blockchain/x/token/spec ./developers/ixo-blockchain/token + + - run: mkdir -p ./developers/ixo-signx + - run: find ./ixo-signx -type f -name "*.md" -exec cp -R {} ./developers/ixo-signx \; + + - run: mkdir -p ./developers/ixo-message-relayer + - run: find ./ixo-message-relayer -type f -name "*.md" -exec cp -R {} ./developers/ixo-message-relayer \; - - name: Create PR - uses: actions/create-pull-request@v4 - with: - title: "Pull .md files from ixo-block" - body: "This PR pulls the .md files from my-other-repo into the docs directory." - branch: "${{GITHUB_BRANCH}}" - base: develop - files: developers/ixo-blockchain/**/*.md + - run: rm -R ./ixo-blockchain + - run: rm -R ./ixo-signx + - run: rm -R ./ixo-message-relayer + + - run: git add . + - run: git config --global user.email "ixo@ixo.world" + - run: git config --global user.name ${{ github.actor }} + - run: git commit -m "Copy *.md files from other repos" + - run: git push \ No newline at end of file diff --git a/developers/ixo-blockchain/README.md b/developers/ixo-blockchain/README.md deleted file mode 100644 index e69de29..0000000 From 5a71b3c5ca1c31161e9a506d76b1df5193e1456f Mon Sep 17 00:00:00 2001 From: Alwyn van Wyk Date: Sat, 4 Nov 2023 14:24:21 +0000 Subject: [PATCH 2/7] Update pull-docs.yml --- .github/workflows/pull-docs.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull-docs.yml b/.github/workflows/pull-docs.yml index cdad0f7..1b48395 100644 --- a/.github/workflows/pull-docs.yml +++ b/.github/workflows/pull-docs.yml @@ -49,12 +49,12 @@ jobs: - run: mkdir -p ./developers/ixo-message-relayer - run: find ./ixo-message-relayer -type f -name "*.md" -exec cp -R {} ./developers/ixo-message-relayer \; - - run: rm -R ./ixo-blockchain - - run: rm -R ./ixo-signx - - run: rm -R ./ixo-message-relayer + # - run: rm -R ./ixo-blockchain + # - run: rm -R ./ixo-signx + # - run: rm -R ./ixo-message-relayer - run: git add . - run: git config --global user.email "ixo@ixo.world" - run: git config --global user.name ${{ github.actor }} - run: git commit -m "Copy *.md files from other repos" - - run: git push \ No newline at end of file + - run: git push From a79a72d2f71ba19b0f48c2af86400904db550958 Mon Sep 17 00:00:00 2001 From: Alwyn van Wyk Date: Sat, 4 Nov 2023 14:29:40 +0000 Subject: [PATCH 3/7] Update pull-docs.yml --- .github/workflows/pull-docs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pull-docs.yml b/.github/workflows/pull-docs.yml index 1b48395..c9bf7b0 100644 --- a/.github/workflows/pull-docs.yml +++ b/.github/workflows/pull-docs.yml @@ -8,7 +8,7 @@ jobs: - name: Checkout uses: actions/checkout@v4 with: - ref: alwyn-ixopatch-1 + ref: alwyn-ixopatch-2 - name: Checkout ixo-blockchain uses: actions/checkout@v4 @@ -57,4 +57,4 @@ jobs: - run: git config --global user.email "ixo@ixo.world" - run: git config --global user.name ${{ github.actor }} - run: git commit -m "Copy *.md files from other repos" - - run: git push + - run: git push origin alwyn-ixopatch-2 From 529eed39dcddfb30a21bbe66bf5cbd143610d7c7 Mon Sep 17 00:00:00 2001 From: alwyn-ixo Date: Sat, 4 Nov 2023 14:29:55 +0000 Subject: [PATCH 4/7] Copy *.md files from other repos --- .../ixo-blockchain/bonds/spec/01_concepts.md | 115 +++++ .../ixo-blockchain/bonds/spec/02_state.md | 22 + .../ixo-blockchain/bonds/spec/03_messages.md | 391 ++++++++++++++++ .../ixo-blockchain/bonds/spec/04_end_block.md | 58 +++ .../ixo-blockchain/bonds/spec/05_events.md | 285 ++++++++++++ .../ixo-blockchain/bonds/spec/06_params.md | 7 + .../bonds/spec/07_future_improvements.md | 10 + .../bonds/spec/08_functions_library.ipynb | 119 +++++ .../ixo-blockchain/bonds/spec/README.md | 89 ++++ .../ixo-blockchain/claims/spec/01_concepts.md | 97 ++++ .../ixo-blockchain/claims/spec/02_state.md | 406 ++++++++++++++++ .../ixo-blockchain/claims/spec/03_messages.md | 136 ++++++ .../ixo-blockchain/claims/spec/04_events.md | 115 +++++ .../ixo-blockchain/claims/spec/05_params.md | 10 + .../claims/spec/06_future_improvements.md | 13 + .../ixo-blockchain/claims/spec/README.md | 67 +++ .../claims/spec/assets/vc_graph.svg | 111 +++++ .../claims/spec/assets/vc_life.svg | 81 ++++ .../ixo-blockchain/entity/spec/01_concepts.md | 43 ++ .../ixo-blockchain/entity/spec/02_state.md | 73 +++ .../ixo-blockchain/entity/spec/03_messages.md | 157 +++++++ .../ixo-blockchain/entity/spec/04_events.md | 115 +++++ .../ixo-blockchain/entity/spec/05_params.md | 9 + .../entity/spec/06_future_improvements.md | 5 + .../ixo-blockchain/entity/spec/README.md | 51 ++ .../ixo-blockchain/iid/spec/01_concepts.md | 106 +++++ .../ixo-blockchain/iid/spec/02_state.md | 238 ++++++++++ .../ixo-blockchain/iid/spec/03_messages.md | 397 ++++++++++++++++ .../ixo-blockchain/iid/spec/04_events.md | 31 ++ .../ixo-blockchain/iid/spec/05_params.md | 3 + .../iid/spec/06_future_improvements.md | 7 + developers/ixo-blockchain/iid/spec/README.md | 73 +++ .../iid/spec/assets/did_doc.svg | 435 ++++++++++++++++++ .../ixo-blockchain/token/spec/01_concepts.md | 51 ++ .../ixo-blockchain/token/spec/02_state.md | 184 ++++++++ .../ixo-blockchain/token/spec/03_messages.md | 181 ++++++++ .../ixo-blockchain/token/spec/04_events.md | 139 ++++++ .../ixo-blockchain/token/spec/05_params.md | 7 + .../token/spec/06_future_improvements.md | 3 + .../ixo-blockchain/token/spec/README.md | 68 +++ developers/ixo-message-relayer/README.md | 409 ++++++++++++++++ developers/ixo-signx/README.md | 321 +++++++++++++ ixo-blockchain | 1 + ixo-message-relayer | 1 + ixo-signx | 1 + 45 files changed, 5241 insertions(+) create mode 100644 developers/ixo-blockchain/bonds/spec/01_concepts.md create mode 100644 developers/ixo-blockchain/bonds/spec/02_state.md create mode 100644 developers/ixo-blockchain/bonds/spec/03_messages.md create mode 100644 developers/ixo-blockchain/bonds/spec/04_end_block.md create mode 100644 developers/ixo-blockchain/bonds/spec/05_events.md create mode 100644 developers/ixo-blockchain/bonds/spec/06_params.md create mode 100644 developers/ixo-blockchain/bonds/spec/07_future_improvements.md create mode 100644 developers/ixo-blockchain/bonds/spec/08_functions_library.ipynb create mode 100644 developers/ixo-blockchain/bonds/spec/README.md create mode 100644 developers/ixo-blockchain/claims/spec/01_concepts.md create mode 100644 developers/ixo-blockchain/claims/spec/02_state.md create mode 100644 developers/ixo-blockchain/claims/spec/03_messages.md create mode 100644 developers/ixo-blockchain/claims/spec/04_events.md create mode 100644 developers/ixo-blockchain/claims/spec/05_params.md create mode 100644 developers/ixo-blockchain/claims/spec/06_future_improvements.md create mode 100644 developers/ixo-blockchain/claims/spec/README.md create mode 100644 developers/ixo-blockchain/claims/spec/assets/vc_graph.svg create mode 100644 developers/ixo-blockchain/claims/spec/assets/vc_life.svg create mode 100644 developers/ixo-blockchain/entity/spec/01_concepts.md create mode 100644 developers/ixo-blockchain/entity/spec/02_state.md create mode 100644 developers/ixo-blockchain/entity/spec/03_messages.md create mode 100644 developers/ixo-blockchain/entity/spec/04_events.md create mode 100644 developers/ixo-blockchain/entity/spec/05_params.md create mode 100644 developers/ixo-blockchain/entity/spec/06_future_improvements.md create mode 100644 developers/ixo-blockchain/entity/spec/README.md create mode 100644 developers/ixo-blockchain/iid/spec/01_concepts.md create mode 100644 developers/ixo-blockchain/iid/spec/02_state.md create mode 100644 developers/ixo-blockchain/iid/spec/03_messages.md create mode 100644 developers/ixo-blockchain/iid/spec/04_events.md create mode 100644 developers/ixo-blockchain/iid/spec/05_params.md create mode 100644 developers/ixo-blockchain/iid/spec/06_future_improvements.md create mode 100644 developers/ixo-blockchain/iid/spec/README.md create mode 100644 developers/ixo-blockchain/iid/spec/assets/did_doc.svg create mode 100644 developers/ixo-blockchain/token/spec/01_concepts.md create mode 100644 developers/ixo-blockchain/token/spec/02_state.md create mode 100644 developers/ixo-blockchain/token/spec/03_messages.md create mode 100644 developers/ixo-blockchain/token/spec/04_events.md create mode 100644 developers/ixo-blockchain/token/spec/05_params.md create mode 100644 developers/ixo-blockchain/token/spec/06_future_improvements.md create mode 100644 developers/ixo-blockchain/token/spec/README.md create mode 100644 developers/ixo-message-relayer/README.md create mode 100644 developers/ixo-signx/README.md create mode 160000 ixo-blockchain create mode 160000 ixo-message-relayer create mode 160000 ixo-signx diff --git a/developers/ixo-blockchain/bonds/spec/01_concepts.md b/developers/ixo-blockchain/bonds/spec/01_concepts.md new file mode 100644 index 0000000..3497108 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/01_concepts.md @@ -0,0 +1,115 @@ +# Concepts + +## Token Bonding Curves + +Bonding curves are continuous liquidity mechanisms which are used in market design for cryptographically-supported token economies. Tokens are atomic units of state information which are cryptographically verifiable in peer-to-peer networks. Bonding curves are an example of an enforceable mechanism through which participating agents influence this state. By designing such mechanisms, an engineer may establish the topological structure of a token economy without presupposing the utilities or associated actions of the agents within that economy. + +Token Bonding Curves are therefore an important crypto-economic mechanism for building a wide range of capabilities directly into decentralised applications. They can function simultaneously as means of decentralised capital formation, liquidity provision and autonomous market maker. +Bonding curves are powerful tools because the tokens they issue can represent rights - including + +- rights of access +- rights of use +- rights of ownership, and +- voting rights. + +In the case of continuous organizations, tokens issued through bonding curves embody rights to the future revenues of a startup. +In the augmented bonding curve, tokens can embody the rights to govern how funds are spent by a not-for-profit organization. +In an Alpha-Bond, tokens can give holders the rights to future outcomes payments and performance incentive bonuses. + +## Token Bonds Module + +The Token Bonds Cosmos SDK Module enables applications that use token bonding curves to be created on-the-fly. +Each new Token B instance declares a new token denomination in the application, with a set of parameters. +The module stores the current state of all tokens that have been created using this module. +Changes in state occur through transactions that are instructed by valid _buy, sell, and swap_ messages. + +**Buy** instructions cause bond tokens to be minted during a state transition. This increases the total supply balance of tokens. +**Sell** instructions burn bond tokens during a state transition that decreases the total supply balance of tokens. +**Limits** are set for the maximum numbers of bond tokens that can exist at any point in state. + +Bond Tokens trade against pairings in their Bond Reserve. + +The bonding curve forms an interface between the reserve token quantity and the bond token price (in the Reserve currency). + +Bonding curves are defined by their mathematical properties. This is determined by the type of curve function and by the function parameters that are set. Generally these parameters are chosen to best-fit empiricially-observed market dynamics of supply and demand. +External parameters, such as market supply and demand, are complex and typically hard to predict. + +--- + +Pricing is defined by the function type and function parameters, which can define either the pricing function of the bond as a function of the supply, or simply indicate that the bond is a token swapper, where pricing is instead defined by the first buyer and any swaps performed thereafter. + +A bond may also specify non-zero fees, which are calculated based on the size of an order and sent to the specified fee address, order quantity limits to limit the size of orders, disable the ability to sell tokens, specify multiple signers that will need to sign for any editing of the bond details, and in the case of swapper bonds, sanity values to set a range of valid exchange rate between the two reserve tokens. Lastly, a bond has a string state value, which in most cases is OPEN, but in certain function types it has more meaning, such as for augmented bonding curves, in which case it can be OPEN \[for open phase\] and HATCH \[for hatch phase\]. This state is _not_ specified by the creator during bond creation. + +```go +type Bond struct { + Token string + Name string + Description string + CreatorDid string + ControllerDid string + FunctionType string + FunctionParameters FunctionParams + ReserveTokens []string + TxFeePercentage sdk.Dec + ExitFeePercentage sdk.Dec + FeeAddress string + ReserveWithdrawalAddress string + MaxSupply sdk.Coin + OrderQuantityLimits sdk.Coins + SanityRate sdk.Dec + SanityMarginPercentage sdk.Dec + CurrentSupply sdk.Coin + CurrentReserve sdk.Coins + AvailableReserve sdk.Coins + CurrentOutcomePaymentReserve sdk.Coins + AllowSells bool + AllowReserveWithdrawals bool + AlphaBond bool + BatchBlocks sdk.Uint + OutcomePayment sdk.Int + State string + BondDid string +} +``` + +The following is a list of all possible bond states: + +- `"HATCH"` +- `"OPEN"` +- `"SETTLED"` +- `"FAILED"` + +By default, a newly created bond will be in state OPEN, unless the bond is an augmented bonding curve, in which case the initial state is HATCH. +The following are the valid transitions between bond states. + +
+- HATCH -> OPEN or FAILED
+- OPEN  -> SETTLE or FAILED
+
+ +No valid transitions exist from the SETTLE and FAILED states. + +## Batching + +For each bond, a single corresponding batch holds a collection of outstanding buy, sell, and swap orders. The lifespan of a batch, in terms of the number of blocks, is defined in the corresponding bond (`BatchBlocks`). + +Orders can be added to the current batch at any point in time. Any order that is not cancelled by the end of the batch's lifespan is eligible to get fulfilled. Otherwise, the order is discarded and any actions that were already performed are reverted. + +The primary task of the batching mechanism is to find a common price for all of the buys and sells submitted to the batch by summing up all of the buys and sells, thus ignoring their order, and matching-up the total buy and sell amounts to give balanced and fair global buy and sell prices. + +For alpha bonds, the batch also stores the next alpha value, if it was changed throughout the lifetime of the batch. If alpha has not changed, then it will show up as `-1`. + +```go +type Batch struct { + BondDid string + BlocksRemaining sdk.Uint + NextPublicAlpha sdk.Dec + TotalBuyAmount sdk.Coin + TotalSellAmount sdk.Coin + BuyPrices sdk.DecCoins + SellPrices sdk.DecCoins + Buys []BuyOrder + Sells []SellOrder + Swaps []SwapOrder +} +``` diff --git a/developers/ixo-blockchain/bonds/spec/02_state.md b/developers/ixo-blockchain/bonds/spec/02_state.md new file mode 100644 index 0000000..6c7db06 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/02_state.md @@ -0,0 +1,22 @@ +# State + +## Bonds + +The instance of a bond is stored with its bond-specific parameters. This record is accessed by the identity of a token that represents the bond. + +- Bonds: `0x00 | tokenHash -> ProtocolBuffer(Bond)` + +## Batches + +As a protection against front-runnning orders, a batching mechanism creates a cache of orders and combines these into a single transaction when the batch conditions have been met. +The state of 2 consecutive batches is held for both the current and last (previous) batch. +This enables querying the final state of a batch before the orders were fulfilled, after the transaction has completed. +The temporary state of a batch in the current block is not observable. This batch is cleared as soon as the batch transaction has completed. + +### Querying Batches + +Batches are accessed by the identity token of the bond. + +- Current Batches: `0x01 | bondDid -> ProtocolBuffer(Batch) ` + +- Last Batches: `0x02 | bondDid -> ProtocolBuffer(Batch) ` diff --git a/developers/ixo-blockchain/bonds/spec/03_messages.md b/developers/ixo-blockchain/bonds/spec/03_messages.md new file mode 100644 index 0000000..3416e48 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/03_messages.md @@ -0,0 +1,391 @@ +# Messages + +In this section we describe the processing of the bonds messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state.md) section. + +## MsgCreateBond + +Bonds can be created by any address using `MsgCreateBond`. + +| **Field** | **Type** | **Description** | +| :----------------------- | :--------------- | :------------------------------------------------------------------------------------------------------------------------ | +| BondDid | `did.Did` | DID of the bond (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Token | `string` | The denomination of the bond's tokens (e.g. `abc`, `mytoken1`) | +| Name | `string` | A friendly name as a title for the bond (e.g. `A B C`, `My Token`) | +| Description | `string` | A description of what the bond represents or its purpose | +| FunctionType | `string` | The type of function that will define the bonding curve (`power_function`, `sigmoid_function`, or `swapper_function`) | +| FunctionParameters | `FunctionParams` | The parameters of the function defining the bonding curve (e.g. `m:12,n:2,c:100`) | +| CreatorDid | `did.Did` | DID of the bond creator (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| ControllerDid | `did.Did` | DID of the bond controller (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| ReserveTokens | `[]string` | The token denominations that will be used as reserve (e.g. `res,rez`) | +| TxFeePercentage | `sdk.Dec` | The percentage fee charged for buys/sells/swaps (e.g. `0.3`) | +| ExitFeePercentage | `sdk.Dec` | The percentage fee charged for sells on top of the tx fee (e.g. `0.2`) | +| FeeAddress | `sdk.AccAddress` | The address of the account that will store charged fees | +| ReserveWithdrawalAddress | `sdk.AccAddress` | The address of the account that will receive any reserve withdrawn by the controller | +| MaxSupply | `sdk.Coin` | The maximum number of bond tokens that can be minted | +| OrderQuantityLimits | `sdk.Coins` | The maximum number of tokens that one can buy/sell/swap in a single order (e.g. `100abc,200res,300rez`) | +| SanityRate | `sdk.Dec` | For a swapper, restricts conversion rate (`r1/r2`) to `sanity rate ยฑ sanity margin percentage`. `0` for no sanity checks. | +| SanityMarginPercentage | `sdk.Dec` | Used as described above. `0` for no sanity checks | +| AllowSells | `bool` | Whether or not selling is allowed (cannot be True if AllowReserveWithdrawals is True) | +| AllowReserveWithdrawals | `bool` | Whether or not reserve withdrawals are allowed (cannot be True if AllowSells is True) | +| AlphaBond | `bool` | Whether or not bond is an alpha bond | +| BatchBlocks | `sdk.Uint` | The lifespan of each orders batch in blocks | +| OutcomePayment | `sdk.Int` | The approximate total payment required to be made in order to transition a bond from OPEN to SETTLE | + +```go +type MsgCreateBond struct { + BondDid string + Token string + Name string + Description string + FunctionType string + FunctionParameters FunctionParams + CreatorDid string + ControllerDid string + ReserveTokens []string + TxFeePercentage sdk.Dec + ExitFeePercentage sdk.Dec + FeeAddress string + ReserveWithdrawalAddress string + MaxSupply sdk.Coin + OrderQuantityLimits sdk.Coins + SanityRate sdk.Dec + SanityMarginPercentage sdk.Dec + AllowSells bool + AllowReserveWithdrawals bool + AlphaBond bool + BatchBlocks sdk.Uint + OutcomePayment sdk.Int +} +``` + +This message is expected to fail if: + +- another bond with this bond DID is already registered +- another bond with this token is already registered, the token is the staking token, or the token is not a valid denomination +- name or description is an empty string +- function type is not one of the defined function types (`power_function`, `sigmoid_function`, `swapper_function`, `augmented_function`) +- function parameters are negative or invalid for the selected function type: + - Valid example for `power_function`: `"m:12.5,n:2,c:100.12"` \ + (i.e. `m=12`, `n=2`, `n=100.12`) + - Valid example for `sigmoid_function`: `"a:3.5,b:5.4,c:1.3"` \ + (i.e. `a=3.5`, `b=5.4`, `c=1.3`) + - Valid example for `augmented_function`: `"d0:500.0,p0:0.01,theta:0.4,kappa:3.0"` \ + (i.e. `d0=500.0`, `p0=0.01`, `theta=0.4`, `kappa=3.0`) + - For `swapper_function`: `""` (no parameters) +- function parameters do not satisfy the extra parameter restrictions + - `sigmoid_function`: `c != 0` + - `augmented_function`: + - `d0 > 0` and must be an integer + - `p0 > 0` + - `0 <= theta < 1` + - `kappa > 0` +- bond DID, creator DID, or controller DID is not a valid DID +- reserve tokens list is invalid. Valid inputs are: + - For `swapper_function`: two valid comma-separated denominations, e.g. `res,rez` + - Otherwise: one or more valid comma-separated denominations, e.g. `res,rez,rex` +- tx or exit fee percentage is negative +- sum of tx and exit fee percentages exceeds 100% +- fee address or reserve withdrawal address are not valid +- order quantity limits is not one or more valid comma-separated amount + - Valid example: `"100res,200rez"` +- max supply value is not in the bond token denomination +- sanity rate is neither an empty string nor a valid decimal +- sanity margin percentage is neither an empty string nor a valid decimal +- sanity rate is not an empty string and sanity margin percentage is an empty string (in other words, sanity rate is defined but sanity margin percentage is not) +- outcome payment is not an integer or is negative +- any field is empty, except for order quantity limits, sanity rate, sanity margin percentage, and function parameters for `swapper_function` +- both AllowSells and AllowReserveWithdrawals are True + +This message creates and stores the `Bond` object at appropriate indexes. Note that the sanity rate and sanity margin percentage are only used in the case of the `swapper_function`, but no error is raised if these are set for other function types. + +## MsgEditBond + +The owner of a bond can edit some of the bond's parameters using `MsgEditBond`. + +| **Field** | **Type** | **Description** | +| :--------------------- | :-------- | :------------------------------------------------------------------------------ | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Name | `string` | Refer to MsgCreateBond | +| Description | `string` | Refer to MsgCreateBond | +| OrderQuantityLimits | `string` | Refer to MsgCreateBond | +| SanityRate | `string` | Refer to MsgCreateBond | +| SanityMarginPercentage | `string` | Refer to MsgCreateBond | +| EditorDid | `did.Did` | DID of the bond editor (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist +- any editable field violates the restrictions set for the same field in `MsgCreateBond` +- all editable fields are `"[do-not-modify]"` +- editor is not the bond creator +- bond DID or editor DID is not a valid DID + +```go +type MsgEditBond struct { + BondDid string + Name string + Description string + OrderQuantityLimits string + SanityRate string + SanityMarginPercentage string + EditorDid string +} +``` + +This message stores the updated `Bond` object. + +## MsgSetNextAlpha + +The controller of a bond can set the next public alpha value for Augmented Bonding Curve type bonds using `MsgSetNextAlpha`. + +| **Field** | **Type** | **Description** | +| :-------- | :-------- | :------------------------------------------------------------------------------ | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Alpha | `sdk.Dec` | Public alpha value to be set (e.g. `0.5`) | +| EditorDid | `did.Did` | DID of the bond editor (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist +- public alpha value falls outside of 0.0001 <= alpha <= 0.9999 +- public alpha value violates any of the below rules + - `newPublicAlpha != publicAlpha` +- resultant system alpha value violates any of the below rules + - `newSystemAlpha != systemAlpha` + - `I > C * systemAlpha` + - `R / C > newSystemAlpha - systemAlpha` +- editor is not the bond controller +- bond DID or editor DID is not a valid DID + +```go +type MsgSetNextAlpha struct { + BondDid string + Alpha sdk.Dec + EditorDid string +} +``` + +This message stores the next alpha value in the current `Batch` object, where it gets processed and set at the end of the batch. + +## MsgUpdateBondState + +The controller of a bond can change a bond's state to SETTLE or FAILED using `MsgUpdateBondState`. + +| **Field** | **Type** | **Description** | +| :-------- | :---------- | :------------------------------------------------------------------------------ | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| State | `BondState` | Bond state to be set (e.g. `SETTLE`) | +| EditorDid | `did.Did` | DID of the bond editor (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist +- state is not SETTLE or FAILED +- state is not a valid transition from the current bond state +- editor is not the bond controller +- bond DID or editor DID is not a valid DID + +```go +type MsgUpdateBondState struct { + BondDid string + State string + EditorDid string +} +``` + +This message updates the bond status to SETTLE or FAILED and moves the outcome payment reserve to the bond reserve, so that this is available for bond token holders to withdraw a share from, proportional to the amount of bond tokens they hold. + +## MsgBuy + +Any address that holds tokens that a bond uses as its reserve can buy tokens from that bond in exchange for reserve tokens. Rather than performing the buy itself, the `MsgBuy` handler registers a buy order in the current orders batch and cancels any other orders that become unfulfillable. Any order in that batch gets fulfilled at the end of the batch's lifespan. The `MsgBuy` handler also locks away the `MaxPrices` value (`< Balance`) indicated by the address so that these are not used elsewhere whilst the batch is being processed. + +A buy order is cancelled if the max prices are exceeded at any point during the lifespan of the batch. Otherwise, the buy order is fulfilled. The number of tokens requested are minted on the fly and any remaining tokens from the locked `MaxPrices`, minus the transaction fee specified by the bond, are returned to the user. The actual price in reserve tokens charged to the address is determined from the bond function, but is also influenced by any other buys and sells in the same orders batch, as a means to prevent front-running. + +In the case of `augmented_function` bonds, if the bond state is `HATCH`, a fixed price-per-token `p0` is used. This value (`p0`) is one of the function parameters required for this function type. + +| **Field** | **Type** | **Description** | +| :-------- | :---------- | :------------------------------------------------------------------------------ | +| BuyerDid | `did.Did` | DID of the buyer (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Amount | `sdk.Coin` | The amount of bond tokens to be bought | +| MaxPrices | `sdk.Coins` | The max price to pay in reserve tokens | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not HATCH or OPEN +- amount is not an amount of an existing bond +- max prices is greater than the balance of the buyer +- max prices are not amounts of the bond's reserve tokens +- denominations in max prices are not the bond's reserve tokens +- buyer does not afford to buy the tokens at the current price +- amount causes the bond's batch-adjusted current supply to exceed the max supply +- amount violates an order quantity limit defined by the bond +- bond DID or buyer DID is not a valid DID + +The batch-adjusted current supply in the case of buys is the current supply of the bond plus any uncancelled buy amounts in the current batch. + +```go +type MsgBuy struct { + BuyerDid string + Amount sdk.Coin + MaxPrices sdk.Coins + BondDid string +} +``` + +This message adds the buy order to the current batch. + +### MsgBuy for Swapper Function Bonds + +In general, but especially in the case of swapper function bonds, buying tokens from a bond can be seen as adding liquidity to that bond's token. To add liquidity to a swapper function, the current exchange rate is used to determine how much of each reserve token makes up the price. Otherwise, the price is an equal number of each of the reserve tokens according to the function type. + +Moreover, in the case of the swapper function, the first `MsgBuy` performed is special and plays a very important role in specifying the price of the bond token. Since we have no price reference for the first buy in a swapper function, the `MaxPrices` specified are used as the actual price, with no fees charged. + +This effectively means that if the user requested `n` bond tokens with max prices `aR1` and `bR2` (for reserve tokens `R1` and `R2`), the next buyers will have to pay `(a/n)R1` and `(b/n)R2` tokens per bond token requested. Specifying high `a` and `b` prices for a small `n` (say `n=1`) means that the next buyers will have to pay at most `aR1` and `bR2` per bond token. **Thus, it is important that the first buy is well-calculated and performed carefully.** + +## MsgSell + +Any address that holds previously bought bond tokens can, at any point, sell the tokens back to the bond in exchange for reserve tokens. Similar to the `MsgBuy`, the `MsgSell` handler just registers a sell order in the current orders batch which then gets fulfilled at the end of the batch's lifespan. + +Once the sell order is fulfilled, the number of tokens to be sold are burned on the fly and the address gets reserve tokens in return, minus the transaction and exit fees specified by the bond. The actual number of reserve tokens given to the address in return is determined from the bond function, but is also influenced by any other buys and sells in the same orders batch, as a means to prevent front-running. A sell order cannot be cancelled. + +In general, but especially in the case of swapper function bonds, buying tokens from a bond can be seen as adding liquidity for that bond. To add liquidity to a swapper function, the current exchange rate is used to determine how much of each reserve token makes up the price. Otherwise, the price is an equal number of each of the reserve tokens according to the function type. + +| **Field** | **Type** | **Description** | +| :-------- | :--------- | :------------------------------------------------------------------------------ | +| SellerDid | `did.Did` | DID of the seller (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Amount | `sdk.Coin` | The amount of bond tokens to be sold | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not OPEN +- amount is not an amount of an existing bond +- amount is greater than the balance of the seller +- amount is greater than the bond's current supply +- amount causes the bond's batch-adjusted current supply to become negative +- amount violates an order quantity limit defined by the bond +- bond function type is `augmented_function` and bond state is `HATCH` +- bond DID or seller DID is not a valid DID + +The batch-adjusted current supply in the case of sells is the current supply of the bond minus any uncancelled sell amounts in the current batch. + +```go +type MsgSell struct { + SellerDid string + Amount sdk.Coin + BondDid string +} +``` + +This message adds the sell order to the current batch. + +## MsgSwap + +Any address that holds tokens (_t1_) that a swapper function bond uses as one of its two reserves (_t1_ and _t2_) can swap the tokens in exchange for reserve tokens of the other type (_t2_). Similar to the `MsgBuy` and `MsgSell`, the `MsgSwap` handler just registers a swap order in the current orders batch which then gets fulfilled at the end of the batch's lifespan. + +| **Field** | **Type** | **Description** | +| :--------- | :--------- | :------------------------------------------------------------------------------ | +| SwapperDid | `did.Did` | DID of the swapper (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| From | `sdk.Coin` | The amount of reserve tokens to be swapped | +| ToToken | `string` | The token denomination that will be given in return | + +This message is expected to fail if: + +- bond does not exist, is not swapper function, or bond state is not OPEN +- from amount is greater than the balance of the swapper +- from and to tokens are the same token +- from and to tokens are not the swapper function's reserve tokens +- from amount violates an order quantity limit defined by the bond +- bond DID or swapper DID is not a valid DID + +```go +type MsgSwap struct { + SwapperDid string + BondDid string + From sdk.Coin + ToToken string +} +``` + +This message adds the swap order to the current batch. + +## MsgMakeOutcomePayment + +If a bond was created with an outcome payment field, then any token holder can make an outcome payment to the bond. If the token holder has enough tokens to pay the outcome payment, the tokens are sent to the bond's reserve and the bond's state gets set to SETTLE. The only action possible by bond token holders after the outcome payment has been made is a share withdrawal (using [MsgWithdrawShare](#MsgWithdrawShare)). + +| **Field** | **Type** | **Description** | +| :-------- | :-------- | :------------------------------------------------------------------------------ | +| SenderDid | `did.Did` | DID of the sender (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Amount | `sdk.Int` | Amount of payment sender is making (e.g. `100000`) | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not OPEN +- bond outcome payment is zero or negative +- bond outcome payment is greater than the balance of the sender +- bond DID or sender DID is not a valid DID + +```go +type MsgMakeOutcomePayment struct { + SenderDid string + Amount sdk.Int + BondDid string +} +``` + +## MsgWithdrawShare + +If a bond's outcome payment was paid, any bond token holder can use this message to get their share of the reserve. The amount owed to the bond token holder is calculated by considering the percentage of bond tokens owned as a fraction of the _remaining_ bond token supply. Examples: + +- If the bond token holder owns 100% of all bond tokens and the reserve has 1000 reserve tokens, then the bond token holder gets all 1000 reserve tokens. +- If three bond token holders each own 1/3 of all bond tokens and the reserve has 1000 reserve tokens, then: + - The first token holder to withdraw gets `1000/3 = 333 tokens` (notice the rounding down from 333.33) + - The second token holder to withdraw gets `667/2 = 333 tokens` (notice the current supply is now 2) + - The third token holder to withdraw gets `334/1 = 334 tokens` (because of rounding, the last holder got an extra token) + +| **Field** | **Type** | **Description** | +| :----------- | :-------- | :------------------------------------------------------------------------------ | +| RecipientDid | `did.Did` | DID of the recipient (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not SETTLE +- recipient does not own any bond tokens +- bond DID or recipient DID is not a valid DID + +```go +type MsgWithdrawShare struct { + RecipientDid string + BondDid string +} +``` + +## MsgWithdrawReserve + +If the bond allows it, i.e. if the `AllowReserveWithdrawals` flag is set to True, then the bond's controller has the ability to withdraw reserve out of the bond's reserve, for usage outside of the bond. This will not affect the `CurrentReserve` reported by the bond but will update the `AvailableReserve` value. + +| **Field** | **Type** | **Description** | +| :------------ | :---------- | :------------------------------------------------------------------------------ | +| WithdrawerDid | `did.Did` | DID of the withdrawer (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | +| Amount | `sdk.Coins` | The amount of reserve tokens to be withdrawn | +| BondDid | `did.Did` | DID of the bond we are interacting with (e.g. `did:ixo:U7GK8p8rVhJMKhBVRCJJ8c`) | + +This message is expected to fail if: + +- bond does not exist or bond state is not OPEN +- withdrawer is not the bond's controller +- bond DID or withdrawer DID is not a valid DID +- amount is not a valid amount +- bond does not have sufficient available reserve + +```go +type MsgWithdrawReserve struct { + WithdrawerDid string + Amount sdk.Coin + BondDid string +} +``` diff --git a/developers/ixo-blockchain/bonds/spec/04_end_block.md b/developers/ixo-blockchain/bonds/spec/04_end_block.md new file mode 100644 index 0000000..50a9da4 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/04_end_block.md @@ -0,0 +1,58 @@ +# End-Block + +At the end of each block, any batch of orders that has reached the end of its lifespan, measured in number of blocks, is cleared. For the rest of the batches, their blocks remaining value is decremented by 1. Orders are performed in the following order: + +1. Buys +2. Sells +3. Swaps + +Since the buy and sell prices are pre-calculated from when the buy and sell orders were added to the batch, there is no additional cancellations of buys or sells that will take place at this stage. However, swaps are processed on a first come first served basis and a swap is cancelled if it violates the sanity rates. + +In the case of `augmented_function` bonds, if the new bond supply after performing all orders is greater or equal to the initial supply (`supply >= S0`), the bond's state gets updated from `HATCH` to `OPEN` and sells are enabled if `AllowSells == true`. + +## Buys + +Using the buy price stored in the batch, the following steps are followed for each buy order: + +1. Mint and send `n` bond tokens to the buyer +2. Calculate total price`total = r + f` in reserve tokens + 1. `r` is the price of buying `n` bond tokens + 2. `f` is the transactional fee based on `r` +3. Send `r` to the reserve +4. Send `f` to the fee address +5. Send unused reserve tokens (`maxPrices-total`) back to buyer +6. Increase bond's current supply by `n` + +Note: the `maxPrices` reserve tokens were locked upon submitting the buy order. + +## Sells + +Using the sell price stored in the batch, the following steps are followed for each sell order: + +1. Calculate total returns `total = r - f` in reserve tokens + 1. `r` is the return for selling `n` bond tokens + 2. `f` is the transactional and exit fees based on `r` +2. Send `total` to the seller +3. Send `f` to the fee address +4. Decrease bond's current supply by `n` + +Note: the `n` bond tokens were burned upon submitting the sell order. + +## Swaps + +The following steps are followed for each swap order: + +1. Calculate the transactional fee `f` based on `t1` reserve tokens +2. Calculate the return `t2` for swapping `t1-f` reserve tokens +3. Check whether the swap violates the sanity rate + 1. Calculate the new reserve balances as a result of the swap + 2. Cancel the swap if the new balances violate the sanity rate +4. Send `t2` to the swapper +5. Send `t1-f` to the reserve +6. Send `f` to the fee address + +Note: the `t1` reserve tokens were locked upon submitting the swap order. If a swap order is cancelled, the `t1` tokens are immediately returned back to the swapper. + +## Set Last Batch + +Once all orders have been processed, the last batch is set as the current batch and the current batch is cleared in preparation for a new list of orders. diff --git a/developers/ixo-blockchain/bonds/spec/05_events.md b/developers/ixo-blockchain/bonds/spec/05_events.md new file mode 100644 index 0000000..a289478 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/05_events.md @@ -0,0 +1,285 @@ +# Events + +The bonds module emits the following typed events: + +### BondCreatedEvent + +Emitted after a successfull `MsgCreateBond` + +| **Field** | **Type** | **Description** | +| :-------- | :------- | :-------------- | +| Bond | `*Bond` | | + +```go +type BondCreatedEvent struct { + Bond *Bond +} +``` + +### BondUpdatedEvent + +Emitted after a successfull `MsgEditBond`, `MsgUpdateBondState` + +| **Field** | **Type** | **Description** | +| :-------- | :------- | :-------------- | +| Bond | `*Bond` | | + +```go +type BondUpdatedEvent struct { + Bond *Bond +} +``` + +### BondSetNextAlphaEvent + +Emitted after a successfull `MsgSetNextAlpha`. Note this doesn't mean the alpha has been updated, it has only been added to the batch for next batch update. + +| **Field** | **Type** | **Description** | +| :-------- | :------- | :-------------- | +| BondDid | `string` | | +| NextAlpha | `string` | | +| Signer | `string` | | + +```go +type BondSetNextAlphaEvent struct { + BondDid string + NextAlpha string + Signer string +} +``` + +### BondBuyOrderEvent + +Emitted after a successfull `MsgBuy`. Note this doesn't mean the buy has been executed, it has only been added to the batch. + +| **Field** | **Type** | **Description** | +| :-------- | :---------- | :-------------- | +| BondDid | `string` | | +| Order | `*BuyOrder` | | + +```go +type BondBuyOrderEvent struct { + Order *BuyOrder + BondDid string +} +``` + +### BondSellOrderEvent + +Emitted after a successfull `MsgSell`. Note this doesn't mean the sell has been executed, it has only been added to the batch. + +| **Field** | **Type** | **Description** | +| :-------- | :----------- | :-------------- | +| BondDid | `string` | | +| Order | `*SellOrder` | | + +```go +type BondSellOrderEvent struct { + Order *SellOrder + BondDid string +} +``` + +### BondSwapOrderEvent + +Emitted after a successfull `MsgSwap`. Note this doesn't mean the swap has been executed, it has only been added to the batch. + +| **Field** | **Type** | **Description** | +| :-------- | :----------- | :-------------- | +| BondDid | `string` | | +| Order | `*SwapOrder` | | + +```go +type BondSwapOrderEvent struct { + Order *SwapOrder + BondDid string +} +``` + +### BondMakeOutcomePaymentEvent + +Emitted after a successfull `MsgMakeOutcomePayment` + +| **Field** | **Type** | **Description** | +| :------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| OutcomePayment | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| SenderDid | `string` | | +| SenderAddress | `string` | | + +```go +type BondMakeOutcomePaymentEvent struct { + BondDid string + OutcomePayment github_com_cosmos_cosmos_sdk_types.Coins + SenderDid string + SenderAddress string +} +``` + +### BondWithdrawShareEvent + +Emitted after a successfull `MsgWithdrawShare` + +| **Field** | **Type** | **Description** | +| :--------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| WithdrawPayment | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| RecipientDid | `string` | | +| RecipientAddress | `string` | | + +```go +type BondWithdrawShareEvent struct { + BondDid string + WithdrawPayment github_com_cosmos_cosmos_sdk_types.Coins + RecipientDid string + RecipientAddress string +} +``` + +### BondWithdrawReserveEvent + +Emitted after a successfull `MsgWithdrawReserve` + +| **Field** | **Type** | **Description** | +| :----------------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| WithdrawAmount | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| WithdrawerDid | `string` | | +| WithdrawerAddress | `string` | | +| ReserveWithdrawalAddress | `string` | | + +```go +type BondWithdrawReserveEvent struct { + BondDid string + WithdrawAmount github_com_cosmos_cosmos_sdk_types.Coins + WithdrawerDid string + WithdrawerAddress string + ReserveWithdrawalAddress string +} +``` + +### BondEditAlphaSuccessEvent + +Emitted after a successfull update of the Alpha state which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :---------- | :------- | :-------------- | +| BondDid | `string` | | +| Token | `string` | | +| PublicAlpha | `string` | | +| SystemAlpha | `string` | | + +```go +type BondEditAlphaSuccessEvent struct { + BondDid string + Token string + PublicAlpha string + SystemAlpha string +} +``` + +### BondEditAlphaFailedEvent + +Emitted if update of the Alpha state failed which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :----------- | :------- | :-------------- | +| BondDid | `string` | | +| Token | `string` | | +| CancelReason | `string` | | + +```go +type BondEditAlphaFailedEvent struct { + BondDid string + Token string + CancelReason string +} +``` + +### BondBuyOrderFulfilledEvent + +Emitted after a successfull `BuyOrder` has been executed which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :-------------------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| Order | `*BuyOrder` | | +| ChargedPrices | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| ChargedFees | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| ReturnedToAddress | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| NewBondTokenBalance | `github_com_cosmos_cosmos_sdk_types.Int` | | +| ChargedPricesOfWhichReserve | `*github_com_cosmos_cosmos_sdk_types.Int` | | +| ChargedPricesOfWhichFunding | `github_com_cosmos_cosmos_sdk_types.Coins` | | + +```go +type BondBuyOrderFulfilledEvent struct { + BondDid string + Order *BuyOrder + ChargedPrices github_com_cosmos_cosmos_sdk_types.Coins + ChargedFees github_com_cosmos_cosmos_sdk_types.Coins + ReturnedToAddress github_com_cosmos_cosmos_sdk_types.Coins + NewBondTokenBalance github_com_cosmos_cosmos_sdk_types.Int + ChargedPricesOfWhichReserve *github_com_cosmos_cosmos_sdk_types.Int + ChargedPricesOfWhichFunding github_com_cosmos_cosmos_sdk_types.Coins +} +``` + +### BondSellOrderFulfilledEvent + +Emitted after a successfull `SellOrder` has been executed which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :------------------ | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| Order | `*SellOrder` | | +| ChargedFees | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| ReturnedToAddress | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| NewBondTokenBalance | `github_com_cosmos_cosmos_sdk_types.Int` | | + +```go +type BondSellOrderFulfilledEvent struct { + BondDid string + Order *SellOrder + ChargedFees github_com_cosmos_cosmos_sdk_types.Coins + ReturnedToAddress github_com_cosmos_cosmos_sdk_types.Coins + NewBondTokenBalance github_com_cosmos_cosmos_sdk_types.Int +} +``` + +### BondSwapOrderFulfilledEvent + +Emitted after a successfull `SwapOrder` has been executed which is done in `EndBlock` + +| **Field** | **Type** | **Description** | +| :---------------- | :----------------------------------------- | :-------------- | +| BondDid | `string` | | +| Order | `*SwapOrder` | | +| ChargedFee | `types.Coin` | | +| ReturnedToAddress | `github_com_cosmos_cosmos_sdk_types.Coins` | | +| TokensSwapped | `types.Coin` | | + +```go +type BondSwapOrderFulfilledEvent struct { + BondDid string + Order *SwapOrder + ChargedFee types.Coin + ReturnedToAddress github_com_cosmos_cosmos_sdk_types.Coins + TokensSwapped types.Coin +} +``` + +### BondBuyOrderCancelledEvent + +Emitted when a `BuyOrder` has been cancelled as it is not eligible to be executed anymore. + +| **Field** | **Type** | **Description** | +| :-------- | :---------- | :-------------- | +| BondDid | `string` | | +| Order | `*BuyOrder` | | + +```go +type BondBuyOrderCancelledEvent struct { + BondDid string + Order *BuyOrder +} +``` diff --git a/developers/ixo-blockchain/bonds/spec/06_params.md b/developers/ixo-blockchain/bonds/spec/06_params.md new file mode 100644 index 0000000..80d95df --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/06_params.md @@ -0,0 +1,7 @@ +# Parameters + +The bonds module contains the following parameter: + +| **Key** | **Type** | **Description** | +| :----------------- | :--------- | :----------------------------------------------------------- | +| ReservedBondTokens | `[]string` | A list of tokens that is reserved and can't be used by users | diff --git a/developers/ixo-blockchain/bonds/spec/07_future_improvements.md b/developers/ixo-blockchain/bonds/spec/07_future_improvements.md new file mode 100644 index 0000000..7220154 --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/07_future_improvements.md @@ -0,0 +1,10 @@ +# Future Improvements + +- **Order processing and front-running prevention**: Improved order fulfillment procedure with less cancellations and more options for the user when buying/selling/swapping, such as minimum returns, specifying amount to be spent rather than bought, etc. The intention is primarily to improve user experience. The main challenge lies in doing this without compromising on front-running prevention and order batching in general. More options for the user means more ways in which an order can be cancelled, and any cancelled order will affect the fulfillability of other orders, which may in turn get cancelled, and so on. One option would be to have an exchange-like behaviour and postpone orders that cannot be fulfilled to the next batch, which then runs into complications of dealing with stale orders. On a similar note, work can be done towards implementing front-running prevention for swap orders [1]. +- **Bond creation and function types**: More function types and an improved bond creation process, with more options for the creator and smarter parameter restrictions. An interesting function type that can be implemented is a rule-based function [2]. +- **IBC**: The availability of Inter-Blockchain Communication will unlock the full potential of the bonds module. On top of being able to create any bond, one will be able to use tokens from other chains as reserve tokens for the created bonds and transfer the bond tokens across chains. Further work would need to be done to ensure compatibility with IBC. + +## References + +1. https://ethresear.ch/t/improving-front-running-resistance-of-x-y-k-market-makers/1281 +2. https://medium.com/thoughtchains/on-single-bonding-curves-for-continuous-token-models-a167f5ffef89 \ No newline at end of file diff --git a/developers/ixo-blockchain/bonds/spec/08_functions_library.ipynb b/developers/ixo-blockchain/bonds/spec/08_functions_library.ipynb new file mode 100644 index 0000000..1705f8a --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/08_functions_library.ipynb @@ -0,0 +1,119 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# Functions Library\n", + "The Bonds Module is deployed with a built-in set of libraries for commonly-used algorithmic pricing and reserve functions. It also includes algorithmic application logic and features, such as *Augmented Bonding*. Additional functions can be added to the Library through SDK updates. This requires a formal process of governance to approve updates, to assure the integrity of these functions.\n", + "\n", + "## Function Types\n", + "The following function types will be included in the standard Bonds SDK Module:\n", + "* Power (exponential)\n", + "* Logistic (sigmoidal)\n", + "* Constant Product (swapper)\n", + "* [Augmented Bonding Curves](https://medium.com/giveth/deep-dive-augmented-bonding-curves-3f1f7c1fa751) with [Alpha Bonds](https://github.com/BlockScience/Risk-Adjusted-Bonding-Curves) functionality (augmented)\n", + "\n", + "Algorithmic Applications include:\n", + "* Risk-adjusted bonding curves\n", + "* Innovation Bonds (offers bond shareholders contingent rights to future IP rights and/or revenues)\n", + "* Impact Bonds (offers bond shareholders contingent rights to success-based outcomes payments and/or rewards)\n", + "\n", + "### Exponential Function (power)\n", + "\n", + "Function (used as pricing function):\n", + "\n", + "$$y = mx^n + c$$\n", + "\n", + "Integral (used as reserve function):\n", + "\n", + "$$r = \\frac{m}{n+1}x^{n+1} + cx$$\n", + "\n", + "### Logistic Function (sigmoid)\n", + "\n", + "Function (used as pricing function):\n", + "\n", + "$$y = a \\cdot \\left( \\frac{x-b}{\\sqrt{c + (x-b)^2}} + 1 \\right)$$\n", + "\n", + "Integral (used as reserve function):\n", + "\n", + "$$y = a \\cdot \\left( \\sqrt{(x-b)^2 + c} + x \\right) - a \\cdot \\left( \\sqrt{b^2 + c} \\right) $$\n", + "\n", + "### Augmented Bonding Curves (augmented)\n", + "\n", + "#### Standard Augmented Bonding Curve Functions\n", + "\n", + "Initial reserve:\n", + "\n", + "$$R_0 = (1-\\theta)d_0$$\n", + "\n", + "Initial supply:\n", + "\n", + "$$S_0 = \\frac{d_0}{p_0}$$\n", + "\n", + "Constant power function invariant:\n", + "\n", + "$$V(R,S) = \\frac{S^\\kappa}{R}$$\n", + "\n", + "Invariant V function:\n", + "\n", + "$$V_0 = V(R_0,S_0) = \\frac{{S_0}^\\kappa}{R_0} = \\left( \\frac{1}{p_0 (1-\\theta)} \\right)^\\kappa {R_0}^{\\kappa - 1}$$\n", + "\n", + "Pricing function:\n", + "\n", + "$$P(R) = \\frac{\\kappa R^{(\\kappa - 1)/\\kappa}}{{V_0}^{1/\\kappa}}$$\n", + "\n", + "Reserve function:\n", + "\n", + "$$R(S) = \\frac{S^\\kappa}{V_0}$$\n", + "\n", + "Ref: https://medium.com/giveth/deep-dive-augmented-bonding-curves-3f1f7c1fa751\n", + "\n", + "#### Alpha Bonds Extension Functions\n", + "\n", + "Alpha:\n", + "\n", + "$$\\alpha = \\frac{S_1 R}{S_1 R - S_0 R + S_0 C}$$\n", + "\n", + "Invariant I:\n", + "\n", + "$$I = \\alpha C + R$$\n", + "\n", + "Kappa:\n", + "\n", + "$$\\kappa = \\frac{I}{I - \\alpha C}$$\n", + "\n", + "Ref: https://github.com/BlockScience/Risk-Adjusted-Bonding-Curves\n", + "\n", + "### Constant Product Function (swapper)\n", + "\n", + "Reserve function:\n", + "\n", + "$$x \\cdot y = k$$" + ], + "metadata": { + "collapsed": false + } + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} \ No newline at end of file diff --git a/developers/ixo-blockchain/bonds/spec/README.md b/developers/ixo-blockchain/bonds/spec/README.md new file mode 100644 index 0000000..efc30de --- /dev/null +++ b/developers/ixo-blockchain/bonds/spec/README.md @@ -0,0 +1,89 @@ +# Bonds module specification + +This document specifies the bonds module, a custom Ixo Cosmos SDK module. + +The bonds module provides universal token bonding curve functions to mint, burn or swap any token in a Cosmos blockchain. Once the Inter-Blockchain Communication (IBC) protocol is available, this should enable cross-network exchanges of tokens at algorithmically-determined prices. + +The bonds module can deliver applications such as: + +- Automated market-makers (like [Uniswap](https://uniswap.io)) +- Decentralised exchanges (like [Bancor](https://bancor.network)) +- Curation markets (like [Relevant](https://github.com/relevant-community/contracts/tree/bondingCurves/contracts)) +- Development Impact Bonds (like ixo alpha-Bonds) +- Continuous organisations (like [Moloch DAO](https://molochdao.com/)) + +Any Cosmos application chain that implements the Bonds module is able to perform functions such as: + +- Issue a new token with custom parameters. +- Pool liquidity for reserves. +- Provide continuous funding. +- Automatically mint and burn tokens at deterministic prices. +- Swap tokens atomically within the same network. +- Exchange tokens across networks, with the IBC protocol. +- (Batch token transactions to prevent front-running) +- Launch a decentralised autonomous initial coin offerings ([DAICO](https://ethresear.ch/t/explanation-of-daicos/465)) +- ..._other **DeFi**ant_ innovations. + +## Contents + +1. **[Concepts](01_concepts.md)** + + - [Concepts](01_concepts.md#concepts) + - [Token Bonding Curves](01_concepts.md#token-bonding-curves) + - [Token Bonds Module](01_concepts.md#token-bonds-module) + - [Batching](01_concepts.md#batching) + +2. **[State](02_state.md)** + + - [State](02_state.md#state) + - [Bonds](02_state.md#bonds) + - [Batches](02_state.md#batches) + - [Querying Batches](02_state.md#querying-batches) + +3. **[Messages](03_messages.md)** + + - [Messages](03_messages.md#messages) + - [MsgCreateBond](03_messages.md#msgcreatebond) + - [MsgEditBond](03_messages.md#msgeditbond) + - [MsgSetNextAlpha](03_messages.md#msgsetnextalpha) + - [MsgUpdateBondState](03_messages.md#msgupdatebondstate) + - [MsgBuy](03_messages.md#msgbuy) + - [MsgBuy for Swapper Function Bonds](03_messages.md#msgbuy-for-swapper-function-bonds) + - [MsgSell](03_messages.md#msgsell) + - [MsgSwap](03_messages.md#msgswap) + - [MsgMakeOutcomePayment](03_messages.md#msgmakeoutcomepayment) + - [MsgWithdrawShare](03_messages.md#msgwithdrawshare) + - [MsgWithdrawReserve](03_messages.md#msgwithdrawreserve) + +4. **[End-Block](04_end_block.md)** + + - [End-Block](04_end_block.md#end-block) + - [Buys](04_end_block.md#buys) + - [Sells](04_end_block.md#sells) + - [Swaps](04_end_block.md#swaps) + - [Set Last Batch](04_end_block.md#set-last-batch) + +5. **[Events](05_events.md)** + + - [Events](05_events.md#events) + - [BondCreatedEvent](05_events.md#bondcreatedevent) + - [BondUpdatedEvent](05_events.md#bondupdatedevent) + - [BondSetNextAlphaEvent](05_events.md#bondsetnextalphaevent) + - [BondBuyOrderEvent](05_events.md#bondbuyorderevent) + - [BondSellOrderEvent](05_events.md#bondsellorderevent) + - [BondSwapOrderEvent](05_events.md#bondswaporderevent) + - [BondMakeOutcomePaymentEvent](05_events.md#bondmakeoutcomepaymentevent) + - [BondWithdrawShareEvent](05_events.md#bondwithdrawshareevent) + - [BondWithdrawReserveEvent](05_events.md#bondwithdrawreserveevent) + - [BondEditAlphaSuccessEvent](05_events.md#bondeditalphasuccessevent) + - [BondEditAlphaFailedEvent](05_events.md#bondeditalphafailedevent) + - [BondBuyOrderFulfilledEvent](05_events.md#bondbuyorderfulfilledevent) + - [BondSellOrderFulfilledEvent](05_events.md#bondsellorderfulfilledevent) + - [BondSwapOrderFulfilledEvent](05_events.md#bondswaporderfulfilledevent) + - [BondBuyOrderCancelledEvent](05_events.md#bondbuyordercancelledevent) + +6. **[Parameters](06_params.md)** + +7. **[Future Improvements](07_future_improvements.md)** + +8. **[Functions Library](08_functions_library.ipynb)** diff --git a/developers/ixo-blockchain/claims/spec/01_concepts.md b/developers/ixo-blockchain/claims/spec/01_concepts.md new file mode 100644 index 0000000..7584d17 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/01_concepts.md @@ -0,0 +1,97 @@ +# Concepts + +## Verifiable Credentials (VCs) + +### What are Verifiable Credentials? + +Verifiable Credentials (VCs) are standardized digital statements made by the issuer about a subject. They serve as a cryptographically secure, tamper-evident, and privacy-preserving mechanism for presenting proofs about an individual's or entity's attributes or qualifications. This digital assertion allows an individual or entity to prove various facets of their identity or other claims without having to reveal excessive information. + +In the physical world, a driving license, a university degree, or a membership card can serve as credentials. In the digital realm, VCs replicate this concept, offering a digital equivalent that's cryptographically secure and verifiable. + +### Standards and Specifications + +VCs operate based on a standard laid out by the [World Wide Web Consortium (W3C)](https://www.w3.org/). This standard ensures that VCs are consistent, interoperable, and recognized across various digital platforms and applications. + +- [W3C Verifiable Credentials Data Model](https://www.w3.org/TR/vc-data-model/): This specification provides a detailed guide on how VCs are structured, issued, and verified. It establishes a foundation for building trust on the web, ensuring that digital attestations are as reliable as their physical counterparts. + +### Components of a Verifiable Credential + +1. **Issuer:** The authoritative entity that creates and signs the VC. The credibility of a VC often depends on the reputation of its issuer. +2. **Subject:** The individual or entity that the VC pertains to. It could be a person, organization, device, or any other entity that the claim is about. +3. **Claim:** The assertion or statement made about the subject. For example, a university (issuer) can assert that a student (subject) has achieved a particular degree (claim). +4. **Proof:** Cryptographic evidence that verifies the authenticity of the VC, ensuring that it hasn't been tampered with since its creation. This proof is typically a digital signature provided by the issuer. + +![VC-graph](./assets/vc_graph.svg) + +### Advantages of Verifiable Credentials + +- **Decentralization and Privacy:** VCs can be used without being tethered to a centralized authority after issuance. This decentralization means users can control and share their credentials without an intermediary, enhancing privacy. +- **Selective Disclosure:** Holders of VCs can choose which parts of their credentials they wish to share, offering finer control over personal data. +- **Interoperability:** Owing to the W3C standard, VCs can be seamlessly used across various platforms and services. +- **Security:** Cryptographic proofs ensure that VCs are tamper-evident and verifiable, instilling trust in their authenticity. + +### Use Cases + +VCs can be employed in a plethora of scenarios: + +- **Identity Verification:** Proving one's identity on online platforms without oversharing personal details. +- **Academic Credentials:** Sharing academic achievements and qualifications digitally. +- **Healthcare:** Sharing medical records or vaccination status in a secure and verifiable manner. +- **Financial Services:** Proving creditworthiness or transaction history. + +### In Summary + +Verifiable Credentials are a monumental step towards a more trustable and private digital ecosystem. By allowing individuals and entities to share and prove information about themselves without jeopardizing their privacy or data security, VCs are poised to redefine how we trust and verify data online. + +![VC-life](./assets/vc_life.svg) + +# Claims Module + +The Claims module in the ixo system facilitates the management and verification of claims, aligning with the W3C standards for Verifiable Credentials (VCs). + +## Overview + +VCs are digital attestations made by an issuer regarding a subject. These claims are both cryptographically secure and tamper-evident, ensuring their integrity. In the ixo system, the data model for a VC is defined by a **Claim Schema**. Each claim schema is established as part of a Protocol ([Entity](/x/entity/spec/02_state.md#entity) with type `protocol`) that includes a method for evaluating the claim and the criteria for its approval. + +Protocols in the ixo system are identifiable by an Entity Identifier in the DID format: `did:ixo:entity:{string}`. Each claim and its evaluation is distinguished by its unique `id`, which for example is the `cid` hash value, which also serves as its cryptographic proof. + +An ixo entity can have one or more claim protocols represented as a `linkedClaim`. Agents can be authorized by the entity to submit or evaluate claims, utilizing the entity's capability delegation verification method and issuing `authz` grants to these agents. + +## Key Features + +1. **Authorize Agents for Claim Submission:** + - Agents are individuals or entities with valid DIDs. + - The "service" agent, acting for an entity, can be a Group. This group can be: + - Any member from a predefined group member list. + - The Group by governance (referring to the group account). +2. **Authorize Agents for Claim Evaluation:** + + - The โ€œevaluationโ€ agent acting on behalf of an entity can be a Group: + - Either any Member of a Group. + - Or the Group by governance. + - There's flexibility in evaluation: + - Multiple agents can be tasked to evaluate claims. + - A single claim can be assessed by multiple agents for additional insights (like getting a second opinion). + - Agents can be authorized for either a collection of claims or specifically identified ones. + - Agents can have constraints, like evaluating claims only within certain dates or evaluating a capped number of claims. + +3. **Registry Maintenance of Claims with Verification Proofs:** + + - Claims are organized under a [Collection](02_state.md#collection), where each collection contains claims submitted under a specific protocol for a distinct entity. Collections are identified by an `id` which is the [CollectionSequence](05_params.md). + - Every claim has a unique `id`, which is typically the CID, doubling as its cryptographic proof. + - Claims have a default `status` of `1`, indicating they've been `submitted`. Enum is [EvaluationStatus](02_state.md#evaluationstatus) + - After evaluation, a claim's status can change to: + - `approved` (=2) + - `rejected` (=3) + - `disputed` (=4) + +4. **Payment Authorization:** + + - Payments can be authorized to agents or evaluators' `account` upon various claim activities like submission, evaluation, approval, or when disputes arise. + +5. **Recording Counter-Claims Evidence:** + - In case of disputes, evidence for counter-claims can be recorded, facilitating transparency and conflict resolution. + +## Conclusion + +The Claims module is instrumental in the ixo system, providing a robust infrastructure for the creation, management, evaluation, and verification of claims. With the integration of the W3C standard for VCs, it ensures that all claims are both trustworthy and verifiable. diff --git a/developers/ixo-blockchain/claims/spec/02_state.md b/developers/ixo-blockchain/claims/spec/02_state.md new file mode 100644 index 0000000..7220752 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/02_state.md @@ -0,0 +1,406 @@ +# State + +## Collections + +A Collections is stored in the state and is accessed by the identity of the collection that is fetched and incremented onchain using the `Param`: `CollectionSequence`. + +- Collections: `0x01 | collectionId -> ProtocolBuffer(Collection)` + +## Claims + +A Claim is stored in the state and is accessed by the identity of the ClaimId(user provided). + +- Claims: `0x02 | claimId -> ProtocolBuffer(Claim)` + +## Disputes + +A Dispute is stored in the state and is accessed by the SubjectId of the dispute(user provided). + +- Disputes: `0x03 | disputeSubjectId(DID) -> ProtocolBuffer(Dispute)` + +# Types + +### Collection + +```go +type Collection struct { + Id string + Entity string + Admin string + Protocol string + StartDate *time.Time + EndDate *time.Time + Quota uint64 + Count uint64 + Evaluated uint64 + Approved uint64 + Rejected uint64 + Disputed uint64 + State CollectionState + Payments *Payments +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the collections identifier, it is incremented on chain for the collection of claims +- `entity` - a string containing the DID of the entity for which the claims are being created +- `admin` - a string containing the account address that will authorize or revoke agents and payments (the granter). It is the `Entity`'s [EntityAccount](/x/entity/spec/02_state.md#entityaccount) named `admin` +- `protocol` - a string containing the DID of the claim protocol +- `startDate` - a timestamp of the start date for the collection, after which claims may be submitted +- `endDate` - a timestamp of the end date for the collection, after which no more claims may be submitted (no endDate is allowed) +- `quota` - a integer containing the maximum number of claims that may be submitted, 0 is unlimited +- `count` - a integer containing the number of claims already submitted (internally calculated) +- `evaluated` - a integer containing the number of claims that have been evaluated (internally calculated) +- `approved` - a integer containing the number of claims that have been evaluated and approved (internally calculated) +- `rejected` - a integer containing the number of claims that have been evaluated and rejected (internally calculated) +- `disputed` - a integer containing the number of claims that have disputed status (internally calculated) +- `state` - a [CollectionState](#collectionstate) +- `payments` - a [Payments](#payments) + +### Payments + +A Payments stores [Payment](#payment) for the claim submission, evaluation, approval, or rejection payments made towards the collection + +```go +type Payments struct { + Submission *Payment + Evaluation *Payment + Approval *Payment + Rejection *Payment +} +``` + +The field's descriptions is as follows: + +- `submission` - a [Payment](#payment) +- `evaluation` - a [Payment](#payment) +- `approval` - a [Payment](#payment) +- `rejection` - a [Payment](#payment) + +### Payment + +A Payment stores information about the amount paid for claim submission, evaluation, approval, or rejection + +```go +type Payment struct { + Account string + Amount github_com_cosmos_cosmos_sdk_types.Coins + Contract_1155Payment *Contract1155Payment + TimeoutNs time.Duration +} +``` + +The field's descriptions is as follows: + +- `account` - a string containing the account address from which the payment will be made (ideally a [EntityAccount](/x/entity/spec/02_state.md#entityaccount)) +- `amount` - a [Coins](https://github.com/cosmos/cosmos-sdk/blob/main/types/coin.go#L180) object which denotes the coins and amount to be paid on payment +- `contract_1155Payment` - a [Contract1155Payment](#contract1155payment) +- `timeoutNs` - a duration containing the timeout after claim/evaluation to create authZ for payment, if 0 then immidiate direct payment is made + +### Contract1155Payment + +A Contract1155Payment stores information about the payment to make if it is a cw1155 tokens payment. + +```go +type Contract1155Payment struct { + Address string + TokenId string + Amount uint32 +} +``` + +The field's descriptions is as follows: + +- `address` - a string containing the smart contract address where the tokens can be transfered on (the cw1155 smart contract) +- `amount` - a integer indicating how many tokens must transfered for the payment +- `tokenId` - a string containing the `id` of the token on the cw1155 smart contract to transfer + +### Claim + +A Claim stores information about a claim that was made towards a [Collection](#collection) + +```go +type Claim struct { + CollectionId string + AgentDid string + AgentAddress string + SubmissionDate *time.Time + ClaimId string + Evaluation *Evaluation + PaymentsStatus *ClaimPayments +} +``` + +The field's descriptions is as follows: + +- `collectionId` - a string containing the Collection `id` this claim belongs +- `agentAddress` - a string containing the account address that submitted the claim +- `agentDid` - a string containing the Did of the agent that submitted the claim +- `submissionDate` - the timestamp of the date and time that the claim was submitted on-chain +- `claimId` - a string containing the unique identifier of the claim (eg. cid hash of file is good identifier) +- `evaluation` - a [Evaluation](#evaluation) +- `paymentsStatus` - a [ClaimPayments](#claimpayments) + +### ClaimPayments + +A ClaimPayments stores an enum for the status for the claim submission, evaluation, approval, or rejection payments + +```go +type ClaimPayments struct { + Submission PaymentStatus + Evaluation PaymentStatus + Approval PaymentStatus + Rejection PaymentStatus +} +``` + +The field's descriptions is as follows: + +- `submission` - a [PaymentStatus](#paymentstatus) +- `evaluation` - a [PaymentStatus](#paymentstatus) +- `approval` - a [PaymentStatus](#paymentstatus) +- `rejection` - a [PaymentStatus](#paymentstatus) + +### Evaluation + +A Evaluation stores information concerning the evaluation of a [Claim](#claim) made + +```go +type Evaluation struct { + ClaimId string + CollectionId string + Oracle string + AgentDid string + AgentAddress string + Status EvaluationStatus + Reason uint32 + VerificationProof string + EvaluationDate *time.Time + Amount github_com_cosmos_cosmos_sdk_types.Coins +} +``` + +The field's descriptions is as follows: + +- `claimId` - a string containing the `id` of the claim the evaluation is for +- `collectionId` - a string containing the Collection `id` the claim this evaluation is for belongs to +- `oracle` - a string containing the DID of the Oracle entity that evaluates the claim +- `agentAddress` - a string containing the account address that submitted the evaluation +- `agentDid` - a string containing the Did of the agent that submitted the evaluation +- `status` - a [EvaluationStatus](#evaluationstatus) +- `reason` - a integer for why the evaluation result was given (codes defined by evaluator) +- `verificationProof` - a string containing the proof to verify the linked resource (eg. the cid of the evaluation Verfiable Credential) +- `evaluationDate` - the timestamp of the date and time that the claim evaluation was submitted on-chain +- `amount` - a [Coins](https://github.com/cosmos/cosmos-sdk/blob/main/types/coin.go#L180) object which denotes the coins and amount to be paid on `Approval` payment if it is a custom amount and not the preset `Approval` from the [Collection](#collection) + +### Dispute + +A Dispute stores information concerning the dispute made towards a [Claim](#claim) + +```go +type Dispute struct { + SubjectId string + Type int32 + Data *DisputeData +} +``` + +The field's descriptions is as follows: + +- `subjectId` - a string containing the `id` of the claim the dispute is for. A unique field +- `type` - a integer interpreted by the client +- `data` - a [DisputeData](#disputedata) + +### DisputeData + +A DisputeData stores information concerning the data for a dispute made towards a [Claim](#claim) + +```go +type DisputeData struct { + Uri string + Type string + Proof string + Encrypted bool +} +``` + +The field's descriptions is as follows: + +- `uri` - a string representing the endpoint of the data linked resource +- `type ` - a string representing the [MIME](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) type of the data linked resource +- `proof ` - a string representing the proof to verify the data linked resource +- `encrypted ` - a boolean value for whether this data linked resource is encrypted or not + +## Enums + +### CollectionState + +Defines the `state` of a [Collection](#collection) denoting whether claims is allowed to be submitted or not. Already submitted claims is still allowed to be evaluated regardless of the `state` + +```go +var CollectionState_name = map[int32]string{ + 0: "OPEN", + 1: "PAUSED", + 2: "CLOSED", +} +``` + +### EvaluationStatus + +Defines the `status` of a [Evaluation](#evaluation) indicating the status and result of the evaluation. + +```go +var EvaluationStatus_name = map[int32]string{ + 0: "PENDING", + 1: "APPROVED", + 2: "REJECTED", + 3: "DISPUTED", +} +``` + +### PaymentType + +Defines the type of [Payment](#payment) used to keep track for payment withdrawals to update `ClaimPayments` accordingly + +```go +var PaymentType_name = map[int32]string{ + 0: "SUBMISSION", + 1: "APPROVAL", + 2: "EVALUATION", + 3: "REJECTION", +} +``` + +### PaymentStatus + +Defines the status of the payment types for `ClaimPayments` + +```go +var PaymentStatus_name = map[int32]string{ + 0: "NO_PAYMENT", + 1: "PROMISED", + 2: "AUTHORIZED", + 3: "GAURANTEED", + 4: "PAID", + 5: "FAILED", + 6: "DISPUTED", +} +``` + +## Authz Types + +### WithdrawPaymentAuthorization + +A WithdrawPaymentAuthorization is an authz authorization that can be granted to allow the grantee to make a withdrawal payout to receive his payment for claims submitted, evaluated or that was approved + +```go +type WithdrawPaymentAuthorization struct { + Admin string + Constraints []*WithdrawPaymentConstraints +} +``` + +The field's descriptions is as follows: + +- `admin` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field +- `constraints` - a list of [WithdrawPaymentConstraints](#withdrawpaymentconstraints) + +### WithdrawPaymentConstraints + +A WithdrawPaymentConstraints stores information about authorization given to make a withdrawal payment through a [WithdrawPaymentAuthorization](#withdrawpaymentauthorization) + +```go +type WithdrawPaymentConstraints struct { + ClaimId string + Inputs []github_com_cosmos_cosmos_sdk_x_bank_types.Input + Outputs []github_com_cosmos_cosmos_sdk_x_bank_types.Output + PaymentType PaymentType + Contract_1155Payment *Contract1155Payment + ToAddress string + FromAddress string + ReleaseDate *time.Time +} +``` + +The field's descriptions is as follows: + +- `claimId` - a string containing the `id` of the claim the withdrawal is for +- `inputs` - a list of cosmos defined `Input` to pass to the the multisend tx to run to withdraw payment +- `outputs` - a list of cosmos defined `Output` to pass to the the multisend tx to run to withdraw payment +- `paymentType` - a [PaymentType](02_state.md#paymenttype) +- `contract_1155Payment` - a [Contract1155Payment](02_state.md#contract1155payment) +- `toAddress` - a string containing the account address to make the payment to +- `fromAddress` - a string containing the account address to make the payment from +- `releaseDate` - a timestamp of the date that grantee can execute authorization to make the withdrawal payment, calculated from created date plus the timeout on [Collection](02_state.md#collection) `Payments` +- `adminAddress` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field + +### SubmitClaimAuthorization + +A SubmitClaimAuthorization is an authz authorization that can be granted to allow the grantee to submit claims for a specified collection + +```go +type SubmitClaimAuthorization struct { + Admin string + Constraints []*SubmitClaimConstraints +} +``` + +The field's descriptions is as follows: + +- `admin` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field +- `constraints` - a list of [SubmitClaimConstraints](#submitclaimconstraints) + +### SubmitClaimConstraints + +A SubmitClaimConstraints stores information about authorization given to submit claims through a [SubmitClaimAuthorization](#submitclaimauthorization) + +```go +type SubmitClaimConstraints struct { + CollectionId string + AgentQuota uint64 +} +``` + +The field's descriptions is as follows: + +- `collectionId` - a string containing the Collection `id` the constraints is for +- `agentQuota` - a integer containing the quota for amount of time the grantee can execute the given authorization(authz) + +### EvaluateClaimAuthorization + +A EvaluateClaimAuthorization is an authz authorization that can be granted to allow the grantee to evaluate claims for a specified collection + +```go +type EvaluateClaimAuthorization struct { + Admin string + Constraints []*EvaluateClaimConstraints +} +``` + +The field's descriptions is as follows: + +- `admin` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field +- `constraints` - a list of [EvaluateClaimConstraints](#evaluateclaimconstraints) + +### EvaluateClaimConstraints + +A EvaluateClaimConstraints stores information about authorization given to evaluate claims through a [EvaluateClaimAuthorization](#evaluateclaimauthorization) + +```go +type EvaluateClaimConstraints struct { + CollectionId string + ClaimIds []string + AgentQuota uint64 + BeforeDate *time.Time + MaxCustomAmount github_com_cosmos_cosmos_sdk_types.Coins +} +``` + +The field's descriptions is as follows: + +- `claimIds` - a list of strings containing all the id's of the claimsthe grantee is allowed to evaluate, can be an empty list to allow any claim +- `collectionId` - a string containing the Collection `id` the constraints is for +- `agentQuota` - a integer containing the quota for amount of time the grantee can execute the given authorization(authz) +- `beforeDate` - a timestamp of the date after which the grantee can't execute this authz anymore, a cut off date +- `MaxCustomAmount` - a [Coins](https://github.com/cosmos/cosmos-sdk/blob/main/types/coin.go#L180) object which denotes the coins and amount that indicates the maximum the evaluator is allowed to change the `APPROVED` payout to, since claims can be made for specific amount an evaluator is allowed to change the `APPROVED` payout amount. diff --git a/developers/ixo-blockchain/claims/spec/03_messages.md b/developers/ixo-blockchain/claims/spec/03_messages.md new file mode 100644 index 0000000..63a212f --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/03_messages.md @@ -0,0 +1,136 @@ +# Messages + +In this section we describe the processing of the claims messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state.md) section. + +## MsgCreateCollection + +A `MsgCreateCollection` creates and stores a new Collection which defines protocols, quotas and payments for claim submissions and evaluations + +```go +type MsgCreateCollection struct { + Entity string + Signer string + Protocol string + StartDate *time.Time + EndDate *time.Time + Quota uint64 + State CollectionState + Payments *Payments +} +``` + +The field's descriptions is as follows: + +- `entity` - a string containing the DID of the entity for which the claims are being created +- `signer` - a string containing the account address of the private key signing the transaction +- `protocol` - a string containing the DID of the claim protocol +- `startDate` - a timestamp of the start date for the collection, after which claims may be submitted +- `endDate` - a timestamp of the end date for the collection, after which no more claims may be submitted (no endDate is allowed) +- `quota` - a integer containing the maximum number of claims that may be submitted, 0 is unlimited +- `state` - a [CollectionState](02_state.md#collectionstate) +- `payments` - a [Payments](02_state.md#payments) + +## MsgSubmitClaim + +A `MsgSubmitClaim` creates and stores a new Claim made towards a `Collection`. On Submission of claim `SUBMISSION` payments will be made if there is any defined in the [Collection](02_state.md#collection) `Payments`. + +```go +type MsgSubmitClaim struct { + CollectionId string + ClaimId string + AgentDid DIDFragment + AgentAddress string + AdminAddress string +} +``` + +The field's descriptions is as follows: + +- `collectionId` - a string containing the Collection `id` this claim belongs +- `agentAddress` - a string containing the account address that is submitting the claim +- `agentDid` - a string containing the Did of the agent that is submitting the claim +- `adminAddress` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field + +## MsgEvaluateClaim + +A `MsgEvaluateClaim` updates the `Evaluation` for a claim. On evaluation payments will be made for both the evaluation of the claim (towards the agent or oracle) as well as if the claim was `APPROVED` then the claim submitter will also get a payment, which will the preset amount defined on th [Collection](02_state.md#collection) `Payments` field or the evaluator can also define a custom `Amount` that can be paid out on approval. + +```go +type MsgEvaluateClaim struct { + ClaimId string + CollectionId string + Oracle string + AgentDid DIDFragment + AgentAddress string + AdminAddress string + Status EvaluationStatus + Reason uint32 + VerificationProof string + Amount github_com_cosmos_cosmos_sdk_types.Coins +} +``` + +The field's descriptions is as follows: + +- `claimId` - a string containing the `id` of the claim the evaluation is for +- `collectionId` - a string containing the Collection `id` the claim this evaluation is for belongs to +- `oracle` - a string containing the DID of the Oracle entity that is evaluating the claim +- `agentAddress` - a string containing the account address that is submitting the evaluation +- `agentDid` - a string containing the Did of the agent that is submitting the evaluation +- `adminAddress` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field +- `status` - a [EvaluationStatus](#evaluationstatus) +- `reason` - a integer for why the evaluation result was given (codes defined by evaluator) +- `verificationProof` - a string containing the proof to verify the linked resource (eg. the cid of the evaluation Verfiable Credential) +- `amount` - a [Coins](https://github.com/cosmos/cosmos-sdk/blob/main/types/coin.go#L180) object which denotes the coins and amount to be paid on `Approval` payment if it is a custom amount and not the preset `Approval` from the [Collection](#collection) + +## MsgDisputeClaim + +A `MsgDisputeClaim` creates and stores a new Dispute. + +```go +type MsgDisputeClaim struct { + SubjectId string + AgentDid DIDFragment + AgentAddress string + DisputeType int32 + Data *DisputeData +} +``` + +The field's descriptions is as follows: + +- `subjectId` - a string containing the `id` of the claim the dispute is for. A unique field +- `disputeType` - a integer interpreted by the client +- `data` - a [DisputeData](02_state.md#disputedata) +- `agentAddress` - a string containing the account address that is submitting the dispute +- `agentDid` - a string containing the Did of the agent that is submitting the dispute + +## MsgWithdrawPayment + +A `MsgWithdrawPayment` creates and stores a new Withdrawal Payment which contains details about a payment that can be made if the `TimeoutNs` in a [Payment](02_state.md#payment) is non 0, which means the payout won't happen on submission/evaluation but an authz gets granted with the receiver as grantee that allows the execution of this message after the `ReleaseDate`. This will allow the receiver to execute the payout through a [MsgExec](https://docs.cosmos.network/main/build/modules/authz#msgexec) to execute the authz. + +```go +type MsgWithdrawPayment struct { + ClaimId string + Inputs []github_com_cosmos_cosmos_sdk_x_bank_types.Input + Outputs []github_com_cosmos_cosmos_sdk_x_bank_types.Output + PaymentType PaymentType + Contract_1155Payment *Contract1155Payment + ToAddress string + FromAddress string + ReleaseDate *time.Time + AdminAddress string +} +``` + +The field's descriptions is as follows: + +- `claimId` - a string containing the `id` of the claim the withdrawal is for +- `inputs` - a list of cosmos defined `Input` to pass to the the multisend tx to run to withdraw payment +- `outputs` - a list of cosmos defined `Output` to pass to the the multisend tx to run to withdraw payment +- `paymentType` - a [PaymentType](02_state.md#paymenttype) +- `contract_1155Payment` - a [Contract1155Payment](02_state.md#contract1155payment) +- `toAddress` - a string containing the account address to make the payment to +- `fromAddress` - a string containing the account address to make the payment from +- `releaseDate` - a timestamp of the date that grantee can execute authorization to make the withdrawal payment, calculated from created date plus the timeout on [Collection](02_state.md#collection) `Payments` +- `adminAddress` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field diff --git a/developers/ixo-blockchain/claims/spec/04_events.md b/developers/ixo-blockchain/claims/spec/04_events.md new file mode 100644 index 0000000..3d29b43 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/04_events.md @@ -0,0 +1,115 @@ +# Events + +The bonds module emits the following typed events: + +### CollectionCreatedEvent + +Emitted after a successfull `MsgCreateCollection` + +```go +type CollectionCreatedEvent struct { + Collection *Collection +} +``` + +The field's descriptions is as follows: + +- `collection` - the full [Collection](02_state.md#collection) + +### CollectionUpdatedEvent + +Emitted after a successfull `MsgSubmitClaim`, `EvaluateClaim` since collection holds a count of claims + +```go +type CollectionUpdatedEvent struct { + Collection *Collection +} +``` + +The field's descriptions is as follows: + +- `collection` - the full [Collection](02_state.md#collection) + +### ClaimSubmittedEvent + +Emitted after a successfull `MsgSubmitClaim` + +```go +type ClaimSubmittedEvent struct { + Claim *Claim +} +``` + +The field's descriptions is as follows: + +- `claim` - the full [Claim](02_state.md#claim) + +### ClaimUpdatedEvent + +Emitted after a successfull `MsgEvaluateClaim` or when the state for the `ClaimPayments` changes. + +```go +type ClaimUpdatedEvent struct { + Claim *Claim +} +``` + +The field's descriptions is as follows: + +- `claim` - the full [Claim](02_state.md#claim) + +### ClaimEvaluatedEvent + +Emitted after a successfull `MsgEvaluateClaim` + +```go +type ClaimEvaluatedEvent struct { + Evaluation *Evaluation +} +``` + +The field's descriptions is as follows: + +- `evaluation` - the full [Evaluation](02_state.md#evaluation) + +### ClaimDisputedEvent + +Emitted after a successfull `MsgDisputeClaim` + +```go +type ClaimDisputedEvent struct { + Dispute *Dispute +} +``` + +The field's descriptions is as follows: + +- `dispute` - the full [Dispute](02_state.md#dispute) + +### PaymentWithdrawnEvent + +Emitted after a successfull `MsgWithdrawPayment` or when a payment gets withdrawn through another trigger like payments on evaluation with 0 timeout. + +```go +type PaymentWithdrawnEvent struct { + Withdraw *WithdrawPaymentConstraints +} +``` + +The field's descriptions is as follows: + +- `withdraw` - the full [WithdrawPaymentConstraints](02_state.md#withdrawpaymentconstraints) + +### PaymentWithdrawCreatedEvent + +Emitted after a successfull payment withdrawal authz gets created on chain if the `Payments` `timeout_ns` is not 0, and a [WithdrawPaymentAuthorization](02_state.md#withdrawpaymentauthorization) is created with the receiver as the grantee + +```go +type PaymentWithdrawCreatedEvent struct { + Withdraw *WithdrawPaymentConstraints +} +``` + +The field's descriptions is as follows: + +- `withdraw` - the full [WithdrawPaymentConstraints](02_state.md#withdrawpaymentconstraints) diff --git a/developers/ixo-blockchain/claims/spec/05_params.md b/developers/ixo-blockchain/claims/spec/05_params.md new file mode 100644 index 0000000..35ed303 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/05_params.md @@ -0,0 +1,10 @@ +# Parameters + +The claims module contains the following parameter: + +| **Key** | **Type** | **Description** | +| :------------------- | :--------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------- | +| CollectionSequence | `uint64` | An onchain sequence to generate collection ids | +| IxoAccount | `string` | The Ixo network account address that will receive it's `NetworkFeePercentage` for every claim evaluation | +| NetworkFeePercentage | `github_com_cosmos_cosmos_sdk_types.Dec` | The percentage that the `IxoAccount` param account will receive for every claim evaluation | +| NodeFeePercentage | `github_com_cosmos_cosmos_sdk_types.Dec` | The percentage that the node relayer for the given marketplace that the collection was created in will receive for every claim evaluation | diff --git a/developers/ixo-blockchain/claims/spec/06_future_improvements.md b/developers/ixo-blockchain/claims/spec/06_future_improvements.md new file mode 100644 index 0000000..44ef026 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/06_future_improvements.md @@ -0,0 +1,13 @@ +# Future Improvements + +The ixo system continually evolves to offer more sophisticated, efficient, and streamlined solutions. Some proposed enhancements in the pipeline for the Claims module include: + +### Agent Authorization for Group Accounts + +To diminish the administrative overhead, agents could be authorized not just for individual accounts but for group accounts. Consider a scenario involving a Project Entity with a defined group of Service Agents. Any member from this group might have the capability to submit claims. The essential task then is only to oversee and manage the group membership, which happens outside the purview of the Claims module. + +### Auto-Authorization for Claim Submission + +In scenarios like public campaigns where agent identification isn't crucial, agents might be permitted to submit claims without preliminary authorization. This open approach, however, carries risks like potential spamming or DDoS attacks. To mitigate such threats, a proposal suggests limiting each agent DID to submit only a defined number of claims. + +These planned improvements emphasize the commitment to making the Claims module more adaptive and in tune with diverse project requirements while preserving system security and efficiency. diff --git a/developers/ixo-blockchain/claims/spec/README.md b/developers/ixo-blockchain/claims/spec/README.md new file mode 100644 index 0000000..3b8fe44 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/README.md @@ -0,0 +1,67 @@ +# Claims module specification + +This document specifies the claims module, a custom Ixo Cosmos SDK module. + +The Claims Module provides an advanced structure for handling Verifiable Claims (VCs), cryptographic attestations regarding a subject. By aligning with the W3C standard and incorporating unique ixo system identifiers, this module offers a comprehensive solution for creating, evaluating, and managing claims. It enables entities to define protocols, authorize agents, and maintain a verifiable registry, ensuring authenticity and transparency in all claim-related processes. + +## Contents + +1. **[Concepts](01_concepts.md)** + + - [Concepts](01_concepts.md#concepts) + - [Verifiable Credentials (VCs)](01_concepts.md#verifiable-credentials-vcs) + - [Claims Module](01_concepts.md#claims-module) + +2. **[State](02_state.md)** + + - [State](02_state.md#state) + - [Collections](02_state.md#collections) + - [Claims](02_state.md#claims) + - [Disputes](02_state.md#disputes) + - [Types](02_state.md#types) + - [Collection](02_state.md#collection) + - [Payments](02_state.md#payments) + - [Payment](02_state.md#payment) + - [Contract1155Payment](02_state.md#contract1155payment) + - [Claim](02_state.md#claim) + - [ClaimPayments](02_state.md#claimpayments) + - [Evaluation](02_state.md#evaluation) + - [Dispute](02_state.md#dispute) + - [DisputeData](02_state.md#disputedata) + - [Enums](02_state.md#enums) + - [CollectionState](02_state.md#collectionstate) + - [EvaluationStatus](02_state.md#evaluationstatus) + - [PaymentType](02_state.md#paymenttype) + - [PaymentStatus](02_state.md#paymentstatus) + - [Authz Types](02_state.md#authz-types) + - [WithdrawPaymentAuthorization](02_state.md#withdrawpaymentauthorization) + - [WithdrawPaymentConstraints](02_state.md#withdrawpaymentconstraints) + - [SubmitClaimAuthorization](02_state.md#submitclaimauthorization) + - [SubmitClaimConstraints](02_state.md#submitclaimconstraints) + - [EvaluateClaimAuthorization](02_state.md#evaluateclaimauthorization) + - [EvaluateClaimConstraints](02_state.md#evaluateclaimconstraints) + +3. **[Messages](03_messages.md)** + + - [Messages](03_messages.md#messages) + - [MsgCreateCollection](03_messages.md#msgcreatecollection) + - [MsgSubmitClaim](03_messages.md#msgsubmitclaim) + - [MsgEvaluateClaim](03_messages.md#msgevaluateclaim) + - [MsgDisputeClaim](03_messages.md#msgdisputeclaim) + - [MsgWithdrawPayment](03_messages.md#msgwithdrawpayment) + +4. **[Events](04_events.md)** + + - [Events](04_events.md#events) + - [CollectionCreatedEvent](04_events.md#collectioncreatedevent) + - [CollectionUpdatedEvent](04_events.md#collectionupdatedevent) + - [ClaimSubmittedEvent](04_events.md#claimsubmittedevent) + - [ClaimUpdatedEvent](04_events.md#claimupdatedevent) + - [ClaimEvaluatedEvent](04_events.md#claimevaluatedevent) + - [ClaimDisputedEvent](04_events.md#claimdisputedevent) + - [PaymentWithdrawnEvent](04_events.md#paymentwithdrawnevent) + - [PaymentWithdrawCreatedEvent](04_events.md#paymentwithdrawcreatedevent) + +5. **[Parameters](05_params.md)** + +6. **[Future Improvements](06_future_improvements.md)** diff --git a/developers/ixo-blockchain/claims/spec/assets/vc_graph.svg b/developers/ixo-blockchain/claims/spec/assets/vc_graph.svg new file mode 100644 index 0000000..5d88c55 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/assets/vc_graph.svg @@ -0,0 +1,111 @@ + + + + + + + + + + +A credential and its proof + +A credential presented schematically. There are two major components: + the credential itself, and its proof. + +The credential includes metadata, including a date of issue and an issuer, and a claim, +in this case that "Pat" is an alumnus of "Example University" +(which is also the issuer of the credential). + +The proof of the credential is a signature, with a nonce, date, the algorithm used, +and a public key belonging to the creator, Example University. + + Credential Graph + Credential Graph + + + + Credential 123 + + + issuanceDate + + 2010-01-01T19:37.24Z + + + type + + AlumniCredential + + + credentialSubject + + + + Claim + + Pat + + AlumniOf + + Example University + + + + issuer + + Example + University + + + + proof + + Credential Proof Graph + Credential Proof Graph + + + + Signature 456 + + + type + + RsaSignature2018 + + + created + + 2017-06-18T21:19:10Z + + + nonce + + 34dj239dsj328 + + + signatureValue + + BavE110...3JT24= + + + creator + + Example University + Public Key 7 + + + + + diff --git a/developers/ixo-blockchain/claims/spec/assets/vc_life.svg b/developers/ixo-blockchain/claims/spec/assets/vc_life.svg new file mode 100644 index 0000000..9b17605 --- /dev/null +++ b/developers/ixo-blockchain/claims/spec/assets/vc_life.svg @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + +Life of a single Verifiable Credential + + +Issuer + + +Issue +exactly once + + +Revoke +up to once + + + + +Holders + + +Delete +up to once per Holder + + + +Transfer +Repeateable + + +Present +repeatable + + + + +Verifiers + + +Verify +repeatable + + +Check Status +Does not preserve privacy +repeatable + + +Check Status +MAY preserve privacy +repeatable + + +Registry + + diff --git a/developers/ixo-blockchain/entity/spec/01_concepts.md b/developers/ixo-blockchain/entity/spec/01_concepts.md new file mode 100644 index 0000000..15a65d7 --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/01_concepts.md @@ -0,0 +1,43 @@ +# Entity Module + +The `Entity` module is a pivotal component of our blockchain system, facilitating the unified management of both non-fungible tokens (NFTs) and their associated Interchain Identifiers (IIDs). By seamlessly intertwining NFTs with IIDs, the `Entity` module establishes a new paradigm for decentralized asset management, bolstered by the credibility and dependability of DID Documents. + +## Overview + +When an `Entity` is created on the blockchain, a trifecta of operations is set into motion: + +1. An IID Document is birthed through the `iid` module, cementing the foundational identity and associated metadata of the entity. +2. An NFT is minted using the CW721 smart contract, capturing the unique and immutable essence of the entity in tokenized form. +3. A dedicated `Entity` data structure is etched into the KV store. This is not merely a reflection of the IID Document; it captures supplementary metadata exclusive to the `Entity`, enhancing its depth and versatility. + +The `id` for all 3 of the different data stored above is deterministically determined on-chain on Entity creation. + +## Key Components + +### Entity Data Structure + +Stored within the KV store, the `Entity` data structure houses metadata that isn't contained within the IID Document. It's instrumental in furnishing a holistic view of the `Entity`, encapsulating both inherent and appended attributes. This data provides richer context, driving interoperability and comprehensive understanding across platforms and applications. + +#### Entity Accounts + +An Entity Account is a Cosmos Module Account that can only be created and controlled by an Entity Owner. An Entity may have any number of Entity Accounts. Each Entity Account has a unique name. For instance โ€œSavingsโ€. The account address is derived from this name and the DID of the Entity. The Entity Owner may authorise any other account to perform transactions for an Entity Account, using Authz. When ownership of an Entity is transferred, the new owner gains control of the Entity Accounts. All residual balances in an Entity Account get transferred together with the Entity NFT when ownership is transferred. + +On Entity creation a default Entity Account gets created with the name `admin`. + +### NFT Creation + +The minting of an NFT via the CW721 smart contract reaffirms the distinctiveness of each `Entity`. This tokenized representation not only encapsulates the essence of the entity but also offers a myriad of possibilities in terms of trade, ownership verification, and utilization in decentralized applications. + +### IID Document Creation + +The automatic generation of an IID Document ensures that every `Entity` is backed by a standardized, robust, and decentralized identity mechanism. This identity is enriched with crucial metadata and, being compliant with W3C's DID specifications, offers global compatibility and recognition. + +### Advantages + +- **Unified Management:** The `Entity` module simplifies the intricacies of managing decentralized assets by unifying IID creation, NFT minting, and metadata storage. +- **Enhanced Metadata:** By preserving additional metadata in the `Entity` data structure, a comprehensive and nuanced understanding of each entity is achieved. +- **Interoperability:** Rooted in globally recognized standards, `Entities` foster seamless interactions across various decentralized platforms and applications. + +- **Decentralization and Security:** The tandem of IID Documents and NFTs ensures a decentralized, tamper-proof, and transparent representation of entities. + +For a deeper dive into the foundational principles of IIDs, consult the [`iid` module documentation](/x/iid/spec/README.md). For a comprehensive understanding of NFTs and the CW721 standard, refer to the [official CW721 documentation](https://github.com/CosmWasm/cw-nfts/blob/main/packages/cw721/README.md) which follows the [eip721 standard](https://eips.ethereum.org/EIPS/eip-721). diff --git a/developers/ixo-blockchain/entity/spec/02_state.md b/developers/ixo-blockchain/entity/spec/02_state.md new file mode 100644 index 0000000..a5a6f5e --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/02_state.md @@ -0,0 +1,73 @@ +# State + +## Entities + +A Entity is stored in the state and is accessed by the identity of the entity(DID). + +- Entities: `0x01 | entityId(DID) -> ProtocolBuffer(Entity)` + +# Types + +### Entity + +```go +type Entity struct { + Id string + Type string + StartDate *time.Time + EndDate *time.Time + Status int32 + RelayerNode string + Credentials []string + EntityVerified bool + Accounts []*EntityAccount + Metadata *EntityMetadata +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity +- `type` - a string representing the type of entity it is eg, `dao`, `protocol`, `asset/device` +- `startDate` - a timestamp of the start date for the entity, as defined by the implementer and interpreted by client applications +- `endDate` - a timestamp of the end date for the entity, as defined by the implementer and interpreted by client applications +- `status` - a integer representing the status of the entity, as defined by the implementer and interpreted by client applications +- `relayerNode` - a string representing the did id of the operator through which the entity was created +- `credentials` - a list of string representing the credentials of the enitity to be verified +- `entityVerified` - a boolean used as check whether the credentials of entity is verified +- `accounts` - a list of [EntityAccount](#entityaccount) +- `metadata` - a [EntityMetadata](#entitymetadata) + +### EntityAccount + +A EntityAccount is a module account generated deterministically using the entity id and name for the account and can only be controlled through the entity owner. + +```go +type EntityAccount struct { + Name string + Address string +} +``` + +The field's descriptions is as follows: + +- `name` - a string representing the name for the [Entity Account](01_concepts.md#entity-accounts) +- `address` - a string containing the address of the [Entity Account](01_concepts.md#entity-accounts) + +### EntityMetadata + +A EntityMetadata stores information relative to a Entity such as versionId, created, and updated. + +```go +type EntityMetadata struct { + VersionId string + Created *time.Time + Updated *time.Time +} +``` + +The field's descriptions is as follows: + +- `versionId` - the version of the last update operation for the entity +- `updated` - the timestamp of the last update operation for the entity +- `created` - the timestamp of the create operation diff --git a/developers/ixo-blockchain/entity/spec/03_messages.md b/developers/ixo-blockchain/entity/spec/03_messages.md new file mode 100644 index 0000000..6187ba4 --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/03_messages.md @@ -0,0 +1,157 @@ +# Messages + +In this section we describe the processing of the entity messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state.md) section. + +## MsgCreateEntity + +A `MsgCreateEntity` creates and stores a new entity doc and a corresponding iid doc with the same id(DID) along with its nft at +appropriate indexes, which is a nft on a cw721 smart contract. It includes the [MsgCreateIidDocument](/x/iid/spec/03_messages.md#msgcreateiiddocument) fields also since creating an entity also creates a corresponding [IidDocument](/x/iid/spec/02_state.md#iiddocument) with the same id as the id generated for the entity. + +```go +type MsgCreateEntity struct { + EntityType string + EntityStatus int32 + Controller []string + Context []*types.Context + Verification []*types.Verification + Service []*types.Service + AccordedRight []*types.AccordedRight + LinkedResource []*types.LinkedResource + LinkedEntity []*types.LinkedEntity + StartDate *time.Time + EndDate *time.Time + RelayerNode string + Credentials []string + OwnerDid DIDFragment + OwnerAddress string + Data encoding_json.RawMessage + AlsoKnownAs string + LinkedClaim []*types.LinkedClaim +} +``` + +The field's descriptions is as follows: + +- `entityType` - a string representing the type of entity it is eg, `dao`, `protocol`, `asset/device` +- `entityStatus` - a integer representing the status of the entity, as defined by the implementer and interpreted by client applications +- `context` - a list of [Context](/x/iid/spec/02_state.md#context) +- `controllers` - a list of strings of controllers(DIDs). A DID controller is an entity that is authorized to make changes to a DID document. https://www.w3.org/TR/did-core/#did-controller +- `verifications` - a list of [Verifications](/x/iid/spec/02_state.md#verification) +- `service` - a list of [Service](/x/iid/spec/02_state.md#service) +- `linkedResource` - a list of [LinkedResource](/x/iid/spec/02_state.md#linked-resource) +- `accordedRight` - a list of [AccordedRight](/x/iid/spec/02_state.md#accorded-right) +- `linkedEntity` - a list of [LinkedEntity](/x/iid/spec/02_state.md#linked-entity) +- `linkedClaim` - a list of [LinkedClaim](/x/iid/spec/02_state.md#linked-claim) +- `alsoKnownAs` - a string. The assertion that two or more DIDs (or other types of URI) refer to the same DID subject can be made using the alsoKnownAs property. https://www.w3.org/TR/did-core/#also-known-as +- `ownerAddress` - a string containing the cosmos address of the private key signing the transaction +- `ownerDid` - a string containing the [MsgCreateIidDocument](/x/iid/spec/03_messages.md#msgcreateiiddocument) id (aka DID) of the owner which will be added to the [IidDocument](/x/iid/spec/02_state.md#iiddocument) list of controllers +- `startDate` - a timestamp of the start date for the entity, as defined by the implementer and interpreted by client applications +- `endDate` - a timestamp of the end date for the entity, as defined by the implementer and interpreted by client applications +- `relayerNode` - a string representing the did id of the operator through which the entity was created +- `credentials` - a list of string representing the credentials of the enitity to be verified + +## MsgUpdateEntity + +The `MsgUpdateEntity` is used to update an entity. It updates the entity with all the fields, so if a field is empty it will be updated with default go type, aka never null. For this reason also provide the previous values for fields you do not wish to update. + +```go +type MsgUpdateEntity struct { + Id string + EntityStatus int32 + StartDate *time.Time + EndDate *time.Time + Credentials []string + ControllerDid DIDFragment + ControllerAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `entityStatus` - a integer representing the status of the entity, as defined by the implementer and interpreted by client applications +- `startDate` - a timestamp of the start date for the entity, as defined by the implementer and interpreted by client applications +- `endDate` - a timestamp of the end date for the entity, as defined by the implementer and interpreted by client applications +- `credentials` - a list of string representing the credentials of the enitity to be verified +- `ControllerAddress` - a string containing the cosmos address of the private key signing the transaction +- `ControllerDid` - a string containing the signers IidDocument Id. Must be in the IidDocument's controllers list to allow update and the `ControllerAddress` must be authorized to sign on behalf of the `ControllerDid` + +## MsgUpdateEntityVerified + +The `MsgUpdateEntityVerified` is used to update the `EntityVerified` field of an entity. Only the relayerNode for the entity can update it. + +```go +type MsgUpdateEntityVerified struct { + Id string + EntityVerified bool + RelayerNodeDid DIDFragment + RelayerNodeAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `entityVerified` - a boolean indicating whether the entity is verified or not, can be based on credentials +- `relayerNodeAddress` - a string containing the cosmos address of the private key signing the transaction +- `relayerNodeDid` - a string containing the signers IidDocument Id. Must be in the `RelayerNode` of the entity and the `RelayerNodeAddress` must be authorized to sign on behalf of the `RelayerNodeDid` + +## MsgTransferEntity + +The `MsgTransferEntity` is used to transfer an entity to a new user. It will change the controllers on the [IidDocument](/x/iid/spec/02_state.md#iiddocument) to the `recipientDid` as well as remove all the [Verification Method](/x/iid/spec/02_state.md#verification-method) and add the the `recipientDid` as a new one. It also transfers the nft representing the entity on the cw721 smart contract to the recipient. + +```go +type MsgTransferEntity struct { + Id string + OwnerDid DIDFragment + OwnerAddress string + RecipientDid DIDFragment +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `recipientDid` - a string containing the recipient IidDocument Id (Did). +- `ownerAddress` - a string containing the cosmos address of the private key signing the transaction +- `ownerDid` - a string containing the signers IidDocument Id. Must be in the IidDocument's controllers list to allow update and the `ownerAddress` must be authorized to sign on behalf of the `ownerDid` + +## MsgCreateEntityAccount + +The `MsgCreateEntityAccount` is used to create additional [Entity Accounts](02_state.md#entityaccount). + +```go +type MsgCreateEntityAccount struct { + Id string + Name string + OwnerAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `name` - a string containing the name for the new entity account. +- `ownerAddress` - a string containing the cosmos address of the private key signing the transaction + +## MsgGrantEntityAccountAuthz + +The `MsgGrantEntityAccountAuthz` is used to create an [Authz](https://docs.cosmos.network/main/build/modules/authz) grant from entity account (as granter) to the msg `GranteeAddress` for the specific authorization + +```go +type MsgGrantEntityAccountAuthz struct { + Id string + Name string + GranteeAddress string + Grant github_com_cosmos_cosmos_sdk_x_authz.Grant + OwnerAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `name` - a string containing the name for the entity account to use as granter for the authz grant. +- `granteeAddress` - a string containing the grantee address for the authz grant. +- `grant` - a [Grant](https://docs.cosmos.network/main/build/modules/authz#grant) that will be created. +- `ownerAddress` - a string containing the cosmos address of the private key signing the transaction diff --git a/developers/ixo-blockchain/entity/spec/04_events.md b/developers/ixo-blockchain/entity/spec/04_events.md new file mode 100644 index 0000000..3c37cb7 --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/04_events.md @@ -0,0 +1,115 @@ +# Events + +The entity module emits the following typed events: + +### EntityCreatedEvent + +Emitted after a successfull `MsgCreateEntity` + +```go +type EntityCreatedEvent struct { + Entity *Entity + Signer string +} +``` + +The field's descriptions is as follows: + +- `entity` - the full [Entity](02_state.md#entity) +- `signer` - a string containing the did of the signer. + +### EntityUpdatedEvent + +Emitted after a successfull `MsgUpdateEntity`, `MsgUpdateEntityVerified`, `MsgTransferEntity`, `MsgCreateEntityAccount` whereby a field of the entity struct gets updated. + +```go +type EntityUpdatedEvent struct { + Entity *Entity + Signer string +} +``` + +The field's descriptions is as follows: + +- `entity` - the full [Entity](02_state.md#entity) +- `signer` - a string containing the did of the signer or the address of the signer. + +### EntityVerifiedUpdatedEvent + +Emitted after a successfull `MsgUpdateEntityVerified` + +```go +type EntityVerifiedUpdatedEvent struct { + Id string + Signer string + EntityVerified bool +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `signer` - a string containing the did of the signer (will the `relayerNode` did in this case). +- `entityVerified` - a boolean indicating whether the entity is verified or not. + +### EntityTransferredEvent + +Emitted after a successfull `MsgTransferEntity` + +```go +type EntityTransferredEvent struct { + Id string + From string + To string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `to` - a string containing the did of the new owner. +- `from` - a string containing the did of the previous owner. + +### EntityAccountCreatedEvent + +Emitted after a successfull `MsgCreateEntityAccount` + +```go +type EntityAccountCreatedEvent struct { + Id string + Signer string + AccountName string + AccountAddress string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `accountName` - a string containing the name of the new entity account. +- `accountAddress` - a string containing the address of the new entity account. +- `signer` - a string containing the address of the signer. + +### EntityAccountAuthzCreatedEvent + +Emitted after a successfull `MsgGrantEntityAccountAuthz` + +```go +type EntityAccountAuthzCreatedEvent struct { + Id string + Signer string + AccountName string + Granter string + Grantee string + Grant *Grant +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the entity. +- `signer` - a string containing the address of the signer. +- `accountName` - a string containing the name of the entity account the authz was granted. +- `granter` - a string containing the address of the entity account the authz was granted. +- `grantee` - a string containing the address of the grantee towards who the authz was granted. +- `grant` - the [Grant](https://docs.cosmos.network/main/build/modules/authz#grant) that was granted. diff --git a/developers/ixo-blockchain/entity/spec/05_params.md b/developers/ixo-blockchain/entity/spec/05_params.md new file mode 100644 index 0000000..a63a9bf --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/05_params.md @@ -0,0 +1,9 @@ +# Parameters + +The entity module contains the following parameter: + +| **Key** | **Type** | **Description** | +| :----------------- | :------- | :--------------------------------------------------------------------------------------- | +| NftContractAddress | `string` | The cw721 smart contract address that is used to mint every entity as an nft on creation | +| NftContractMinter | `string` | The address of the `NftContractAddress` minter | +| CreateSequence | `uint64` | An onchain sequence that is used to generate the entity id so it can be deterministic | diff --git a/developers/ixo-blockchain/entity/spec/06_future_improvements.md b/developers/ixo-blockchain/entity/spec/06_future_improvements.md new file mode 100644 index 0000000..e482f6d --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/06_future_improvements.md @@ -0,0 +1,5 @@ +# Future Improvements + +As the decentralized landscape evolves, we're committed to enhancing the capabilities and functionalities of the `Entity` module. Future updates may include more granular metadata management, streamlined integration with external platforms, and expanded utility in decentralized finance and applications. + +We welcome community contributions and feedback to make the `Entity` module even more robust and versatile. diff --git a/developers/ixo-blockchain/entity/spec/README.md b/developers/ixo-blockchain/entity/spec/README.md new file mode 100644 index 0000000..30494a9 --- /dev/null +++ b/developers/ixo-blockchain/entity/spec/README.md @@ -0,0 +1,51 @@ +# Entity module specification + +This document specifies the entity module, a custom Ixo Cosmos SDK module. + +The Entity Module introduces a holistic approach to NFT-backed identities, bridging the gap between decentralized identifiers and tangible assets. Upon entity creation, a symbiotic relationship forms between an IID Document, an NFT, and the Entity's metadata. Further enriched with the concept of Entity Accounts, this module ensures a seamless transition of ownership, while offering a robust framework for entities to operate within a decentralized landscape. + +## Contents + +1. **[Concepts](01_concepts.md)** + + - [Entity Module](01_concepts.md#entity-module) + - [Overview](01_concepts.md#overview) + - [Key Components](01_concepts.md#key-components) + - [Entity Data Structure](01_concepts.md#entity-data-structure) + - [Entity Accounts](01_concepts.md#entity-accounts) + - [NFT Creation](01_concepts.md#nft-creation) + - [IID Document Creation](01_concepts.md#iid-document-creation) + - [Advantages](01_concepts.md#advantages) + +2. **[State](02_state.md)** + + - [State](02_state.md#state) + - [Entities](02_state.md#entities) + - [Types](02_state.md#types) + - [Entity](02_state.md#entity) + - [EntityAccount](02_state.md#entityaccount) + - [EntityMetadata](02_state.md#entitymetadata) + +3. **[Messages](03_messages.md)** + + - [Messages](03_messages.md#messages) + - [MsgCreateEntity](03_messages.md#msgcreateentity) + - [MsgUpdateEntity](03_messages.md#msgupdateentity) + - [MsgUpdateEntityVerified](03_messages.md#msgupdateentityverified) + - [MsgTransferEntity](03_messages.md#msgtransferentity) + - [MsgCreateEntityAccount](03_messages.md#msgcreateentityaccount) + - [MsgGrantEntityAccountAuthz](03_messages.md#msggrantentityaccountauthz) + +4. **[Events](04_events.md)** + + - [Events](04_events.md#events) + - [EntityCreatedEvent](04_events.md#entitycreatedevent) + - [EntityUpdatedEvent](04_events.md#entityupdatedevent) + - [EntityVerifiedUpdatedEvent](04_events.md#entityverifiedupdatedevent) + - [EntityTransferredEvent](04_events.md#entitytransferredevent) + - [EntityAccountCreatedEvent](04_events.md#entityaccountcreatedevent) + - [EntityAccountAuthzCreatedEvent](04_events.md#entityaccountauthzcreatedevent) + +5. **[Parameters](05_params.md)** + +6. **[Future Improvements](06_future_improvements.md)** diff --git a/developers/ixo-blockchain/iid/spec/01_concepts.md b/developers/ixo-blockchain/iid/spec/01_concepts.md new file mode 100644 index 0000000..bf82bbd --- /dev/null +++ b/developers/ixo-blockchain/iid/spec/01_concepts.md @@ -0,0 +1,106 @@ +# Concepts + +## DID Documents + +A DID (Decentralized Identifier) Document is a standardized format that describes how to reach a DID subject. This format is inherently decentralized, meaning it isn't dependent on a centralized authority or a single point of failure. + +### Key Components of DID Documents: + +- **DID Subject:** The entity that the DID Document describes. It is identified by the DID itself. +- **Public Keys:** Used for authenticating the DID subject and, in some cases, for recovering lost or compromised DIDs. +- **Authentication Methods:** Specify the mechanisms that can be used to authenticate as the DID subject. +- **Service Endpoints:** These enable the discovery of services that can be utilized to interact with the DID subject or associated entities. + +DID Documents in our system also adhere to the JSON-LD (JSON Linked Data) protocols, which allow data interchange and integration of linked data using JSON. JSON-LD ensures a standardized, extensible, and context-aware representation of data in JSON format. + +### Advantages: + +- **Decentralization:** DID Documents leverage decentralized systems, negating the vulnerabilities of central points of failure. +- **Interoperability:** Their standardized format ensures DID Documents can be consistently interpreted across varying systems and platforms. +- **Security and Privacy:** Their decentralized nature guarantees users retain full control over their identifiers, freeing them from reliance on potentially vulnerable centralized systems. + +For a comprehensive understanding and detailed specifications of DID Documents, refer to the official [W3C DID specification](https://www.w3.org/TR/did-core/). For specifics on JSON-LD, consult the [W3C JSON-LD specification](https://www.w3.org/TR/json-ld/). + +![DID-Document](./assets/did_doc.svg) + +# IID Module + +
+The `iid` module encapsulates our implementation of DID Document management on our blockchain. Built atop the sturdy foundation of the Cosmos SDK, this module supports the creation, reading, and updating of DID Documents, ensuring these operations are in compliance with W3C's official standards. By following both the DID and JSON-LD specifications, we provide a decentralized platform optimized for dependable DID management. +
+
+ +Every digital asset in the Cosmos context should have a universally addressable Interchain Identifier (IID). +Interchain Identifiers are a standards-compliant mechanism for uniquely identifying and referring to digital assets within chain namespaces. +IIDs also enable (off-chain) assertions to be made about (on-chain) digital assets โ€“ for instance, in the form of Verifiable Credentials. +Each IID is associated with an IID Document, which contains all the data needed to compose and interact with an asset's properties and services. + +## Context + +Applications using this module will enable assets on Cosmos networks to be interoperable with the systems and tooling for Decentralised Identifiers (DIDs), which conform with the [W3C DID Core](https://w3c.github.io/did-core/) and related family of specifications. +The types of assets for which this is relevant includes Non-Fungible Tokens (NFTs), Fungible Tokens, Wallets Accounts, Self-sovereign Digital Identifiers, Name Records, or any other uniquely identifiable asset type. + +Any module which perfoms IID registry functions may implement the same methods as the IID module. Or application modules may use the services of the IID Module to perform these functions. + +Integrating IID registry functions within application-specific modules has the advantage of reducing redundancies by having the application module as a context. + +For application chains which have multiple modules that use IIDs (e.g. an NFT module plus Fungible Tokens module, plus Self-sovereign Identity Module), developers might find it more convenient to include the IID Module to service all their application-specific modules. + +## Concepts + +### DIDs and IIDs + +Decentralized Identifiers (DIDs) are the [W3C specification](https://w3c.github.io/did-core/) for identifying any subject in the physical or digital realm. DIDs implement standardised DID Methods to produce fully-qualified Universal Resource Identifier (URI), as defined by RFC3986. + +Interchain Identifiers (IIDs) are a DID Method for identifying on-chain assets โ€“ such as NFTs, fungible tokens, namespace records and account wallets. + +### IID Document + +Properties of an IID are conceptually stored in the format of an IID Document object. Which contains core properties (as defined by [W3C DID Core](https://w3c.github.io/did-core/)): + +- Identifiers + - DID Subject + - DID Controller + - Also Known As +- Verification Methods + - Cryptographic material +- Verification Relationships + - Authentication + - Assertion + - Key Agreement + - Capability Invocation + - Capability Delegation +- Service + +As well as additional property sets which are unique to digital assets: + +- Linked Resources +- Linked Claims +- Linked Entities +- Accorded Rights + +Property extensions may be added by application developers who need to implement their own [DID Method](https://w3c.github.io/did-core/#method-syntax) for a specific use case (although it is anticipated that the IID method should serve most). + +### IID Registry + +The IID Module is a [Verifiable Data Registry](https://w3c.github.io/did-core/#dfn-verifiable-data-registry) system to CRU(without the D) decentralized identifiers and IID documents. + +Resolving a given IID using the IID Module services returns the data necessary to produce an IID document in a [DID-conformant format](https://w3c.github.io/did-core/#dfn-did-documents), which can be serialized as JSON-LD. + +### IID Method + +The IID Method defines a standard way to: + +- Create an IID +- Set the properties associated with the IID +- Read (resolve) an IID Document to produce a conformant JSON-LD representation. +- Update IID Document properties +- Deactivate an IID + +### IID Resolver + +The IID resolver is a [DID resolver](https://w3c.github.io/did-core/#dfn-did-resolvers) service that takes an IID as input and produces an IID Document as output (which conforms to the [W3C DID documents](https://w3c.github.io/did-core/#dfn-did-documents) format). + +### IID Deactivation + +If an IID has been [deactivated](https://w3c.github.io/did-core/#method-operations), the IID document metadata includes a property `deactivated` with the boolean value `true`. diff --git a/developers/ixo-blockchain/iid/spec/02_state.md b/developers/ixo-blockchain/iid/spec/02_state.md new file mode 100644 index 0000000..a77aa25 --- /dev/null +++ b/developers/ixo-blockchain/iid/spec/02_state.md @@ -0,0 +1,238 @@ +# State + +## Iids + +An IidDocument is stored in the state and is accessed by the id of the IidDocument(user provided). + +- Iids: `0x01 | iidId(DID) -> ProtocolBuffer(IidDocument)` + +# Types + +### IidDocument + +```go +type IidDocument struct { + Context []*Context + Id string + Controller []string + VerificationMethod []*VerificationMethod + Service []*Service + Authentication []string + AssertionMethod []string + KeyAgreement []string + CapabilityInvocation []string + CapabilityDelegation []string + LinkedResource []*LinkedResource + AccordedRight []*AccordedRight + LinkedEntity []*LinkedEntity + LinkedClaim []*LinkedClaim + AlsoKnownAs string + IidMetadata *IidMetadata +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the DID document. +- `context` - a list of [Context](#context) +- `controller` - a list of strings of controllers(DIDs). A DID controller is an entity that is authorized to make changes to a DID document. https://www.w3.org/TR/did-core/#did-controller +- `verificationMethod` - a list of [VerificationMethod](#verification-method) +- `service` - a list of [Service](#service) +- `linkedResource` - a list of [LinkedResource](#linked-resource) +- `accordedRight` - a list of [AccordedRight](#accorded-right) +- `linkedEntity` - a list of [LinkedEntity](#linked-entity) +- `linkedClaim` - a list of [LinkedClaim](#linked-claim) +- `authentication` - a list of strings. Authentication represents public keys associated with the did document. https://www.w3.org/TR/did-core/#authentication +- `assertionMethod` - a list of strings. Used to specify how the DID subject is expected to express claims, such as for the purposes of issuing a Verifiable Credential. https://www.w3.org/TR/did-core/#assertion +- `keyAgreement` - a list of strings. Used to specify how an entity can generate encryption material in order to transmit confidential information intended for the DID subject. https://www.w3.org/TR/did-core/#key-agreement +- `capabilityInvocation` - a list of strings. Used to specify a verification method that might be used by the DID subject to invoke a cryptographic capability, such as the authorization to update the DID Document. https://www.w3.org/TR/did-core/#capability-invocation +- `capabilityDelegation` - a list of strings. Used to specify a mechanism that might be used by the DID subject to delegate a cryptographic capability to another party. https://www.w3.org/TR/did-core/#capability-delegation +- `alsoKnownAs` - a string. The assertion that two or more DIDs (or other types of URI) refer to the same DID subject can be made using the alsoKnownAs property. https://www.w3.org/TR/did-core/#also-known-as +- `iidMetadata` - a [IidMetadata](#iidmetadata) + +### Verification Method + +A DID document can express verification methods, such as cryptographic public keys, which can be used to authenticate or authorize interactions with the DID subject or associated parties. https://www.w3.org/TR/did-core/#verification-methods + +```go +type VerificationMethod struct { + Id string + Type string + Controller string + // Types that are valid to be assigned to VerificationMaterial: + // *VerificationMethod_BlockchainAccountID + // *VerificationMethod_PublicKeyHex + // *VerificationMethod_PublicKeyMultibase + // *VerificationMethod_PublicKeyBase58 + VerificationMaterial isVerificationMethod_VerificationMaterial +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the verification method (required). +- `type` - a string the type of verification method +- `controller` - a string containing the did of the owner of the key +- `verificationMaterial`: a string that is either + - `blockchainAccountID` - a string representing a cosmos based account address + - `publicKeyHex` - a string representing a public key encoded as a hex string + - `publicKeyMultibase` - a string representing a public key encoded according to the Multibase Data Format [Hexadecimal upper-case encoding](https://datatracker.ietf.org/doc/html/draft-multiformats-multibase#appendix-B.1) + - `publicKeyBase58` - a string representing a public key encoded as a base58 string + +### Service + +Services are used in DID documents to express ways of communicating with the DID subject or associated entities. https://www.w3.org/TR/did-core/#services + +```go +type Service struct { + Id string + Type string + ServiceEndpoint string +} +``` + +The field's descriptions is as follows: + +- `id` - a string representing the service id +- `type` - a string representing the type of the service (for example: IIDComm) +- `serviceEndpoint` - a string representing the endpoint of the service, such as an URL + +### Accorded Right + +An Accorded Right is stored in a list within the IidDocument data structure. Accorded Right are used to - + +```go +type AccordedRight struct { + Type string + Id string + Mechanism string + Message string + Service string +} +``` + +The field's descriptions is as follows: + +- `id` - a string representing the right id +- `type` - a string representing the type of the right +- `mechanism` - a string representing the mechanism of the right, +- `message` - a string representing the message pertaining to the right, +- `service` - a string representing the service this right describes + +### Linked Resource + +An Linked Resource is stored in a list within the IidDocument data structure. Linked Resource are used to - + +```go +type LinkedResource struct { + Type string + Id string + Description string + MediaType string + ServiceEndpoint string + Proof string + Encrypted string + Right string +} +``` + +The field's descriptions is as follows: + +- `id` - a string representing the unique service id +- `type` - a string representing the type of linked resource +- `description ` - a string representing the description of this linked resource +- `mediaType ` - a string representing the [MIME](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types) type of the linked resource +- `serviceEndpoint ` - a string representing the endpoint of the service, such as an URL +- `proof ` - a string representing the proof to verify the linked resource +- `encrypted ` - a string representing the boolean value for whether this linked resource is encrypted or not +- `right ` - a string + +### Linked Entity + +An Linked Entity is stored in a list within the IidDocument data structure. Linked Entity are used to - + +```go +type LinkedEntity struct { + Type string + Id string + Relationship string + Service string +} +``` + +The field's descriptions is as follows: + +- `id` - a string representing the unique linked entity id +- `relationship ` - a string representing the relationship for the linked Entity eg. `subsidiary` +- `type ` - a string representing the type of linked entity eg. `BlockchainAccount`, `Group` +- `service ` - a string representing the service (possibly uri) that the linked entity is on. + +### Linked Claim + +An Linked Claim is stored in a list within the IidDocument data structure. Linked Claim are used to - + +```go +type LinkedClaim struct { + Type string + Id string + Description string + ServiceEndpoint string + Proof string + Encrypted string + Right string +} +``` + +The field's descriptions is as follows: + +- `id` - a string representing the unique service id +- `type` - a string representing the type of linked resource +- `description ` - a string representing the description of this linked resource +- `serviceEndpoint ` - a string representing the endpoint of the service, such as an URL +- `proof ` - a string representing the proof to verify the linked resource. +- `encrypted ` - a string representing the boolean value for whether this linked resource is encrypted or not. +- `right ` - a string + +### Context + +A Context is stored in a list within the IidDocument data structure. Context are used to define the spec for the DID Documents since it follows the jsonld protocol. https://www.w3.org/TR/did-core/#json-ld + +```go +type Context struct { + Key string + Val string +} +``` + +The field's descriptions is as follows: + +- `key` - a string identifying the context mainly for storage purposes +- `value ` - a string representing the context + +## IidMetadata + +A IidMetadata stores information relative to a DID document such as versionId, created, updated and deactivated. + +```go +type IidMetadata struct { + VersionId string + Created *time.Time + Updated *time.Time + Deactivated bool +} +``` + +The field's descriptions is as follows: + +- `versionId` - the version of the last update operation for the did document +- `updated` - the timestamp of the last update operation for the did document +- `created` - the timestamp of the create operation +- `deactivated` - a boolean indicating if the iid has been deactivated + +## Verification + +A verification message represent a combination of a verification method and a set of verification relationships. It has the following fields: + +- `relationships` - a list of strings identifying the verification relationship for the verification method +- `method` - a [verification method object](#verification-method) +- `context` - a list of strings identifying additional [json ld contexts](https://json-ld.org/spec/latest/json-ld/#the-context) diff --git a/developers/ixo-blockchain/iid/spec/03_messages.md b/developers/ixo-blockchain/iid/spec/03_messages.md new file mode 100644 index 0000000..3d8652b --- /dev/null +++ b/developers/ixo-blockchain/iid/spec/03_messages.md @@ -0,0 +1,397 @@ +# Messages + +In this section we describe the processing of the iid messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state.md) section. + +## MsgCreateIidDocument + +A `MsgCreateIidDocument` is used to create a new iid document. + +```go +type MsgCreateIidDocument struct { + Id string + Controllers []string + Context []*Context + Verifications []*Verification + Services []*Service + AccordedRight []*AccordedRight + LinkedResource []*LinkedResource + LinkedEntity []*LinkedEntity + AlsoKnownAs string + Signer string + LinkedClaim []*LinkedClaim +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the DID document. +- `context` - a list of [Context](02_state.md#context) +- `controllers` - a list of strings of controllers(DIDs). A DID controller is an entity that is authorized to make changes to a DID document. https://www.w3.org/TR/did-core/#did-controller +- `verifications` - a list of [Verifications](02_state.md#verification) +- `service` - a list of [Service](02_state.md#service) +- `linkedResource` - a list of [LinkedResource](02_state.md#linked-resource) +- `accordedRight` - a list of [AccordedRight](02_state.md#accorded-right) +- `linkedEntity` - a list of [LinkedEntity](02_state.md#linked-entity) +- `linkedClaim` - a list of [LinkedClaim](02_state.md#linked-claim) +- `alsoKnownAs` - a string. The assertion that two or more DIDs (or other types of URI) refer to the same DID subject can be made using the alsoKnownAs property. https://www.w3.org/TR/did-core/#also-known-as +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgUpdateIidDocument + +The `MsgUpdateIidDocument` is used to update an iid document. It updates the iid document with all the fields, so if a field is empty it will be updated with default go type, aka never null. For this reason also provide the previous values for fields you do not wish to update. + +```go +type MsgUpdateIidDocument struct { + Id string + Controllers []string + Context []*Context + Verifications []*Verification + Services []*Service + AccordedRight []*AccordedRight + LinkedResource []*LinkedResource + LinkedEntity []*LinkedEntity + AlsoKnownAs string + Signer string + LinkedClaim []*LinkedClaim +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the DID document. +- `context` - a list of [Context](02_state.md#context) +- `controllers` - a list of strings of controllers(DIDs). A DID controller is an entity that is authorized to make changes to a DID document. https://www.w3.org/TR/did-core/#did-controller +- `verifications` - a list of [Verifications](02_state.md#verification) +- `service` - a list of [Service](02_state.md#service) +- `linkedResource` - a list of [LinkedResource](02_state.md#linked-resource) +- `accordedRight` - a list of [AccordedRight](02_state.md#accorded-right) +- `linkedEntity` - a list of [LinkedEntity](02_state.md#linked-entity) +- `linkedClaim` - a list of [LinkedClaim](02_state.md#linked-claim) +- `alsoKnownAs` - a string. The assertion that two or more DIDs (or other types of URI) refer to the same DID subject can be made using the alsoKnownAs property. https://www.w3.org/TR/did-core/#also-known-as +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgAddVerification + +The `MsgAddVerification` is used to add new [verification methods](https://w3c.github.io/did-core/#verification-methods) and [verification relationships](https://w3c.github.io/did-core/#verification-relationships) to an iid document. + +```go +type MsgAddVerification struct { + Id string + Verification *Verification + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `verification` - the [verification](02_state.md#verification) to add to the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgSetVerificationRelationships + +The `MsgSetVerificationRelationships` is used to overwrite the [verification relationships](https://w3c.github.io/did-core/#verification-relationships) for a [verification methods](https://w3c.github.io/did-core/#verification-methods) of an iid document. + +```go +type MsgSetVerificationRelationships struct { + Id string + MethodId string + Relationships []string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `methodId` - a string containing the unique identifier of the verification method within the iid document. +- `relationships` - a list of strings identifying the verification relationship for the verification method +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgRevokeVerification + +The `MsgRevokeVerification` is used to remove a [verification method](https://w3c.github.io/did-core/#verification-methods) and related [verification relationships](https://w3c.github.io/did-core/#verification-relationships) from an iid document. + +```go +type MsgRevokeVerification struct { + Id string + MethodId string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `methodId` - a string containing the unique identifier of the verification method within the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgAddService + +The `MsgAddService` is used to add a [service](https://w3c.github.io/did-core/#services) to an iid document. + +```go +type MsgAddService struct { + Id string + ServiceData *Service + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `service_data` - the [service](02_state.md#service) object to add to the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgDeleteService + +The `MsgDeleteService` is used to remove a [service](https://w3c.github.io/did-core/#services) from an iid document. + +```go +type MsgDeleteService struct { + Id string + ServiceId string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `serviceData` - the [service](02_state.md#service) object to add to the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgAddController + +The `MsgAddController` is used to add a controller to an iid document. + +```go +type MsgAddController struct { + Id string + ControllerDid string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `controllerDid` - the did string to add to the iid document's controllers +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgDeleteController + +The `MsgDeleteController` is used to remove a controller from an iid document. + +```go +type MsgDeleteController struct { + Id string + ControllerDid string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `controllerDid` - the controller did object to remove from the iid document's controllers +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgAddLinkedResource + +The `MsgAddLinkedResource` is used to add a [LinkedResource](02_state.md#linked-resource) to an iid document. + +```go +type MsgAddLinkedResource struct { + Id string + LinkedResource *LinkedResource + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `linkedResource` - the [LinkedResource](02_state.md#linked-resource) object to add to the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgDeleteLinkedResource + +The `MsgDeleteLinkedResource` is used to remove a [LinkedResource](02_state.md#linked-resource) from an iid document. + +```go +type MsgDeleteLinkedResource struct { + Id string + ResourceId string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `resourceId` - the unique id of the [LinkedResource](02_state.md#linked-resource) in the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgAddLinkedClaim + +The `MsgAddLinkedClaim` is used to add a [LinkedClaim](02_state.md#linked-claim) to an iid document. + +```go +type MsgAddLinkedClaim struct { + Id string + LinkedClaim *LinkedClaim + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `linkedClaim` - the [LinkedClaim](02_state.md#linked-claim) object to add to the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgDeleteLinkedClaim + +The `MsgDeleteLinkedClaim` is used to remove a [LinkedClaim](02_state.md#linked-claim) from an iid document. + +```go +type MsgDeleteLinkedClaim struct { + Id string + ClaimId string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `claimId` - the unique id of the [LinkedClaim](02_state.md#linked-claim) in the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgAddLinkedEntity + +The `MsgAddLinkedEntity` is used to add a [LinkedEntity](02_state.md#linked-entity) to an iid document. + +```go +type MsgAddLinkedEntity struct { + Id string + LinkedEntity *LinkedEntity + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `linkedEntity` - the [LinkedEntity](02_state.md#linked-entity) object to add to the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgDeleteLinkedEntity + +The `MsgDeleteLinkedEntity` is used to remove a [LinkedEntity](02_state.md#linked-entity) from an iid document. + +```go +type MsgDeleteLinkedEntity struct { + Id string + EntityId string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `entityId` - the unique id of the [LinkedEntity](02_state.md#linked-entity) in the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgAddAccordedRight + +The `MsgAddAccordedRight` is used to add an [AccordedRight](02_state.md#accorded-right) to an iid document. + +```go +type MsgAddAccordedRight struct { + Id string + AccordedRight *AccordedRight + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `accordedRight` - the [AccordedRight](02_state.md#accorded-right) object to add to the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgDeleteAccordedRight + +The `MsgDeleteAccordedRight` is used to remove a [AccordedRight](02_state.md#accorded-right) from an iid document. + +```go +type MsgDeleteAccordedRight struct { + Id string + RightId string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `rightId` - the unique id of the [AccordedRight](02_state.md#accorded-right) in the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgAddIidContext + +The `MsgAddIidContext` is used to add a [Context](02_state.md#context) to an iid document. + +```go +type MsgAddIidContext struct { + Id string + Context *Context + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `context ` - the [Context](02_state.md#context) object to add to the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgDeleteIidContext + +The `MsgDeleteIidContext` is used to remove a [Context](02_state.md#context) from an iid document. + +```go +type MsgDeleteIidContext struct { + Id string + ContextKey string + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `contextKey ` - the unique key of the [Context](02_state.md#context) in the iid document +- `signer` - a string containing the cosmos address of the private key signing the transaction + +## MsgDeactivateIID + +The `MsgDeactivateIID` is used to change the state of the [IidDocument](02_state.md#iiddocument) by changing the `Deactivated` field inside the [IidMetadata](02_state.md#iidmetadata) to true. + +```go +type MsgDeactivateIID struct { + Id string + State bool + Signer string +} +``` + +The field's descriptions is as follows: + +- `id` - the iid string identifying the iid document +- `state` - the string representing the boolean value to change the [IidMetadata](02_state.md#iidmetadata) `Deactivated` field to, currently ignored and only changed to `false` +- `signer` - a string containing the cosmos address of the private key signing the transaction diff --git a/developers/ixo-blockchain/iid/spec/04_events.md b/developers/ixo-blockchain/iid/spec/04_events.md new file mode 100644 index 0000000..7027720 --- /dev/null +++ b/developers/ixo-blockchain/iid/spec/04_events.md @@ -0,0 +1,31 @@ +# Events + +The iid module emits the following typed events: + +### IidDocumentCreatedEvent + +Emitted after a successfull `MsgCreateIidDocument`, `MsgCreateEntity`, since for entity creation an iid doc also gets created. + +```go +type IidDocumentCreatedEvent struct { + IidDocument *IidDocument +} +``` + +The field's descriptions is as follows: + +- `iidDocument` - the full [IidDocument](02_state.md#iiddocument) + +### IidDocumentUpdatedEvent + +Emitted after a successfull Msg of all the rest of iid module Msg types since they all update the iid doc. + +```go +type IidDocumentUpdatedEvent struct { + IidDocument *IidDocument +} +``` + +The field's descriptions is as follows: + +- `iidDocument` - the full [IidDocument](02_state.md#iiddocument) diff --git a/developers/ixo-blockchain/iid/spec/05_params.md b/developers/ixo-blockchain/iid/spec/05_params.md new file mode 100644 index 0000000..dbdeff2 --- /dev/null +++ b/developers/ixo-blockchain/iid/spec/05_params.md @@ -0,0 +1,3 @@ +# Parameters + +The iid module contains no module paramters. diff --git a/developers/ixo-blockchain/iid/spec/06_future_improvements.md b/developers/ixo-blockchain/iid/spec/06_future_improvements.md new file mode 100644 index 0000000..0ed8892 --- /dev/null +++ b/developers/ixo-blockchain/iid/spec/06_future_improvements.md @@ -0,0 +1,7 @@ +# Future Improvements + +The development and refinement of the IID module is an ongoing endeavor. As decentralized ecosystems evolve and new challenges and opportunities arise, we are dedicated to ensuring that the IID module remains at the forefront of innovation and usability. + +While we have a roadmap for enhancements and optimizations, we highly value feedback from our community and users. Such collaboration helps in identifying areas of improvement, potential integrations, and innovative features that could further enhance the module. + +If you have suggestions, feedback, or ideas that could benefit the IID module, we encourage you to share them with our team. Your insights are crucial in our pursuit of excellence and ensuring that the IID module meets the diverse needs of its users. diff --git a/developers/ixo-blockchain/iid/spec/README.md b/developers/ixo-blockchain/iid/spec/README.md new file mode 100644 index 0000000..23bdb7b --- /dev/null +++ b/developers/ixo-blockchain/iid/spec/README.md @@ -0,0 +1,73 @@ +# Iid module specification + +This document specifies the iid module, a custom Ixo Cosmos SDK module. + +The IID (Interchain Identifier) Module establishes a decentralized identity mechanism, ensuring a standardized approach for all entities within the system. By harnessing the power of DIDs (Decentralized Identifiers) and IIDs, this module facilitates a robust, secure, and universally recognizable identity framework, paving the way for a seamless integration across various platforms and networks. + +## Contents + +1. **[Concepts](01_concepts.md)** + + - [Concepts](01_concepts.md#concepts) + - [DID Documents](01_concepts.md#did-documents) + - [Key Components of DID Documents:](01_concepts.md#key-components-of-did-documents) + - [Advantages:](01_concepts.md#advantages) + - [IID Module](01_concepts.md#iid-module) + - [Context](01_concepts.md#context) + - [Concepts](01_concepts.md#concepts-1) + - [DIDs and IIDs](01_concepts.md#dids-and-iids) + - [IID Document](01_concepts.md#iid-document) + - [IID Registry](01_concepts.md#iid-registry) + - [IID Method](01_concepts.md#iid-method) + - [IID Resolver](01_concepts.md#iid-resolver) + - [IID Deactivation](01_concepts.md#iid-deactivation) + +2. **[State](02_state.md)** + + - [State](02_state.md#state) + - [Iids](02_state.md#iids) + - [Types](02_state.md#types) + - [IidDocument](02_state.md#iiddocument) + - [Verification Method](02_state.md#verification-method) + - [Service](02_state.md#service) + - [Accorded Right](02_state.md#accorded-right) + - [Linked Resource](02_state.md#linked-resource) + - [Linked Entity](02_state.md#linked-entity) + - [Linked Claim](02_state.md#linked-claim) + - [Context](02_state.md#context) + - [IidMetadata](02_state.md#iidmetadata) + - [Verification](02_state.md#verification) + +3. **[Messages](03_messages.md)** + + - [Messages](03_messages.md#messages) + - [MsgCreateIidDocument](03_messages.md#msgcreateiiddocument) + - [MsgUpdateIidDocument](03_messages.md#msgupdateiiddocument) + - [MsgAddVerification](03_messages.md#msgaddverification) + - [MsgSetVerificationRelationships](03_messages.md#msgsetverificationrelationships) + - [MsgRevokeVerification](03_messages.md#msgrevokeverification) + - [MsgAddService](03_messages.md#msgaddservice) + - [MsgDeleteService](03_messages.md#msgdeleteservice) + - [MsgAddController](03_messages.md#msgaddcontroller) + - [MsgDeleteController](03_messages.md#msgdeletecontroller) + - [MsgAddLinkedResource](03_messages.md#msgaddlinkedresource) + - [MsgDeleteLinkedResource](03_messages.md#msgdeletelinkedresource) + - [MsgAddLinkedClaim](03_messages.md#msgaddlinkedclaim) + - [MsgDeleteLinkedClaim](03_messages.md#msgdeletelinkedclaim) + - [MsgAddLinkedEntity](03_messages.md#msgaddlinkedentity) + - [MsgDeleteLinkedEntity](03_messages.md#msgdeletelinkedentity) + - [MsgAddAccordedRight](03_messages.md#msgaddaccordedright) + - [MsgDeleteAccordedRight](03_messages.md#msgdeleteaccordedright) + - [MsgAddIidContext](03_messages.md#msgaddiidcontext) + - [MsgDeleteIidContext](03_messages.md#msgdeleteiidcontext) + - [MsgDeactivateIID](03_messages.md#msgdeactivateiid) + +4. **[Events](04_events.md)** + + - [Events](04_events.md#events) + - [IidDocumentCreatedEvent](04_events.md#iiddocumentcreatedevent) + - [IidDocumentUpdatedEvent](04_events.md#iiddocumentupdatedevent) + +5. **[Parameters](05_params.md)** + +6. **[Future Improvements](06_future_improvements.md)** diff --git a/developers/ixo-blockchain/iid/spec/assets/did_doc.svg b/developers/ixo-blockchain/iid/spec/assets/did_doc.svg new file mode 100644 index 0000000..85e36ee --- /dev/null +++ b/developers/ixo-blockchain/iid/spec/assets/did_doc.svg @@ -0,0 +1,435 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/developers/ixo-blockchain/token/spec/01_concepts.md b/developers/ixo-blockchain/token/spec/01_concepts.md new file mode 100644 index 0000000..44fc44d --- /dev/null +++ b/developers/ixo-blockchain/token/spec/01_concepts.md @@ -0,0 +1,51 @@ +# Concepts + +### EIP-1155 Smart Contract Tokens + +[EIP-1155](https://eips.ethereum.org/EIPS/eip-1155) represents a multi-token standard that supports fungible, semi-fungible, and non-fungible tokens within a single smart contract. The distinction is crucial as it allows for both unique and fungible token behaviors within the same contract. By adopting this standard, the `Token` module provides a flexible solution for varied token use-cases, including those in DeFi, gaming, art, and beyond. + +# Token Module + +The Token module offers an advanced management solution for the creation, minting, and management of EIP-1155 smart contract tokens within the decentralized ecosystem. + +## Concepts + +### Token + +A [Token](02_state.md#token) can also be thought of as a token collection and it serves as an umbrella for individual tokens and consists of the following attributes: + +- **Minter:** The primary entity authorized to mint tokens within the collection. +- **Name (Namespace):** A unique identifier for the token collection. +- **Description:** A textual overview of the token collection. +- **Image:** A visual representation or logo for the token collection. +- **Cap:** The upper limit on the number of unique EIP-1155 tokens that can be minted within the collection. +- **Current Supply Count:** A real-time count of minted tokens within the collection. +- **Retired and Cancelled Tokens List:** A registry for tracking tokens that have been retired or canceled. + +Upon the creation of a token collection, a corresponding CW1155 smart contract is initiated, with its address stored within the collection for reference. + +### TokenProperties + +Every time a token is minted, a [TokenProperties](02_state.md#tokenproperties) object gets created and stored in the on-chain key-value store. This ensures the persistence of crucial token attributes and data, granting transparency and integrity. + +## Features + +### 1. Token Collection Creation + +Minting starts with the establishment of a token collection, complete with all necessary attributes and an associated CW1155 smart contract. + +### 2. Minting Authorizations + +The primary minter has the authority to delegate minting capabilities to other entities through [authz grants](02_state.md#authz-types), further decentralizing and democratizing the minting process. + +### 3. Batch Operations + +Tokens can be minted, transfered and retired in batches, allowing for efficient bulk operations while maintaining the unique attributes of each individual token. + +### 4. Token Uniqueness and Fungibility + +Leveraging the benefits of EIP-1155, tokens within the same namespace (like "CARBON") can have distinct IDs, making them non-fungible. However, tokens sharing an ID remain fungible among themselves. This dual nature offers unparalleled versatility in token operations and value calculations. + +### 5. Token Retirement + +Token holders can retire their tokens as a means to "offset their footprint," offering an environmentally-conscious angle to token utility. diff --git a/developers/ixo-blockchain/token/spec/02_state.md b/developers/ixo-blockchain/token/spec/02_state.md new file mode 100644 index 0000000..a47eae6 --- /dev/null +++ b/developers/ixo-blockchain/token/spec/02_state.md @@ -0,0 +1,184 @@ +# State + +## Tokens + +A Token is stored in the state and is accessed by the concatenation of the `minter + contract_address` as each `Token` creation instantiates a new contract with contract code form `Ixo1155ContractCode`. + +- Tokens: `0x01 | minter + contract_address -> ProtocolBuffer(Token)` + +## TokenProperties + +A TokenProperties is stored in the state and is accessed by the identity of the TokenProperties(user provided). + +- Claims: `0x02 | tokenPropertiesId -> ProtocolBuffer(TokenProperties)` + +# Types + +### Token + +A Token is the base Token associated with a specific Minter, Contract Address and Token name (namespace) + +```go +type Token struct { + Minter string + ContractAddress string + Class string + Name string + Description string + Image string + Type string + Cap github_com_cosmos_cosmos_sdk_types.Uint + Supply github_com_cosmos_cosmos_sdk_types.Uint + Paused bool + Stopped bool + Retired []*TokensRetired + Cancelled []*TokensCancelled +} +``` + +The field's descriptions is as follows: + +- `minter` - a string containing the address of the minter +- `contractAddress` - a string containing the address of the smart contract(cw1155) that was instantiated on creation of the `Token` and is used to mint the 1155 tokens. +- `class` - a string containing the token protocol entity DID (validated) +- `name` - a string containing the token name, which must be unique (namespace) +- `description` - a string containing any arbitrary description +- `image` - a string containing the image url for the token +- `type` - a string containing the token type eg. ixo1155 +- `cap` - a integer containing the maximum number of tokens with this name that can be minted, 0 is unlimited +- `supply` - a integer containing how much has already been minted for this Token name +- `paused` - a boolean indicating wheter to stop allowance of token minting temporarily +- `stopped` - a boolean indicating wheter to stop allowance of token minting permanently +- `retired` - a list of [EntityAccount](#entityaccount) +- `cancelled` - a list of [EntityAccount](#entityaccount) + +### TokensRetired + +A TokensCancelled stores information about the retired tokens that was burned on the ixo1155 smart contract with the address at `ContractAddress` of the [Token](#token) + +```go +type TokensRetired struct { + Id string + Reason string + Jurisdiction string + Amount github_com_cosmos_cosmos_sdk_types.Uint + Owner string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the token ([TokenProperties](#tokenproperties)) +- `reason` - a string containing any arbitrary reason that specifies the reason for retiring tokens. +- `jurisdiction` - a string containing the jurisdiction of the token owner. A jurisdiction has the format: [-[ ]] The country-code must be 2 alphabetic characters, the sub-national-code can be 1-3 alphanumeric characters, and the postal-code can be up to 64 alphanumeric characters. Only the country-code is required, while the sub-national-code and postal-code are optional and can be added for increased precision. +- `amount` - a integer indicating how many tokens of the token with `id` has been retired. +- `owner` - a string containing the cosmos address of the owner who did the retiring. + +### TokensCancelled + +A TokensCancelled stores information about the cancelled tokens that was burned on the ixo1155 smart contract with the address at `ContractAddress` of the [Token](#token) + +```go +type TokensCancelled struct { + Id string + Reason string + Amount github_com_cosmos_cosmos_sdk_types.Uint + Owner string +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the token ([TokenProperties](#tokenproperties)) +- `reason` - a string containing any arbitrary reason that specifies the reason for cancelling tokens. +- `amount` - a integer indicating how many tokens of the token with `id` has been cancelled. +- `owner` - a string containing the cosmos address of the owner who did the cancelling. + +### TokenProperties + +A TokenProperties stores information about a specific minted token that will be minted on the ixo1155 smart contract with the address at `ContractAddress` of the [Token](#token) + +```go +type TokenProperties struct { + Id string + Index string + Name string + Collection string + TokenData []*TokenData +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the token +- `index` - a string containing the unique identifier hexstring that identifies the token +- `name` - a string containing the token name, which is same as [Token](#token) `Name` +- `collection` - a string containing the did of the "collection" the token was minted towards (eg. Supamoto Malawi Did) +- `tokenData` - a list of [TokenData](#tokendata) + +### TokenData + +A TokenData stores information that is the `linkedResources` added to `tokenMetadata` when queried + +```go +type TokenData struct { + Uri string + Encrypted bool + Proof string + Type string + Id string +} +``` + +The field's descriptions is as follows: + +- `uri` - a string containing the uri where the resource can be fetched (eg. a credential link abc123.ipfs) +- `encrypted` - a boolean indicating whether the resource data has been encrypted or not +- `proof` - a string containing the proof to verify the resource if a proof exists +- `type` - a string containing the resource type, media type value should always be `application/json` +- `id` - a string containing the did of entity to map token to, can be empty! + +## Authz Types + +### MintAuthorization + +A MintAuthorization is an authz authorization that can be granted to allow the grantee to mint tokens for the specified [Token](02_state.md#token) with its constraints + +```go +type WithdrawPaymentAuthorization struct { + Minter string + Constraints []*MintConstraints +} +``` + +The field's descriptions is as follows: + +- `minter` - a string containing the account address defined in the [Token](02_state.md#token) `Minter` field +- `constraints` - a list of [MintConstraints](#mintconstraints) + +### MintConstraints + +A MintConstraints stores information about authorization given to make a withdrawal payment through a [WithdrawPaymentAuthorization](#withdrawpaymentauthorization) + +```go +type MintConstraints struct { + ContractAddress string + Amount github_com_cosmos_cosmos_sdk_types.Uint + Name string + Index string + Collection string + TokenData []*TokenData +} +``` + +The field's descriptions is as follows: + +- `claimId` - a string containing the `id` of the claim the withdrawal is for +- `inputs` - a list of cosmos defined `Input` to pass to the the multisend tx to run to withdraw payment +- `outputs` - a list of cosmos defined `Output` to pass to the the multisend tx to run to withdraw payment +- `paymentType` - a [PaymentType](02_state.md#paymenttype) +- `contract_1155Payment` - a [Contract1155Payment](02_state.md#contract1155payment) +- `toAddress` - a string containing the account address to make the payment to +- `fromAddress` - a string containing the account address to make the payment from +- `releaseDate` - a timestamp of the date that grantee can execute authorization to make the withdrawal payment, calculated from created date plus the timeout on [Collection](02_state.md#collection) `Payments` +- `adminAddress` - a string containing the account address defined in the [Collection](02_state.md#collection) `admin` field diff --git a/developers/ixo-blockchain/token/spec/03_messages.md b/developers/ixo-blockchain/token/spec/03_messages.md new file mode 100644 index 0000000..a076d1a --- /dev/null +++ b/developers/ixo-blockchain/token/spec/03_messages.md @@ -0,0 +1,181 @@ +# Messages + +In this section we describe the processing of the token messages and the corresponding updates to the state. All created/modified state objects specified by each message are defined within the [state](./02_state.md) section. + +## MsgCreateToken + +A `MsgCreateToken` creates and stores a new Token struct (which is a class overview for minting tokens). Sets up the Token by initiating a cw1155 smart contract, and saving the address in the Token as well as a unique name (namespace). + +```go +type MsgCreateToken struct { + Minter string + Class DIDFragment + Name string + Description string + Image string + TokenType string + Cap github_com_cosmos_cosmos_sdk_types.Uint +} +``` + +The field's descriptions is as follows: + +- `minter` - a string containing the address of the minter +- `class` - a string containing the token protocol entity DID (validated) +- `name` - a string containing the token name, which must be unique (namespace) +- `description` - a string containing any arbitrary description +- `image` - a string containing the image url for the token +- `tokenType` - a string containing the token type eg. ixo1155 +- `cap` - a integer containing the maximum number of tokens with this name that can be minted, 0 is unlimited + +## MsgMintToken + +A `MsgMintToken` mints tokens on the ixo1155 contract that was instantiate on the [Token](#token) creation. There will also be [TokenProperties](02_state.md#tokenproperties) created for each unique id. +Allows a Minter to directly mint the token with a name that is specified in the Token, and a unique index. The minted tokens `id` is a hex encoded md5 hash of the token `name` plus `index`, with no separators. + +```go +type MsgMintToken struct { + Minter string + ContractAddress string + Owner string + MintBatch []*MintBatch +} +``` + +The field's descriptions is as follows: + +- `minter` - a string containing the address of the minter +- `contractAddress` - a string containing the contract address, same as the `ContractAddress` of the [Token](#token) +- `owner` - a string containing the address of the owner to mint the tokens for +- `mintBatch` - a list of [MintBatch](#mintbatch) + +## MsgTransferToken + +A `MsgTransferToken` transfers tokens on the ixo1155 contract that was instantiate on the [Token](#token) creation and where the tokens was minted. + +```go +type MsgTransferToken struct { + Owner string + Recipient string + Tokens []*TokenBatch +} +``` + +The field's descriptions is as follows: + +- `owner` - a string containing the address of the owner to transfer the tokens from +- `recipient` - a string containing the address of the owner to transfer the tokens to +- `tokens` - a list of [TokenBatch](#tokenbatch). All the tokens must be on the smart contract. + +## MsgRetireToken + +A `MsgRetireToken` burns the tokens on the ixo1155 contract that was instantiate on the [Token](#token) creation and where the tokens was minted. It also adds the retire details to the [Token](#token) `Retired` field to keep a record of the retire event. Retiring credits is permanent and cannot be undone. + +```go +type MsgRetireToken struct { + Owner string + Tokens []*TokenBatch + Jurisdiction string + Reason string +} +``` + +The field's descriptions is as follows: + +- `owner` - a string containing the address of the owner of the tokens to retire +- `tokens` - a list of [TokenBatch](#tokenbatch). All the tokens must be on the smart contract. +- `reason` - a string containing any arbitrary reason that specifies the reason for retiring tokens. +- `jurisdiction` - a string containing the jurisdiction of the token owner. A jurisdiction has the format: [-[ ]] The country-code must be 2 alphabetic characters, the sub-national-code can be 1-3 alphanumeric characters, and the postal-code can be up to 64 alphanumeric characters. Only the country-code is required, while the sub-national-code and postal-code are optional and can be added for increased precision. + +## MsgCancelToken + +A `MsgCancelToken` burns the tokens on the ixo1155 contract that was instantiate on the [Token](#token) creation and where the tokens was minted. It also adds the cancel details to the [Token](#token) `Cancelled` field to keep a record of the cancel event. +Cancels a specified amount of tradable tokens, removing the amount from the token owner's tradable balance(by burning it) and removing the amount from the tokenโ€™s tradable supply. Cancelling credits is permanent and cannot be undone. + +```go +type MsgCancelToken struct { + Owner string + Tokens []*TokenBatch + Reason string +} +``` + +The field's descriptions is as follows: + +- `owner` - a string containing the address of the owner of the tokens to retire +- `tokens` - a list of [TokenBatch](#tokenbatch). All the tokens must be on the smart contract. +- `reason` - a string containing any arbitrary reason that specifies the reason for retiring tokens. + +## MsgPauseToken + +A `MsgPauseToken` changes the `Paused` field on the [Token](#token) which stops allowance of token minting temporarily if set to `true` or allow minting again if set to `false` + +```go +type MsgPauseToken struct { + Minter string + ContractAddress string + Paused bool +} +``` + +The field's descriptions is as follows: + +- `minter` - a string containing the address of the minter, must be same as `Minter` of the [Token](#token), must also be the signers address +- `contractAddress` - a string containing the contract address, same as the `ContractAddress` of the [Token](#token) +- `paused` - a boolean indicating whether to stop allowance of token minting temporarily + +## MsgStopToken + +A `MsgPauseToken` changes the `Cancelled` field on the [Token](#token) which stops allowance of token minting permanently + +```go +type MsgStopToken struct { + Minter string + ContractAddress string +} +``` + +The field's descriptions is as follows: + +- `minter` - a string containing the address of the minter, must be same as `Minter` of the [Token](#token), must also be the signers address +- `contractAddress` - a string containing the contract address, same as the `ContractAddress` of the [Token](#token) + +## Generic types + +### MintBatch + +A MintBatch allows batching mint token info + +```go +type MintBatch struct { + Name string + Index string + Amount github_com_cosmos_cosmos_sdk_types.Uint + Collection string + TokenData []*TokenData +} +``` + +The field's descriptions is as follows: + +- `name` - a string containing the token name, which is same as [Token](02_state.md#token) `Name` +- `index` - a string containing the unique identifier hexstring that identifies the token +- `amount` - a integer indicating how many tokens must be minted for this unique `index` and generate `id` +- `collection` - a string containing the did of the "collection" the token was minted towards (eg. Supamoto Malawi Did) +- `tokenData` - a list of [TokenData](02_state.md#tokendata) + +### TokenBatch + +A TokenBatch allows batching tokens for transfering and retiring + +```go +type TokenBatch struct { + Id string + Amount github_com_cosmos_cosmos_sdk_types.Uint +} +``` + +The field's descriptions is as follows: + +- `id` - a string containing the unique identifier of the token ([TokenProperties](#tokenproperties)) +- `amount` - a integer indicating how many tokens is in the batch for the specified `id` diff --git a/developers/ixo-blockchain/token/spec/04_events.md b/developers/ixo-blockchain/token/spec/04_events.md new file mode 100644 index 0000000..30a682b --- /dev/null +++ b/developers/ixo-blockchain/token/spec/04_events.md @@ -0,0 +1,139 @@ +# Events + +The token module emits the following typed events: + +### TokenCreatedEvent + +Emitted after a successfull `MsgCreateToken` + +```go +type TokenCreatedEvent struct { + Token *Token +} +``` + +The field's descriptions is as follows: + +- `token` - the full [Token](02_state.md#token) + +### TokenUpdatedEvent + +Emitted after a successfull `MsgMintToken`, `RetireToken`, `CancelToken`, `PauseToken`, `StopToken` + +```go +type TokenUpdatedEvent struct { + Token *Token +} +``` + +The field's descriptions is as follows: + +- `token` - the full [Token](02_state.md#token) + +### TokenMintedEvent + +Emitted for every batch in `MintBatch` after a successfull `MsgMintToken` + +```go +type TokenMintedEvent struct { + ContractAddress string + Minter string + Owner string + Amount github_com_cosmos_cosmos_sdk_types.Uint + TokenProperties *TokenProperties +} +``` + +The field's descriptions is as follows: + +- `minter` - a string containing the address of the minter +- `contractAddress` - a string containing the contract address, same as the `ContractAddress` of the [Token](#token) +- `owner` - a string containing the address of the owner to mint the tokens for +- `amount` - a integer indicating how many tokens has been minted for the specific id in `TokenProperties` +- `tokenProperties` - the [TokenProperties](02_state.md#tokenproperties) that was just created for the minted tokens + +### TokenTransferredEvent + +Emitted after a successfull `TransferToken` + +```go +type TokenTransferredEvent struct { + Owner string + Recipient string + Tokens []*TokenBatch +} +``` + +The field's descriptions is as follows: + +- `owner` - a string containing the address of the owner the tokens was transferred from +- `recipient` - a string containing the address of the new owner the tokens was transferred to +- `tokens` - a list of [TokenBatch](#tokenbatch). All the tokens that was trasnferred + +### TokenCancelledEvent + +Emitted after a successfull `MsgCancelToken` + +```go +type TokenCancelledEvent struct { + Owner string + Tokens []*TokenBatch +} +``` + +The field's descriptions is as follows: + +- `owner` - a string containing the address of the owner who cancelled the tokens +- `tokens` - a list of [TokenBatch](#tokenbatch). All the tokens that was cancelled + +### TokenRetiredEvent + +Emitted after a successfull `MsgRetireToken` + +```go +type TokenRetiredEvent struct { + Owner string + Tokens []*TokenBatch +} +``` + +The field's descriptions is as follows: + +- `owner` - a string containing the address of the owner who retired the tokens +- `tokens` - a list of [TokenBatch](#tokenbatch). All the tokens that was retired + +### TokenPausedEvent + +Emitted after a successfull `MsgPauseToken` + +```go +type TokenPausedEvent struct { + Minter string + ContractAddress string + Paused bool +} +``` + +The field's descriptions is as follows: + +- `minter` - a string containing the address of the minter +- `contractAddress` - a string containing the contract address +- `paused` - a boolean indicating whether token minting has been temporarily stopped or not, also the field `Paused` on [Token](#token) + +### TokenStoppedEvent + +Emitted after a successfull `MsgStopToken` + +```go +type TokenStoppedEvent struct { + Minter string + ContractAddress string + Stopped bool +} +``` + +The field's descriptions is as follows: + +- `minter` - a string containing the address of the minter +- `contractAddress` - a string containing the contract address +- `stopped` - a boolean indicating whether token minting has been permanently stopped, also the field `Stopped` on [Token](#token) diff --git a/developers/ixo-blockchain/token/spec/05_params.md b/developers/ixo-blockchain/token/spec/05_params.md new file mode 100644 index 0000000..9f3ff51 --- /dev/null +++ b/developers/ixo-blockchain/token/spec/05_params.md @@ -0,0 +1,7 @@ +# Parameters + +The token module contains the following parameter: + +| **Key** | **Type** | **Description** | +| :------------------ | :------- | :------------------------------------------------------------------------------------------------------------------------------------ | +| Ixo1155ContractCode | `uint64` | The contract code for the stored cw1155 smart contract which is used on every token collection creation to instantiate a new contract | diff --git a/developers/ixo-blockchain/token/spec/06_future_improvements.md b/developers/ixo-blockchain/token/spec/06_future_improvements.md new file mode 100644 index 0000000..02b720e --- /dev/null +++ b/developers/ixo-blockchain/token/spec/06_future_improvements.md @@ -0,0 +1,3 @@ +# Future Improvements + +The dynamic world of decentralized finance and token standards presents endless opportunities for refinement. As EIP-1155 and other standards continue to evolve, the `Token` module will align with these advancements, ensuring its continued relevance and utility. We eagerly anticipate community feedback and contributions to ensure that the module meets and exceeds user expectations. diff --git a/developers/ixo-blockchain/token/spec/README.md b/developers/ixo-blockchain/token/spec/README.md new file mode 100644 index 0000000..7bdb988 --- /dev/null +++ b/developers/ixo-blockchain/token/spec/README.md @@ -0,0 +1,68 @@ +# Token module specification + +This document specifies the token module, a custom Ixo Cosmos SDK module. + +Embracing the versatility of the EIP-1155 standard, the Token Module offers a sophisticated mechanism for managing multi-token smart contracts. Whether you're dealing with fungible or non-fungible tokens, this module streamlines the process of creation, minting, and management. From defining token collections to ensuring transparent on-chain token attributes, the Token Module stands as a beacon of efficiency and flexibility in the decentralized token ecosystem. + +## Contents + +1. **[Concepts](01_concepts.md)** + + - [Concepts](01_concepts.md#concepts) + - [EIP-1155 Smart Contract Tokens](01_concepts.md#eip-1155-smart-contract-tokens) + - [Token Module](01_concepts.md#token-module) + - [Concepts](01_concepts.md#concepts-1) + - [Token](01_concepts.md#token) + - [TokenProperties](01_concepts.md#tokenproperties) + - [Features](01_concepts.md#features) + - [1. Token Collection Creation](01_concepts.md#1-token-collection-creation) + - [2. Minting Authorizations](01_concepts.md#2-minting-authorizations) + - [3. Batch Operations](01_concepts.md#3-batch-operations) + - [4. Token Uniqueness and Fungibility](01_concepts.md#4-token-uniqueness-and-fungibility) + - [5. Token Retirement](01_concepts.md#5-token-retirement) + +2. **[State](02_state.md)** + + - [State](02_state.md#state) + - [Tokens](02_state.md#tokens) + - [TokenProperties](02_state.md#tokenproperties) + - [Types](02_state.md#types) + - [Token](02_state.md#token) + - [TokensRetired](02_state.md#tokensretired) + - [TokensCancelled](02_state.md#tokenscancelled) + - [TokenProperties](02_state.md#tokenproperties-1) + - [TokenData](02_state.md#tokendata) + - [Authz Types](02_state.md#authz-types) + - [MintAuthorization](02_state.md#mintauthorization) + - [MintConstraints](02_state.md#mintconstraints) + - + +3. **[Messages](03_messages.md)** + + - [Messages](03_messages.md#messages) + - [MsgCreateToken](03_messages.md#msgcreatetoken) + - [MsgMintToken](03_messages.md#msgminttoken) + - [MsgTransferToken](03_messages.md#msgtransfertoken) + - [MsgRetireToken](03_messages.md#msgretiretoken) + - [MsgCancelToken](03_messages.md#msgcanceltoken) + - [MsgPauseToken](03_messages.md#msgpausetoken) + - [MsgStopToken](03_messages.md#msgstoptoken) + - [Generic types](03_messages.md#generic-types) + - [MintBatch](03_messages.md#mintbatch) + - [TokenBatch](03_messages.md#tokenbatch) + +4. **[Events](04_events.md)** + + - [Events](04_events.md#events) + - [TokenCreatedEvent](04_events.md#tokencreatedevent) + - [TokenUpdatedEvent](04_events.md#tokenupdatedevent) + - [TokenMintedEvent](04_events.md#tokenmintedevent) + - [TokenTransferredEvent](04_events.md#tokentransferredevent) + - [TokenCancelledEvent](04_events.md#tokencancelledevent) + - [TokenRetiredEvent](04_events.md#tokenretiredevent) + - [TokenPausedEvent](04_events.md#tokenpausedevent) + - [TokenStoppedEvent](04_events.md#tokenstoppedevent) + +5. **[Parameters](05_params.md)** + +6. **[Future Improvements](06_future_improvements.md)** diff --git a/developers/ixo-message-relayer/README.md b/developers/ixo-message-relayer/README.md new file mode 100644 index 0000000..0192eb4 --- /dev/null +++ b/developers/ixo-message-relayer/README.md @@ -0,0 +1,409 @@ +
+ +![Logo](/logo.png) + +# Ixo Message Relayer + +![Docker](https://img.shields.io/badge/Docker-2CA5E0?style=for-the-badge&logo=docker&logoColor=white)![NestJS](https://img.shields.io/badge/nestjs-E0234E?style=for-the-badge&logo=nestjs&logoColor=white)![NodeJS](https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white)![Prisma](https://img.shields.io/badge/Prisma-3982CE?style=for-the-badge&logo=Prisma&logoColor=white)![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge&logo=typescript&logoColor=white) + +[![ixo](https://img.shields.io/badge/ixo-project-blue)](https://ixo.foundation) +[![GitHub](https://img.shields.io/github/stars/ixofoundation/jambo?style=social)](https://github.com/ixofoundation/ixo-message-relayer) +![GitHub repo size](https://img.shields.io/github/repo-size/ixofoundation/ixo-message-relayer) +[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/ixofoundation/ixo-message-relayer/blob/main/LICENSE) + +[![Twitter](https://img.shields.io/twitter/follow/ixo_impact?style=social)](https://twitter.com/ixoworld) +[![Medium](https://img.shields.io/badge/Medium-ixo-green)](https://ixoworld.medium.com/) + +
+ +
+ +The Ixo Message Relayer is a server that facilitates a meticulously coordinated sequence of operations ensuring mobile-to-web authentication and transaction signing on the IXO blockchain. The process kicks off with the Login module, where the SDK generates a random hash and a secureHash (which is a SHA-256 hash of the hash and a secureNonce). A QR code, containing this hash, is then displayed for the mobile app to scan. Once scanned, the mobile app uploads the user data to the server using this hash as an identifier of the login request, which the SDK is polling for. This endpoint is secured with an AUTHORIZATION environment variable, ensuring only the mobile app with the correct authorization can upload this data. Subsequently, the SDK polls the server to fetch the login data, providing a secureNonce in the process. The server validates the request by hashing the provided hash and secureNonce to ensure it matches the secureHash, thereby affirming the authenticity of the user making the request. Upon validation, the server returns the login data to the SDK and purges the data from the server to maintain data cleanliness. + +Transitioning to the Transactions module, the SDK creates a transaction request by uploading all the necessary transaction data along with an identifier hash, which is derived from the hash of the transaction data. This hash acts as a unique identifier for the transaction. Upon scanning a QR code generated by the SDK, the mobile app fetches the transaction data from the server using this hash. This endpoint is also protected to ensure only the mobile app can access the transaction data. The mobile app then validates the integrity of the data received from the server by hashing the data and ensuring the hash matches the hash it obtained from the QR code, thereby ensuring data authenticity and thwarting any potential middleman attacks. Following this, the mobile app signs the transaction, broadcasts it to the IXO blockchain, and updates the transaction status on the server, either as success or failure. This update endpoint is also protected to ensure only the mobile app can update the transaction data. Concurrently, the SDK polls the server to fetch the transaction response for the provided hash, allowing it to retrieve the response only for the transaction that was updated by the mobile app. + +The server's response to all endpoints is structured in a consistent format, encapsulated in an object. This object always contains a success field indicating the success or failure of the intended operation. Additionally, there's a data field which generally houses a message field explaining the reason for the success or failure of the request. If there's data to be provided, it is encapsulated within this data field. For the polling endpoints like login fetch and transaction response, there's an additional code field in the response. A code value of 418 signifies that even if the success field is false, the SDK should continue polling and not throw an error, ensuring a robust and resilient flow of operations. + +The server is designed to work seamlessly with a complementary SDK which facilitates the management of various authentication and transaction flows between web clients, mobile applications, and the server itself. For more comprehensive insights and utilization of the server's capabilities, you may explore the SDK source code hosted on [this repository](https://github.com/ixofoundation/ixo-signx) or directly integrate the SDK into your projects via the published [NPM package](https://www.npmjs.com/package/@ixo/signx-sdk). + +## Environment Variables + +Ensuring the secure and efficient operation of the Ixo Message Relayer Nest.js server, various environment variables are configured to govern aspects like authorization, and database management. The `.env.example` file illustrates a templated structure of these variables, providing a guideline for environment setup. + +Here's an overview of each environment variable and its utility within the application: + +- **PORT**: Specifies the port number on which the Nest.js server will run. +- **AUTHORIZATION**: Utilized for authorizing API requests, ensuring they originate from authenticated sources. The Authorization header in API requests must precisely match this value (example: `Bearer u4D81XDt4YsbXo6KSynYFChk`). +- **DATABASE_URL**: The full PostgresQL database uri as provided in example. +- **SENTRY_DSN**: Sentry DNS for Sentry error logging to catch production issues. + +### Security Note + +It is paramount that sensitive variables such as AUTHORIZATION and DATABASE_URL are secured and not exposed to unauthorized personnel or systems. Employ stringent security practices like utilizing secrets management tools, employing strict access controls, and conducting periodic security audits to ensure the confidentiality and integrity of these critical data points. + +### Usage Note + +To implement these configurations, developers need to create an `.env` file, using `.env.example` as a template, and supply the appropriate values for each variable, ensuring the secure and tailored operation of the server based on the specific deployment environment and use case. + +This environment configuration section can serve as a guide to developers, system administrators, and other stakeholders involved in the deployment and maintenance of the server, providing a structured view of the configurable elements that dictate the serverโ€™s functionality and security. + +## Running the app + +```bash +# Clone the repository +$ git clone https://github.com/ixofoundation/ixo-message-relayer.git +# Navigate to the project directory +$ cd ixo-message-relayer + +# Install dependancies +$ yarn install + +# development +$ yarn run start + +# watch mode +$ yarn run start:dev + +# production mode +$ yarn run start:prod +``` + +## Docker Usage + +If you prefer to run the application inside a Docker container, we've provided a Docker image for convenience. The image is available at `ghcr.io/ixofoundation/ixo-message-relayer:v0.0.1` and an example docker-compose file is below for reference: + +### docker-compose.yaml + +```yaml +version: '3.7' +services: + ixo-message-relayer: + container_name: ixo-message-relayer + image: ghcr.io/ixofoundation/ixo-message-relayer:v0.0.1 + build: + context: . + dockerfile: Dockerfile + # Can use a .env file + env_file: .env + restart: always + ports: + - 3000:3000 + logging: + driver: 'json-file' + options: + max-size: '1m' + max-file: '1' + depends_on: + - ixo-message-relayer-db + + ixo-message-relayer-db: + container_name: ixo-message-relayer-db + image: postgres:15.1 + restart: always + environment: + - POSTGRES_DB=message-relayer + - POSTGRES_PASSWORD=pass + ports: + - 5432:5432 + volumes: + - ./data/db:/var/lib/postgresql/data + - ./prisma/migrations/20230301091449_init/:/docker-entrypoint-initdb.d/ +``` + +## API Documentation + +### POST `/login/create` + +This endpoint is utilized by the mobile app to store login request data on the server. Upon scanning a QR code generated by the SDK, the mobile app initiates a login request by sending the relevant data to this endpoint. The login data is stored on the server under a unique hash identifier generated by the SDK, which facilitates subsequent polling by the SDK to retrieve this data for user login. The endpoint is protected by an authorization mechanism to ensure that only the mobile app can upload login data. + +#### Parameters + +- `hash`: A unique identifier for the login request. +- `secureHash`: A secure hash generated by hashing the `hash` and a `secureNonce`. +- `data`: The login request data. +- `success`: A boolean indicating the success status of the login request. + +#### Request Body + +```json +{ + "hash": "string", + "secureHash": "string", + "data": "object", + "success": "boolean" +} +``` + +#### Response Body + +```json +{ + "success": "boolean", + "data": { + "message": "string" + } +} +``` + +#### Response Properties + +- **success**: Indicates whether the request to server was successful. +- **data**: + - **message**: A message explaining the success or failure of the request. + +#### Usage + +```bash +curl -X POST https://[server-address]/login/create \ +-H "Content-Type: application/json" \ +-d '{"hash": "uniqueHash", "secureHash": "secureHashValue", "data": { ... }, "success": true}' +``` + +### POST `/login/fetch` + +This endpoint facilitates the retrieval of login request data that was previously stored on the server by the mobile app. The SDK polls this endpoint to fetch the login data for a user based on a unique hash identifier. The server validates the request by hashing the provided hash and a secureNonce to ensure it matches the stored secureHash, thereby affirming the authenticity of the user making the request. Upon validation, the server returns the login data to the SDK and deletes the data from the server to maintain data cleanliness. + +#### Parameters + +- `hash`: A unique identifier for the login request. +- `secureNonce`: A secure nonce generated by the SDK. + +#### Request Body + +```json +{ + "hash": "string", + "secureNonce": "string" +} +``` + +#### Response Body + +```json +{ + "success": "boolean", + "data": { + "message": "string", + "data": "object", + "success": "boolean" + }, + "code": "number" +} +``` + +#### Response Properties + +- **success**: Indicates whether the request to server was successful. +- **code**: A code indicating whether the SDK should continue polling (418 if it should continue). +- **data**: + - **message**: A message explaining the success or failure of the request. + - **data**: The login data + - **success**: Wether the login was a sucess or fail due to rejection on mobile for example + +#### Usage + +```bash +curl -X POST https://[server-address]/login/fetch \ +-H "Content-Type: application/json" \ +-d '{"hash": "uniqueHash", "secureNonce": "secureNonceValue"}' +``` + +### POST `/transaction/create` + +This endpoint is utilized by the SDK to store transaction request data on the server. The SDK initiates a transaction request by sending the relevant data, along with a unique hash identifier (which is also the hash of the transaction data), to this endpoint. This hash facilitates subsequent retrieval of this data by the mobile app for signing and broadcasting the transaction. The endpoint validates the request by hashing the provided transaction data and ensuring it matches the provided hash, thereby affirming the authenticity of the transaction data. + +#### Parameters + +- `hash`: A unique identifier for the transaction request which is also the hash of the transaction data. +- `address`: The address involved in the transaction. +- `did`: The decentralized identifier involved in the transaction. +- `pubkey`: The public key of the user initiating the transaction. +- `txBodyHex`: The hexadecimal encoded raw txBodyBytes which can be encoded from the registry exported from @ixo/impactxclient-sdk npm package (eg registry.encodeTxBody({ messages, memo })) +- `timestamp`: The stringified utc DateTime, add uniqueness for tx hash to prevent duplicates (eg new Date().toISOString()) + +#### Request Body + +```json +{ + "hash": "string", + "address": "string", + "did": "string", + "pubkey": "string", + "txBodyHex": "string", + "timestamp": "string" +} +``` + +#### Response Body + +```json +{ + "success": "boolean", + "data": { + "message": "string", + "validUntil": "string" + } +} +``` + +#### Response Properties + +- **success**: Indicates whether the request to server was successful. +- **data**: + - **message**: A message explaining the success or failure of the request. + - **validUntil**: The ISO 8601 formatted datetime string indicating the expiry time of the transaction request + +#### Usage + +```bash +curl -X POST https://[server-address]/transaction/create \ +-H "Content-Type: application/json" \ +-d '{"hash": "uniqueHash", "address": "userAddress", "did": "userDid", "pubkey": "userPubKey", "txBodyHex": "transactionBodyHex", "timestamp": "transactionTimestamp"}' +``` + +### POST `/transaction/fetch` + +This endpoint allows the mobile app to fetch the data of a specific transaction request based on a unique hash identifier. After scanning the QR code displayed by the SDK, the mobile app uses the hash to retrieve the transaction data from this endpoint for signing and broadcasting the transaction. The endpoint is protected to ensure only the mobile app can access the transaction data, and it validates the request by checking the hash against the stored transaction data to ensure data authenticity. + +#### Parameters + +- `hash`: A unique identifier for the transaction request. + +#### Request Body + +```json +{ + "hash": "string" +} +``` + +#### Response Body + +```json +{ + "success": "boolean", + "data": { + "message": "string", + "address": "string", + "did": "string", + "pubkey": "string", + "txBodyHex": "string", + "timestamp": "string" + } +} +``` + +#### Response Properties + +- **success**: Indicates whether the request to server was successful. +- **data**: + - **message**: A message explaining the success or failure of the request. + - **address**: The address involved in the transaction. + - **did**: The decentralized identifier involved in the transaction. + - **pubkey**: The public key of the user initiating the transaction. + - **txBodyHex**: The hexadecimal representation of the raw encoded transaction body. + - **timestamp**: The The ISO 8601 formatted timestamp when the transaction request was created. + +#### Usage + +```bash +curl -X POST https://[server-address]/transaction/fetch \ +-H "Content-Type: application/json" \ +-d '{"hash": "uniqueHash"}' +``` + +### POST `/transaction/update` + +This endpoint is leveraged by the mobile app to update a transaction request's data on the server following the signing and broadcasting of the transaction. The mobile app sends the transaction response data to this endpoint, which then updates the corresponding transaction request record on the server. The endpoint is protected to ensure only the mobile app can update the transaction data. + +#### Parameters + +- `hash`: A unique identifier for the transaction request. +- `data`: The response data of the transaction. +- `success`: A boolean indicating whether the transaction was successful or failed. + +#### Request Body + +```json +{ + "hash": "string", + "data": "string", + "success": "boolean" +} +``` + +#### Response Body + +```json +{ + "success": "boolean", + "data": { + "message": "string" + } +} +``` + +#### Response Properties + +- **success**: Indicates whether the request to server was successful. +- **data**: + - **message**: A message explaining the success or failure of the request. + +#### Usage + +```bash +curl -X POST https://[server-address]/transaction/update \ +-H "Content-Type: application/json" \ +-d '{"hash": "uniqueHash", "data": "transactionResponseData", "success": true}' +``` + +### POST `/transaction/response` + +This endpoint is utilized by the SDK to poll the server for a response to a specific transaction request. By providing the unique hash identifier for the transaction, the SDK can retrieve the response data updated by the mobile app. This endpoint facilitates the flow where after the mobile app signs and broadcasts the transaction, and updates the server with the response data, the SDK polls this endpoint to obtain the response. + +#### Parameters + +- `hash`: A unique identifier for the transaction request. + +#### Request Body + +```json +{ + "hash": "string" +} +``` + +#### Response Body + +```json +{ + "success": "boolean", + "code": "number", + "data": { + "message": "string", + "data": "string", + "success": "boolean" + } +} +``` + +#### Response Properties + +- **success**: Indicates whether the request to server was successful. +- **code**: A code indicating whether the SDK should continue polling (418 if it should continue). +- **data**: + - **message**: A message explaining the success or failure of the request. + - **data**: The response data of the transaction. + - **success**: Whether the transaction was a success or fail due to rejection on mobile for example. + +#### Usage + +```bash +curl -X POST https://[server-address]/transaction/response \ +-H "Content-Type: application/json" \ +-d '{"hash": "uniqueHash"}' +``` + +## ๐Ÿ“ƒ License + +This SDK is licensed under the Apache 2 License. See the [LICENSE](/LICENSE) file for more information. diff --git a/developers/ixo-signx/README.md b/developers/ixo-signx/README.md new file mode 100644 index 0000000..3dad697 --- /dev/null +++ b/developers/ixo-signx/README.md @@ -0,0 +1,321 @@ +# SignX SDK + +[![ixo](https://img.shields.io/badge/ixo-project-blue)](https://ixo.foundation) +[![GitHub](https://img.shields.io/github/stars/ixofoundation/jambo?style=social)](https://github.com/ixofoundation/ixo-signx) +![GitHub repo size](https://img.shields.io/github/repo-size/ixofoundation/ixo-signx) +[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/ixofoundation/ixo-signx/blob/main/LICENSE) + +[![Twitter](https://img.shields.io/twitter/follow/ixo_impact?style=social)](https://twitter.com/ixoworld) +[![Medium](https://img.shields.io/badge/Medium-ixo-green)](https://ixoworld.medium.com/) + +![NodeJS](https://img.shields.io/badge/node.js-6DA55F?style=for-the-badge&logo=node.js&logoColor=white)![TypeScript](https://img.shields.io/badge/typescript-%23007ACC.svg?style=for-the-badge&logo=typescript&logoColor=white) + +

+ +

+ +
+ +The SignX SDK provides an easy way to integrate mobile-to-web authentication and transaction signing using the IXO blockchain in your applications. + +This repo and product is intentionally managed as Open Source and we aim to use this guide to light our way https://opensource.guide/. +Let us know how we are doing! + +## ๐Ÿ“ Description + +The SignX SDK orchestrates a seamless and secure interaction between client applications, a mobile app, and a server, encapsulating the complexities of mobile-to-web authentication and transaction signing on the IXO blockchain. The flow is initiated when a client application triggers a login request through the SDK, which in turn generates a unique identifier and a secure hash. This information is encoded into a QR code that is displayed to the user. Upon scanning this QR code with the mobile app, the user's account details are securely transmitted to the server. + +During this phase, the SDK engages in a polling mechanism, continually checking the server for the authentication response corresponding to the QR code data. This ensures that the client application is updated in near real-time once the user has completed the scanning process. The SDK has built-in error handling and timeout features to manage scenarios where the response from the server is delayed or unsuccessful. Upon receiving a successful response from the server, the SDK triggers an event notifying the client application of the successful login, and provides the user's account details for further interactions. + +With the user now authenticated, the SDK facilitates transaction operations. When a transaction is initiated through the SDK, it packages the necessary transaction data and securely transmits this, along with a unique transaction hash, to the server. Similar to the login flow, a QR code is generated for the user to scan using the mobile app. This QR code encodes information required for the mobile app to retrieve the transaction data from the server, sign the transaction, and broadcast it to the IXO blockchain. + +Post the QR code generation, the SDK re-engages its polling mechanism, constantly checking the server for updates regarding the transaction status. The mobile app, after broadcasting the transaction, uploads the transaction response to the server. Once the server processes this response, it updates the transaction status which is then picked up by the SDK in one of its polling iterations. Upon receiving a successful or failed transaction response, the SDK emits an event to inform the client application of the outcome, thus completing the transaction flow. + +Through this orchestrated flow, the SignX SDK abstracts the technical intricacies, providing a straightforward and secure way for client applications to leverage mobile-to-web authentication and transaction signing on the IXO blockchain. + +The SDK is crafted to interact harmoniously with a designated server, which handles the storage and provides the necessary endpoints for polling data during the authentication and transaction processes. To fully leverage the SDK's capabilities and ensure a streamlined operation, it is essential to set up and utilize the accompanying server, the source code for which can be found [here](https://github.com/ixofoundation/ixo-message-relayer). + +## ๐Ÿ”จ Install + +```sh +npm install @ixo/signx-sdk + +yarn add @ixo/signx-sdk +``` + +## ๐Ÿ’ป Usage + +This SDK exposes a client class SignX which can be instantiated in your client applications to interact with the SignX server and mobile app for various operations. + +Import and initialize the SignX client in your application: + +```js +import { SignX } from '@ixo/signx-sdk'; + +const signXClient = new SignX({ + endpoint: 'https://your-signx-server.com', + sitename: 'YourSiteName', + network: 'mainnet', +}); +``` + +### Login + +Initiate a login request using the `login` method: + +```js +const loginRequest = await signXClient.login(); + +// Use loginRequest data to show QR code to user for scanning by mobile app +``` + +Subscribe to events for success or failure [here](#event-handling) + +### Transacting + +Initiate a transaction using the `transact` method: + +```js +const transactRequest = await signXClient.transact(TRANSACT_DTO); + +// Use transactRequest data to show QR code to user for scanning by mobile app +``` + +Subscribe to events for success or failure [here](#event-handling). TRANSACT_DTO type can be seen [here](#types) + +### Event Handling + +Listen for success and error events emitted by the SignX client: + +```js +signXClient.on(SIGN_X_LOGIN_SUCCESS, data => { + console.log('Login Success:', data); +}); + +signXClient.on(SIGN_X_LOGIN_ERROR, error => { + console.error('Login Error:', error); +}); + +signXClient.on(SIGN_X_TRANSACT_SUCCESS, data => { + console.log('Transaction Success:', data); +}); + +signXClient.on(SIGN_X_TRANSACT_ERROR, error => { + console.error('Transaction Error:', error); +}); +``` + +## ๐Ÿ“Ž Utility Functions + +### hashTransactData + +Hashes transaction data for use in the transact method: + +```js +// hashTransactData(data: TRANSACT_DTO): string +const hash = hashTransactData(transactData); +``` + +### generateSecureHash + +Generates a secure hash from a given hash and nonce: + +```js +// generateSecureHash(hash: string, nonce: string): string +const secureHash = generateSecureHash(hash, nonce); +``` + +## ๐Ÿ–‡๏ธ API Reference + +### Types + +- NETWORK: The network type: + ```js + type NETWORK = 'mainnet' | 'testnet' | 'devnet'; + ``` +- TRANSACT_DTO: The data transfer object for transactions: + ```js + type TRANSACT_DTO = { + address: string, // bech32 encoded address, as received from login (eg ixo123) + did: string, // base64 encoded did, as received from login (eg did:x:1234) + pubkey: string, // hex encoded pubkey, as receivced from login + txBodyHex: string, // hex encoded raw txBodyBytes which can be encoded from the registry exported from @ixo/impactxclient-sdk npm package (eg registry.encodeTxBody({ messages, memo })) + timestamp: string, // stringified utc DateTime, add uniqueness for tx hash to prevent duplicates (eg new Date().toISOString()) + }; + ``` + +### Class SignX + +#### Properties + +- timeout: The timeout for polling in milliseconds (default is 2 minutes). +- pollingInterval: The interval between polling requests in milliseconds (default is 2.5 seconds). +- network: The network type. +- endpoint: The endpoint URL of the SignX server. +- sitename: The name of your site. (shown on mobile app on request) + +#### Methods + +- login: Initiates a login request and starts polling. +- transact: Initiates a transaction and starts polling. +- stopPolling: Stops the polling process. + +## ๐Ÿ“ฑ Examples + +Example used in a React project: + +```js +let signXClient: SignX; + +let signXInitializing = false; +export const initializeSignX = async ( + chainInfo: KEPLR_CHAIN_INFO_TYPE, + walletUser?: USER, +): Promise => { + if (signXInitializing) return; + signXInitializing = true; + + let handleClose: () => void; + try { + if (!chainInfo || !chainInfo.chainId) throw new Error('No chain info found to initialize SignX'); + if (chainInfo.chainName !== 'ixo') throw new Error('SignX only works on ixo chain'); + + signXClient = new SignX({ + endpoint: 'https://signx.devnet.ixo.earth', + network: chainInfo.chainNetwork || 'mainnet', + sitename: config.siteName ?? 'JAMBO dApp', + }); + + // if user already has an address or pubkey(already signed in), return + if (walletUser?.address || walletUser?.pubKey) return walletUser; + + // get login data from client to display QR code and start polling + const data = await signXClient.login({ pollingInterval: 2000 }); + + const closeModal = () => { + signXClient.off(SIGN_X_LOGIN_ERROR, () => {}); + signXClient.off(SIGN_X_LOGIN_SUCCESS, () => {}); + signXClient.stopPolling('Login cancelled', SIGN_X_LOGIN_ERROR); + }; + + handleClose = renderModal( + , + closeModal, + ); + + const eventData: any = await new Promise((resolve, reject) => { + const handleSuccess = (data: any) => { + signXClient.off(SIGN_X_LOGIN_ERROR, handleError); // Remove error listener once successful + resolve(data); + }; + const handleError = (error: any) => { + signXClient.off(SIGN_X_LOGIN_SUCCESS, handleSuccess); // Remove success listener on error + reject(error); + }; + + signXClient.on(SIGN_X_LOGIN_SUCCESS, handleSuccess); + signXClient.on(SIGN_X_LOGIN_ERROR, handleError); + }); + handleClose(); // manually close the modal after event emitted + + return { + name: eventData.data.name, + address: eventData.data.address, + pubKey: fromHex(eventData.data.pubKey), + did: eventData.data.did, + algo: eventData.data.algo, + }; + } catch (e) { + console.error('ERROR::initializeSignX::', e); + // handle error like sign out of wallet + const event = new Event(EVENT_LISTENER_TYPE.wallet_logout); + window.dispatchEvent(event); + } finally { + signXInitializing = false; + if (handleClose) handleClose(); + } +}; + +let signXBroadCastMessageBusy = false; +export const signXBroadCastMessage = async ( + msgs: TRX_MSG[], + memo = '', + chainInfo: KEPLR_CHAIN_INFO_TYPE, + wallet: WALLET, +): Promise => { + if (signXBroadCastMessageBusy) return null; + signXBroadCastMessageBusy = true; + + let handleClose: () => void; + try { + if (!chainInfo || !chainInfo.chainId) throw new Error('No chain info found'); + if (chainInfo.chainName !== 'ixo') throw new Error('SignX only works on ixo chain'); + + if (!wallet.user) throw new Error('No user found to broadcast transaction'); + if (!signXClient) throw new Error('No signXClient found to broadcast transaction'); + + const registry = createRegistry(); + + // get login data from client to display QR code and start polling + const data = await signXClient.transact({ + address: wallet.user.address, + did: wallet.user.did!, + pubkey: toHex(wallet.user.pubKey), + timestamp: new Date().toISOString(), + txBodyHex: toHex(registry.encodeTxBody({ messages: msgs as any, memo })), + }); + + const closeModal = () => { + signXClient.off(SIGN_X_TRANSACT_ERROR, () => {}); + signXClient.off(SIGN_X_TRANSACT_SUCCESS, () => {}); + signXClient.stopPolling('Transaction cancelled', SIGN_X_TRANSACT_ERROR); + }; + + handleClose = renderModal( + , + closeModal, + ); + + const eventData: any = await new Promise((resolve, reject) => { + const handleSuccess = (data: any) => { + signXClient.off(SIGN_X_TRANSACT_ERROR, handleError); // Remove error listener once successful + resolve(data); + }; + const handleError = (error: any) => { + signXClient.off(SIGN_X_TRANSACT_SUCCESS, handleSuccess); // Remove success listener on error + reject(error); + }; + + signXClient.on(SIGN_X_TRANSACT_SUCCESS, handleSuccess); + signXClient.on(SIGN_X_TRANSACT_ERROR, handleError); + }); + handleClose(); // manually close the modal after event emitted + + console.log({ eventData }); + + return eventData.data?.transactionHash; + } catch (e) { + console.error('ERROR::signXBroadCastMessage::', e); + Toast.errorToast(`Transaction Failed`); + return null; + } finally { + signXBroadCastMessageBusy = false; + if (handleClose) handleClose(); + } +}; + +``` + +## ๐Ÿ“ƒ License + +This SDK is licensed under the Apache 2 License. See the [LICENSE](/LICENSE) file for more information. diff --git a/ixo-blockchain b/ixo-blockchain new file mode 160000 index 0000000..f4193c3 --- /dev/null +++ b/ixo-blockchain @@ -0,0 +1 @@ +Subproject commit f4193c31eb73851aec7be091f2845183f2dd0c61 diff --git a/ixo-message-relayer b/ixo-message-relayer new file mode 160000 index 0000000..3e56a68 --- /dev/null +++ b/ixo-message-relayer @@ -0,0 +1 @@ +Subproject commit 3e56a6875c62546609ad819f79c555614acae386 diff --git a/ixo-signx b/ixo-signx new file mode 160000 index 0000000..e8a3967 --- /dev/null +++ b/ixo-signx @@ -0,0 +1 @@ +Subproject commit e8a396724a19b3389cea1bb340f4a2f11d0e7056 From 87dd82417d8067da8c70f01d91ac437983a7b8e2 Mon Sep 17 00:00:00 2001 From: Alwyn van Wyk Date: Sat, 4 Nov 2023 14:33:07 +0000 Subject: [PATCH 5/7] Update pull-docs.yml --- .github/workflows/pull-docs.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pull-docs.yml b/.github/workflows/pull-docs.yml index c9bf7b0..95f16bf 100644 --- a/.github/workflows/pull-docs.yml +++ b/.github/workflows/pull-docs.yml @@ -1,4 +1,4 @@ -name: Copy .md from ixo-blockchain +name: Copy docs from other repositories. run-name: ${{ github.actor }} pushed a change. on: [push] jobs: @@ -49,9 +49,9 @@ jobs: - run: mkdir -p ./developers/ixo-message-relayer - run: find ./ixo-message-relayer -type f -name "*.md" -exec cp -R {} ./developers/ixo-message-relayer \; - # - run: rm -R ./ixo-blockchain - # - run: rm -R ./ixo-signx - # - run: rm -R ./ixo-message-relayer + - run: rm -R ./ixo-blockchain + - run: rm -R ./ixo-signx + - run: rm -R ./ixo-message-relayer - run: git add . - run: git config --global user.email "ixo@ixo.world" From da4d57f7214aaae1bc7d5da657667beefe17b77c Mon Sep 17 00:00:00 2001 From: alwyn-ixo Date: Sat, 4 Nov 2023 14:33:22 +0000 Subject: [PATCH 6/7] Copy *.md files from other repos --- ixo-blockchain | 1 - ixo-message-relayer | 1 - ixo-signx | 1 - 3 files changed, 3 deletions(-) delete mode 160000 ixo-blockchain delete mode 160000 ixo-message-relayer delete mode 160000 ixo-signx diff --git a/ixo-blockchain b/ixo-blockchain deleted file mode 160000 index f4193c3..0000000 --- a/ixo-blockchain +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f4193c31eb73851aec7be091f2845183f2dd0c61 diff --git a/ixo-message-relayer b/ixo-message-relayer deleted file mode 160000 index 3e56a68..0000000 --- a/ixo-message-relayer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 3e56a6875c62546609ad819f79c555614acae386 diff --git a/ixo-signx b/ixo-signx deleted file mode 160000 index e8a3967..0000000 --- a/ixo-signx +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e8a396724a19b3389cea1bb340f4a2f11d0e7056 From cd7f0aa4913c5d0c9f81b38b39edcde9bbcfe0ba Mon Sep 17 00:00:00 2001 From: Alwyn van Wyk Date: Sat, 4 Nov 2023 14:40:24 +0000 Subject: [PATCH 7/7] Update pull-docs.yml --- .github/workflows/pull-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-docs.yml b/.github/workflows/pull-docs.yml index 95f16bf..6840062 100644 --- a/.github/workflows/pull-docs.yml +++ b/.github/workflows/pull-docs.yml @@ -2,7 +2,7 @@ name: Copy docs from other repositories. run-name: ${{ github.actor }} pushed a change. on: [push] jobs: - copy-docs-from-blockchain-repo: + copy-docs-from-other-repos: runs-on: ubuntu-latest steps: - name: Checkout