diff --git a/.codex/UPGRADE_BACKLOG.md b/.codex/UPGRADE_BACKLOG.md index 77b9860..03c88ba 100644 --- a/.codex/UPGRADE_BACKLOG.md +++ b/.codex/UPGRADE_BACKLOG.md @@ -212,6 +212,31 @@ Use checkboxes to track completion. Keep task summaries short and file-specific. - Done when: - each major concept has one canonical home +## Developer guides audit — Apr 2026 + +Source: `~/.cursor/plans/developer_guides_audit_b84f6fcb.plan.md` + +This audit reviewed every page under `guides/dev/` for duplication, broken or invented APIs, missing task scaffolding, and IA orphans. The bulk has been implemented. Items below are residual. + +### Decisions (recorded for future contributors) + +- `guides/dev/evaluation-engine.mdx` — DELETED (was empty); redirect to `/guides/dev/agent-evaluations` lives in `docs.json`. +- `guides/dev/claims.mdx` — DELETED (invented message names and superseded by `ixo-claims.mdx`); redirect in place. +- `guides/dev/introduction.mdx` — DELETED (duplicated `overview.mdx` with non-functional cards); redirect in place. +- `guides/dev/identity-and-credentials.mdx` — MOVED to `articles/identity-and-credentials.mdx` per `CONTENT_MODEL_AND_IA.md` (concept article belongs in `articles/`); redirect in place; all internal links updated. +- `guides/dev/ixo-domains.mdx` — KEPT as a routing page accessible by URL but **intentionally absent from nav**; many concept pages link to it (glossary, core-concepts, articles/cdt-systems, articles/assets, articles/domain-config). Adding it to nav would duplicate `overview.mdx`. +- `guides/dev/ixo-stack-sdks.mdx` — REDUCED to a short pointer page; kept in nav for redirect compatibility (`/guides/dev/spatial-web-sdks` → here). +- All canonical chain message shapes (entities, tokens, bonds, liquid-staking, smart accounts, claims, authz) — VERIFIED against `ixofoundation/ixo-blockchain` proto files. `MsgSendWithAuthenticator` and `MsgSubmitProposalUpdateLiquidStakeParams` confirmed as not existing — replaced with the `AuthenticatorTxExtension` pattern and the standard Cosmos `MsgSubmitProposal` wrapping. +- `@ixo/oracle-agent-sdk` snippets — flagged as illustrative; npm package is not publicly published. Canonical home is `sdk-reference/oracle-adk.mdx`. + +### Residual / follow-up + +- [ ] Confirm the canonical npm slug for the Oracle ADK once the package is published; replace the illustrative snippets in `guides/dev/workflows.mdx` and `guides/dev/examples.mdx` with verified API calls. +- [ ] Decide whether `guides/dev/ixo-stack-sdks.mdx` should be folded into `guides/dev/overview.mdx` and replaced with a redirect (currently kept as a thin pointer for backward compatibility). +- [ ] When Mintlify nested-group nav is reviewed, validate the new sub-groups under Developer Guides (Identity and access, Domains and entities, Claims and verification, Tokens and bonds, Channels and integrations, Operate) — adjust labels if site analytics show consistent mismatch. +- [ ] Cross-check the verified message shapes after every IXO blockchain release; update `tokens.mdx`, `bonds.mdx`, `liquid-staking.mdx`, `smart-accounts.mdx`, `entities.mdx` if proto signatures change. +- [ ] Consider creating `reference/oracle-adk-status.mdx` with the public availability matrix so guides can defer instead of re-explaining. + ## Phase 6 — Editorial polish and QA - [ ] Run a repo-wide grammar and formatting cleanup after structural fixes. diff --git a/.codex/templates/guide-page-template.mdx b/.codex/templates/guide-page-template.mdx index fa44ff7..4b9581b 100644 --- a/.codex/templates/guide-page-template.mdx +++ b/.codex/templates/guide-page-template.mdx @@ -54,6 +54,14 @@ Describe the symptom, likely cause, and fix. ## Next steps -- Link to the relevant reference page -- Link to the next guide -- Link to the canonical product overview + + + Link to the reference surface users need after this guide. + + + Link to the most logical follow-on implementation guide. + + + Link to the canonical product or platform overview page. + + diff --git a/.codex/templates/product-overview-template.mdx b/.codex/templates/product-overview-template.mdx index c433ad3..903c441 100644 --- a/.codex/templates/product-overview-template.mdx +++ b/.codex/templates/product-overview-template.mdx @@ -1,6 +1,6 @@ --- -title: "" -description: "" +title: "Canonical product or SDK name" +description: "One-sentence description of what this surface is and when to use it." --- ## What it is @@ -58,5 +58,11 @@ npm install ## Next steps -- The most important guide -- The most important reference page + + + Link the highest-priority implementation guide for this product. + + + Link the key reference page users need for technical integration. + + diff --git a/guides/dev/identity-and-credentials.mdx b/articles/identity-and-credentials.mdx similarity index 87% rename from guides/dev/identity-and-credentials.mdx rename to articles/identity-and-credentials.mdx index 6150e83..001d17e 100644 --- a/guides/dev/identity-and-credentials.mdx +++ b/articles/identity-and-credentials.mdx @@ -26,7 +26,7 @@ This page ties together concepts that are also described on the [Emerging digita - The entity a statement is **about**. In a verifiable credential, the **credential subject** is identified by a DID (often the holder’s DID). + The entity a statement is **about**. In a verifiable credential, the **credential subject** is identified by a DID (often the holder's DID). @@ -34,7 +34,7 @@ This page ties together concepts that are also described on the [Emerging digita - A tamper-evident, issuer-signed bundle of claims about a subject, usable by **verifiers** without trusting only the holder’s copy. Status and revocation may be checked against registry or service endpoints. + A tamper-evident, issuer-signed bundle of claims about a subject, usable by **verifiers** without trusting only the holder's copy. Status and revocation may be checked against registry or service endpoints. @@ -55,7 +55,7 @@ This page ties together concepts that are also described on the [Emerging digita 1. **Register identity** — Create or obtain a DID and domain record so the entity exists in the shared model ([digital twins](/guides/digital-twins), [domain registration](/guides/domain-registration)). 2. **Submit a claim** — Assert something about that entity with evidence and context ([claims](/guides/dev/ixo-claims)). 3. **Validate / evaluate** — Humans, services, or Agentic Oracles check the claim against program rules; outcomes may be recorded on-chain or in linked services. -4. **Issue a VC** — After validation, an issuer may bind selected assertions into a verifiable credential whose **subject** is the holder’s DID ([credential issuance](/platforms/Emerging/credential-issuance)). +4. **Issue a VC** — After validation, an issuer may bind selected assertions into a verifiable credential whose **subject** is the holder's DID ([credential issuance](/platforms/Emerging/credential-issuance)). 5. **Verify or revoke** — Verifiers check proofs and status; issuers or governance may revoke or supersede credentials when state changes. ## How the pieces relate @@ -98,6 +98,14 @@ flowchart TB ## See also -- [Core concepts](/core-concepts) — vocabulary for domains, PODs, cooperation, and Qi -- [Glossary](/reference/glossary) — short definitions with links -- [Authentication](/guides/dev/authentication) — credentials and session patterns for developers + + + Vocabulary for domains, PODs, cooperation, and Qi. + + + Short definitions with links to deeper pages. + + + Credentials and session patterns for developers. + + diff --git a/core-concepts.mdx b/core-concepts.mdx index 952561f..3a2124d 100644 --- a/core-concepts.mdx +++ b/core-concepts.mdx @@ -5,7 +5,7 @@ description: "Vocabulary and mental models for IXO, Qi, entities, claims, eviden --- - This page is **definitions and structure**: what words mean and how layers fit together. For motivation, positioning, and a short worked example, read [Act on Reality](/introduction) first. When you are ready to pick a first artifact (POD, Flow, Blueprint, and so on), use [What you can build](/guides/what-you-can-build). For DIDs, claims, and verifiable credentials in one place, read [Identity and credentials](/guides/dev/identity-and-credentials). For quick term lookup, use the [Glossary](/reference/glossary). + This page is **definitions and structure**: what words mean and how layers fit together. For motivation, positioning, and a short worked example, read [Act on Reality](/introduction) first. When you are ready to pick a first artifact (POD, Flow, Blueprint, and so on), use [What you can build](/guides/what-you-can-build). For DIDs, claims, and verifiable credentials in one place, read [Identity and credentials](/articles/identity-and-credentials). For quick term lookup, use the [Glossary](/reference/glossary). ## The problem space diff --git a/docs.json b/docs.json index 94de638..864a7fc 100644 --- a/docs.json +++ b/docs.json @@ -79,18 +79,59 @@ "guides/dev/overview", "guides/dev/ixo-stack-sdks", "guides/dev/workflows", - "mcp/model-context-protocol", - "guides/dev/ussd-gateway", - "guides/dev/authentication", - "guides/dev/identity-and-credentials", - "guides/dev/ixo-claims", - "guides/digital-twins", - "guides/domain-registration", - "guides/dev/domain-settings", - "guides/dev/domain-privacy", - "guides/digital-mrv", - "guides/registry", - "guides/ixo-oracles-architecture" + "guides/dev/examples", + { + "group": "Identity and access", + "pages": [ + "guides/dev/authentication", + "articles/identity-and-credentials", + "guides/dev/session-keys", + "guides/dev/smart-accounts", + "guides/dev/authz", + "guides/dev/authz-custom" + ] + }, + { + "group": "Domains and entities", + "pages": [ + "guides/digital-twins", + "guides/dev/entities", + "guides/domain-registration", + "guides/dev/domain-settings", + "guides/dev/domain-privacy" + ] + }, + { + "group": "Claims and verification", + "pages": [ + "guides/dev/ixo-claims", + "guides/dev/agent-evaluations", + "guides/digital-mrv" + ] + }, + { + "group": "Tokens and bonds", + "pages": [ + "guides/dev/tokens", + "guides/dev/bonds", + "guides/dev/liquid-staking" + ] + }, + { + "group": "Channels and integrations", + "pages": [ + "mcp/model-context-protocol", + "guides/dev/ussd-gateway", + "guides/dev/image-handling" + ] + }, + { + "group": "Operate", + "pages": [ + "guides/registry", + "guides/ixo-oracles-architecture" + ] + } ] } ] @@ -159,6 +200,22 @@ "source": "/guides/dev/spatial-web-sdks", "destination": "/guides/dev/ixo-stack-sdks" }, + { + "source": "/guides/dev/introduction", + "destination": "/guides/dev/overview" + }, + { + "source": "/guides/dev/identity-and-credentials", + "destination": "/articles/identity-and-credentials" + }, + { + "source": "/guides/dev/evaluation-engine", + "destination": "/guides/dev/agent-evaluations" + }, + { + "source": "/guides/dev/claims", + "destination": "/guides/dev/ixo-claims" + }, { "source": "/sdk-reference/oracle-ai-sdk", "destination": "/sdk-reference/oracle-adk" diff --git a/guides/dev/authentication.mdx b/guides/dev/authentication.mdx index 010f29a..a70a789 100644 --- a/guides/dev/authentication.mdx +++ b/guides/dev/authentication.mdx @@ -53,6 +53,14 @@ The surface-level rate policy has been exceeded. Apply retry/backoff per API gui ## Next steps -- API authentication reference: `/api-reference/authentication` -- Networks and endpoints: `/reference/networks-and-endpoints` -- Product and SDK map: `/reference/product-and-sdk-map` + + + Apply endpoint-specific authentication requirements and headers. + + + Select chain IDs and base URLs for your environment. + + + Confirm canonical product names, SDK names, and routes. + + diff --git a/guides/dev/authz-custom.mdx b/guides/dev/authz-custom.mdx index 22e527e..e490d0b 100644 --- a/guides/dev/authz-custom.mdx +++ b/guides/dev/authz-custom.mdx @@ -84,5 +84,5 @@ Custom authorizations in IXO use lists for constraints because there can only be ## Related Resources - [Cosmos SDK Authz Module Documentation](https://docs.cosmos.network/main/build/modules/authz) -- [IXO Claims Module Documentation](/guides/dev/claims) +- [Claims management](/guides/dev/ixo-claims) - [Digital vouchers workflow](/platforms/Emerging/digital-vouchers) diff --git a/guides/dev/authz.mdx b/guides/dev/authz.mdx index a52b5a0..c610d69 100644 --- a/guides/dev/authz.mdx +++ b/guides/dev/authz.mdx @@ -1,133 +1,174 @@ --- -title: 'Managing Authorization' -description: 'Learn how to manage permissions and authorizations using the IXO MultiClient SDK' +title: "Manage authorization" +description: "Grant, revoke, and execute Cosmos authz and feegrant messages on the IXO Protocol." --- - - Authorization (AuthZ) allows accounts to grant permissions to other accounts for executing specific types of transactions. This guide shows you how to implement common authorization scenarios. - - -## Granting Send Authorization - -Grant permission to another account to send tokens on your behalf. + + Authorization (`x/authz`) lets one account grant another the right to broadcast specific message types on its behalf, scoped by amount, time, or message URL. `x/feegrant` lets one account pay another's transaction fees. Both are standard Cosmos SDK modules — IXO uses the upstream message types directly. + -```typescript -const response = await MsgGrantSend( - "1000000uixo", // Amount to authorize - "granter_address", // Address granting permission - "grantee_address" // Address receiving permission -); -``` +## Before you start - - - - **Type:** `string` - - **Description:** Token amount and denomination to authorize - +You need: - - - **Type:** `string` - - **Description:** Address granting the authorization - +- An IXO account with `uixo` for fees on the network you target — see [Networks and endpoints](/reference/networks-and-endpoints). +- An offline signer — see the [SDK README](https://github.com/ixofoundation/ixo-multiclient-sdk#creating-signers). +- The granter and grantee bech32 addresses. - - - **Type:** `string` - - **Description:** Address receiving the authorization - - +```bash +npm install @ixo/impactxclient-sdk +``` -## Executing IBC Send with Authorization +```ts +import { cosmos, createSigningClient } from "@ixo/impactxclient-sdk"; -Send tokens through IBC channels using previously granted authorization. +const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner); +``` -```typescript -const response = await MsgExecSendIbc( - "channel-0", // IBC channel - "grantee_address", // Address with authorization - "1000000uixo" // Amount to send -); +## Grant a send authorization + +`SendAuthorization` lets the grantee call `cosmos.bank.v1beta1.MsgSend` from the granter, capped at `spend_limit`. + +```ts +const sendAuth = cosmos.bank.v1beta1.SendAuthorization.fromPartial({ + spendLimit: [{ denom: "uixo", amount: "1000000" }], +}); + +const grantMsg = { + typeUrl: "/cosmos.authz.v1beta1.MsgGrant", + value: cosmos.authz.v1beta1.MsgGrant.fromPartial({ + granter: granterAddress, + grantee: granteeAddress, + grant: cosmos.authz.v1beta1.Grant.fromPartial({ + authorization: { + typeUrl: "/cosmos.bank.v1beta1.SendAuthorization", + value: cosmos.bank.v1beta1.SendAuthorization.encode(sendAuth).finish(), + }, + }), + }), +}; + +await signingClient.signAndBroadcast(granterAddress, [grantMsg], "auto"); ``` -## Managing Fee Allowances +For broader grants (e.g. authorize any IBC transfer message URL), use `cosmos.authz.v1beta1.GenericAuthorization` with the target `msg` type URL. + +## Execute a granted message + +The grantee wraps the message they were authorized to send inside `cosmos.authz.v1beta1.MsgExec`. + +```ts +const innerSend = cosmos.bank.v1beta1.MsgSend.fromPartial({ + fromAddress: granterAddress, + toAddress: recipientAddress, + amount: [{ denom: "uixo", amount: "100000" }], +}); + +const execMsg = { + typeUrl: "/cosmos.authz.v1beta1.MsgExec", + value: cosmos.authz.v1beta1.MsgExec.fromPartial({ + grantee: granteeAddress, + msgs: [ + { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: cosmos.bank.v1beta1.MsgSend.encode(innerSend).finish(), + }, + ], + }), +}; + +await signingClient.signAndBroadcast(granteeAddress, [execMsg], "auto"); +``` -### Granting Fee Allowance +For an IBC transfer, replace the inner message with `ibc.applications.transfer.v1.MsgTransfer`. -Authorize another account to use your tokens for transaction fees. +## Revoke an authorization -```typescript -const response = await MsgGrantAllowanceFeegrant( - "granter_address", // Address granting allowance - "grantee_address" // Address receiving allowance -); +```ts +const revokeMsg = { + typeUrl: "/cosmos.authz.v1beta1.MsgRevoke", + value: cosmos.authz.v1beta1.MsgRevoke.fromPartial({ + granter: granterAddress, + grantee: granteeAddress, + msgTypeUrl: "/cosmos.bank.v1beta1.MsgSend", + }), +}; ``` -### Revoking Fee Allowance +## Grant a fee allowance + +```ts +const basicAllowance = cosmos.feegrant.v1beta1.BasicAllowance.fromPartial({ + spendLimit: [{ denom: "uixo", amount: "500000" }], +}); + +const grantAllowanceMsg = { + typeUrl: "/cosmos.feegrant.v1beta1.MsgGrantAllowance", + value: cosmos.feegrant.v1beta1.MsgGrantAllowance.fromPartial({ + granter: granterAddress, + grantee: granteeAddress, + allowance: { + typeUrl: "/cosmos.feegrant.v1beta1.BasicAllowance", + value: cosmos.feegrant.v1beta1.BasicAllowance.encode(basicAllowance).finish(), + }, + }), +}; +``` -Remove a previously granted fee allowance. +## Revoke a fee allowance -```typescript -const response = await MsgRevokeAllowance( - "granter_address", // Address that granted allowance - "grantee_address" // Address to revoke from -); +```ts +const revokeAllowanceMsg = { + typeUrl: "/cosmos.feegrant.v1beta1.MsgRevokeAllowance", + value: cosmos.feegrant.v1beta1.MsgRevokeAllowance.fromPartial({ + granter: granterAddress, + grantee: granteeAddress, + }), +}; ``` -## AuthZ Function Reference +The grantee then sets the granter's address as the `feePayer` in the transaction's fee object — the granter is debited instead of the grantee. -### Core Functions +## Verify the result - - - Grants send authorization. +Query active grants through the [gRPC gateway API](/api-reference/grpc-gateway-api): - **Parameters:** `amount: string, granter: string, grantee: string` - +- `cosmos.authz.v1beta1.Query/Grants` — grants between a granter and grantee +- `cosmos.authz.v1beta1.Query/GranterGrants` — all grants issued by a granter +- `cosmos.authz.v1beta1.Query/GranteeGrants` — all grants received by a grantee +- `cosmos.feegrant.v1beta1.Query/Allowance` — fee allowance status - - Executes IBC send with authorization. +## Troubleshooting - **Parameters:** `channel: string, grantee: string, amount: string` + + + Confirm bech32 addresses are valid for the chain prefix (`ixo`), the denom is supported, and the amount is within `spend_limit`. - - - Grants fee allowance. - - **Parameters:** `granter: string, grantee: string` + + Confirm the grant has not expired, the grantee's transaction message URL exactly matches the authorization's allowed type, and the spend limit has not been exhausted. - - - Revokes a fee allowance. - - **Parameters:** `granter: string, grantee: string` - - - - Executes a transaction with granted authorization. - - **Parameters:** *Varies by transaction type* + + Ensure the granter has sufficient balance for the allowance, the allowance type matches the use case (`BasicAllowance` vs `PeriodicAllowance` vs `AllowedMsgAllowance`), and the transaction's `feePayer` is set to the granter. -## Troubleshooting - - - - Ensure addresses are correctly formatted - - Verify the amount is within allowed limits - - Check that the denomination is supported - - - - - Confirm the authorization hasn't expired - - Verify the grantee has sufficient permissions - - Check that the authorization type matches the operation - - - - - Ensure the granter has sufficient balance - - Verify the allowance hasn't been exceeded - - Check for any time-based restrictions - - - Authorizations can be time-limited. Monitor expiration dates and renewal requirements for critical permissions. + Use `AllowedMsgAllowance` to combine fee payment with a strict whitelist of message URLs the grantee may submit at the granter's expense. + +## Next steps + + + + Use IXO-specific authz types for entities, claims, and tokens. + + + Add programmable authenticators on top of authz. + + + Full reference for `x/authz`. + + + Full reference for `x/feegrant`. + + diff --git a/guides/dev/bonds.mdx b/guides/dev/bonds.mdx index f6121d1..7e4f6d4 100644 --- a/guides/dev/bonds.mdx +++ b/guides/dev/bonds.mdx @@ -1,217 +1,211 @@ --- -title: 'Managing Bonds' -description: 'Create and manage financial instruments on the IXO blockchain using the IXO MultiClient SDK' +title: "Manage bonds" +description: "Create and manage algorithmic bonds, trade them, and settle outcome payments on the IXO Protocol." --- - - Bonds use mathematical bonding curves to determine token prices. The bond state affects which operations are allowed at any given time. - +The IXO Protocol bonds module provides universal token bonding-curve functions to mint, burn, swap, and settle bonds. Bonds price their tokens via a bonding curve (`function_type` and `function_parameters`), accept one or more `reserve_tokens`, and pass through a lifecycle of `HATCH → OPEN → SETTLE` (or `FAILED`). Alpha bonds add risk-adjustment via the `oracle_did`-controlled `MsgSetNextAlpha`. -## Creating a Bond +## Before you start -Create a new financial instrument with specific parameters and bonding curve. +You need: -```typescript -const response = await CreateBond( - true // allowSells parameter determines if selling bonds is permitted -); -``` - -### Bond parameters - - - Unique identifier for the bond - The bond's token denomination - Name of the bond - Description of the bond - Type of bonding curve (`augmented_function` or `bonding_function`) - Array of parameters defining the bonding curve - Array of accepted reserve tokens - Transaction fee percentage - Exit fee percentage - Maximum supply of bond tokens - Limits on order quantities - Whether selling of bonds is allowed - Whether reserve withdrawals are allowed - Whether this is an alpha bond - Number of blocks per batch - - -## Modifying Bond Parameters +- An IXO account with sufficient `uixo` for fees on the network you target — see [Networks and endpoints](/reference/networks-and-endpoints). +- An offline signer — see the [SDK README on creating signers](https://github.com/ixofoundation/ixo-multiclient-sdk#creating-signers). +- For `MsgCreateBond`: a controller DID, a creator DID, optional oracle DID for alpha bonds, and reserve token denoms. +- For `MsgWithdrawReserve`: the bond's `allow_reserve_withdrawals` flag must be `true`. -Update an existing bond's configuration. - -```typescript -const response = await EditBond(); +```bash +npm install @ixo/impactxclient-sdk ``` - - You can update parameters like name, description, order quantity limits, sanity rate, and sanity margin percentage. - - -## Managing Bond State +```ts +import { ixo, createSigningClient } from "@ixo/impactxclient-sdk"; -Change the lifecycle state of a bond. - -```typescript -const response = await UpdateBondState( - "OPEN" // New state for the bond -); +const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner); ``` -### Available states - - - - Initial fundraising phase - - - - Active trading phase - - - - Settlement phase - - - - Failed bond state - - - -## Trading Bonds - -### Buying Bonds - -Purchase bond tokens using reserve tokens. - -```typescript -const response = await Buy( - 1000000, // Amount of bonds to buy - 100 // Maximum price willing to pay -); +## Create a bond + +```ts +const createBondMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgCreateBond", + value: ixo.bonds.v1beta1.MsgCreateBond.fromPartial({ + bondDid: "did:ixo:bond:abc123", + token: "BOND", + name: "Solar Farm Alpha Bond", + description: "Outcome-linked bond for verified solar production", + functionType: "augmented_function", + functionParameters: [ + ixo.bonds.v1beta1.FunctionParam.fromPartial({ param: "p0", value: "1" }), + ], + creatorDid: "did:ixo:creator123", + controllerDid: "did:ixo:controller123", + oracleDid: "did:ixo:oracle123", + reserveTokens: ["uixo"], + txFeePercentage: "0.5", + exitFeePercentage: "1.0", + feeAddress: feeAddress, + reserveWithdrawalAddress: reserveAddress, + maxSupply: { denom: "BOND", amount: "1000000" }, + orderQuantityLimits: [], + sanityRate: "0", + sanityMarginPercentage: "0", + allowSells: true, + allowReserveWithdrawals: false, + alphaBond: true, + batchBlocks: "1", + outcomePayment: "0", + creatorAddress: signerAddress, + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [createBondMsg], "auto"); ``` -### Selling Bonds - -Sell bond tokens back to the reserve pool (if allowed). - -```typescript -const response = await Sell( - 1000000, // Amount of bonds to sell - 100 // Minimum price willing to accept -); +## Edit, set alpha, transition state + +```ts +const editMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgEditBond", + value: ixo.bonds.v1beta1.MsgEditBond.fromPartial({ + bondDid: "did:ixo:bond:abc123", + name: "Solar Farm Alpha Bond v2", + description: "Updated description", + orderQuantityLimits: "", + sanityRate: "", + sanityMarginPercentage: "", + editorDid: "did:ixo:editor123", + editorAddress: signerAddress, + }), +}; + +const setAlphaMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgSetNextAlpha", + value: ixo.bonds.v1beta1.MsgSetNextAlpha.fromPartial({ + bondDid: "did:ixo:bond:abc123", + alpha: "0.85", + delta: "0.05", + oracleDid: "did:ixo:oracle123", + oracleAddress: oracleSignerAddress, + }), +}; + +const updateStateMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgUpdateBondState", + value: ixo.bonds.v1beta1.MsgUpdateBondState.fromPartial({ + bondDid: "did:ixo:bond:abc123", + state: "OPEN", + editorDid: "did:ixo:editor123", + editorAddress: signerAddress, + }), +}; ``` -## Managing Bond Outcomes - -### Making Outcome Payments - -Add funds to the outcome payment reserve. - -```typescript -const response = await MakeOutcomePayment( - 1000000 // Amount for the outcome payment -); +Bond states are: `HATCH` (initial fundraising), `OPEN` (active trading), `SETTLE` (settlement), `FAILED`. + +## Buy, sell, swap + +```ts +const buyMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgBuy", + value: ixo.bonds.v1beta1.MsgBuy.fromPartial({ + buyerDid: "did:ixo:buyer123", + amount: { denom: "BOND", amount: "1000000" }, + maxPrices: [{ denom: "uixo", amount: "100" }], + bondDid: "did:ixo:bond:abc123", + buyerAddress: signerAddress, + }), +}; + +const sellMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgSell", + value: ixo.bonds.v1beta1.MsgSell.fromPartial({ + sellerDid: "did:ixo:seller123", + amount: { denom: "BOND", amount: "1000000" }, + bondDid: "did:ixo:bond:abc123", + sellerAddress: signerAddress, + }), +}; + +const swapMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgSwap", + value: ixo.bonds.v1beta1.MsgSwap.fromPartial({ + swapperDid: "did:ixo:swapper123", + bondDid: "did:ixo:bond:abc123", + from: { denom: "uixo", amount: "1000" }, + toToken: "uatom", + swapperAddress: signerAddress, + }), +}; ``` -### Withdrawing Funds - -#### Withdraw Share - -Claim your share of the bond's returns. - -```typescript -const response = await WithdrawShare( - WalletUsers.tester // Signer of the transaction -); +## Outcome payments and withdrawals + +```ts +const outcomePayMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgMakeOutcomePayment", + value: ixo.bonds.v1beta1.MsgMakeOutcomePayment.fromPartial({ + senderDid: "did:ixo:funder123", + amount: "1000000", + bondDid: "did:ixo:bond:abc123", + senderAddress: signerAddress, + }), +}; + +const withdrawShareMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgWithdrawShare", + value: ixo.bonds.v1beta1.MsgWithdrawShare.fromPartial({ + recipientDid: "did:ixo:holder123", + bondDid: "did:ixo:bond:abc123", + recipientAddress: signerAddress, + }), +}; + +const withdrawReserveMsg = { + typeUrl: "/ixo.bonds.v1beta1.MsgWithdrawReserve", + value: ixo.bonds.v1beta1.MsgWithdrawReserve.fromPartial({ + withdrawerDid: "did:ixo:treasury123", + amount: [{ denom: "uixo", amount: "500000" }], + bondDid: "did:ixo:bond:abc123", + withdrawerAddress: signerAddress, + }), +}; ``` -#### Withdraw Reserve +## Verify the result -Withdraw funds from the bond's reserve (if allowed). - -```typescript -const response = await WithdrawReserve( - WalletUsers.tester, // Signer of the transaction - 1000000 // Amount to withdraw -); -``` +Query bond state through the [Blocksync GraphQL API](/api-reference/blocksync-graphql-api) or `ixo.bonds.v1beta1` query endpoints on the [gRPC gateway API](/api-reference/grpc-gateway-api). -## Bond Function Reference +## Troubleshooting - - Creates a new bond. - - **Parameters:** `allowSells: boolean` + + `function_type` must be one of the supported curve types (`power_function`, `sigmoid_function`, `swapper_function`, `augmented_function`). Each requires a specific set of `function_parameters` — see the [bonds proto](https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo/bonds/v1beta1). - - - Modifies bond parameters. - - **Parameters:** *Varies based on parameters to update* + + State transitions are constrained by the bond's lifecycle. `HATCH → OPEN` requires the hatch threshold to be met. `OPEN → SETTLE` is typically called once the outcome obligation is met or the bond expires. - - - Changes bond lifecycle state. - - **Parameters:** `state: string` + + `MsgWithdrawReserve` fails when `allow_reserve_withdrawals` is `false` on `MsgCreateBond`. This flag is immutable. - - - Purchases bond tokens. - - **Parameters:** `amount: number, maxPrice: number` - - - - Sells bond tokens. - - **Parameters:** `amount: number, minPrice: number` - - - - Sets next alpha value. - - **Parameters:** *Varies by implementation* - - - - Makes outcome payment. - - **Parameters:** `amount: number` - - - - Withdraws share. - - **Parameters:** `signer: WalletUser` - - - - Withdraws from reserve. - - **Parameters:** `signer: WalletUser, amount: number` + + Only the bond's `oracle_address` (resolving from `oracle_did`) can broadcast `MsgSetNextAlpha`. Confirm the signer matches. -## Troubleshooting - - - - Ensure all function parameters are correctly specified - - Verify the bonding curve parameters are valid - - Check that reserve tokens are properly configured - - - - - Confirm the current state allows the requested transition - - Verify all conditions for state change are met - - Check authorization for state changes - - - - - Ensure sufficient balance for purchases - - Verify sells are allowed if attempting to sell - - Check price limits are reasonable - +## Next steps + + + + Module-level features and types. + + + Source of truth for bond messages. + + + Mint outcome tokens against settled bonds. + + + Stake IXO tokens for use in bonded protocols. + + diff --git a/guides/dev/claims.mdx b/guides/dev/claims.mdx deleted file mode 100644 index 715e273..0000000 --- a/guides/dev/claims.mdx +++ /dev/null @@ -1,207 +0,0 @@ ---- -title: 'Managing Claims and Collections' -description: 'Create, submit, and evaluate claims and collections on the IXO blockchain using the IXO MultiClient SDK' ---- - -Claims and collections are central to managing interactions and transactions on the IXO blockchain. This guide shows you how to implement common claim operations. - -## Creating a Collection - -Set up a new collection for submitting and evaluating claims. - -```typescript -const response = await CreateCollection( - "entityDid1234", // The DID of the entity creating the collection - "protocolDid1234", // The DID of the associated protocol - "paymentsAccount1234" // Account to handle payments -); -``` - -### Parameters - - - - DID of the entity creating the collection - - - - DID of the protocol under which the collection falls - - - - Account to handle collection-related payments - - - - Transaction signer - - - - CW20 token address for payments - - - -## Querying Collections - -Retrieve collection data using the IXO Blocksync GraphQL API. - -```graphql -query MyQuery { - claimCollection(id: "99") { - id - startDate - endDate - entity - protocol - admin - count - evaluated - approved - rejected - disputed - claimSchemaTypesLoaded - invalidated - payments - quota - state - } -} -``` - - - Replace the `id` field with your specific collection ID to get detailed information about that collection. - - -## Managing Claims - -### Submitting a Claim - -Submit a new claim to an existing collection. - -```typescript -const response = await MsgExecAgentSubmit( - "claimId1234", // Unique identifier for the claim - "collectionId1234", // Identifier of the collection - "adminAddress1234" // Admin address authorizing the claim submission -); -``` - -### Evaluating a Claim - -Assess and evaluate a submitted claim. - -```typescript -const response = await MsgExecAgentEvaluate( - "claimId1234", // Unique identifier for the claim - "collectionId1234", // Identifier of the collection - "adminAddress1234" // Admin address authorizing the claim evaluation -); -``` - -## Querying Claims - -Retrieve detailed information about claims using GraphQL. - -```graphql -query MyQuery { - claim(claimId: "bafkreihzugslzexyu2c6o6nmtm7vxbsyelo7pzmcppsmqawj2s6blmgojy") { - schemaType - claimId - agentAddress - agentDid - collectionId - paymentsStatus - submissionDate - evaluationByClaimId { - status - verificationProof - amount - evaluationDate - oracle - reason - } - } -} -``` - -## Claims Function Reference - - - - Creates a new collection. - - **Parameters:** `entityDid, protocolDid, paymentsAccount, signer?, cw20Address?` - - - - Updates collection state. - - **Parameters:** `collectionId, adminAddress, signer?` - - - - Submits a claim intent. - - **Parameters:** `claimId, collectionId, adminAddress` - - - - Submits a claim. - - **Parameters:** `claimId, collectionId, adminAddress` - - - - Evaluates a claim. - - **Parameters:** `claimId, collectionId, adminAddress` - - - - Grants submission authorization. - - **Parameters:** *Varies by implementation* - - - - Grants evaluation authorization. - - **Parameters:** *Varies by implementation* - - - - Initiates a claim dispute. - - **Parameters:** *Varies by implementation* - - - - Executes payment withdrawal. - - **Parameters:** *Varies by implementation* - - - -## Troubleshooting - - - - Ensure all DIDs and account addresses are correct - - Verify payment account details are accurate - - Check that the protocol DID exists and is valid - - - - - Check that the claim ID is unique and valid - - Ensure the admin address has the necessary permissions - - Verify the collection is in a state that accepts claims - - - - - Confirm the claim is in a state ready for evaluation - - Verify the evaluator has the correct authorization - - Check that the collection is still active and valid - - - - Always verify the status and details of claims and collections through the GraphQL API before performing operations on them. - diff --git a/guides/dev/domain-privacy.mdx b/guides/dev/domain-privacy.mdx index cf5272c..5e8af9d 100644 --- a/guides/dev/domain-privacy.mdx +++ b/guides/dev/domain-privacy.mdx @@ -37,6 +37,14 @@ Expected result: ## Next steps -- Domain settings: `/guides/dev/domain-settings` -- API authentication: `/api-reference/authentication` -- Product and SDK map: `/reference/product-and-sdk-map` + + + Configure services, permissions, and domain-level behavior. + + + Apply correct auth patterns across IXO API surfaces. + + + Confirm canonical product names and SDK route mappings. + + diff --git a/guides/dev/domain-settings.mdx b/guides/dev/domain-settings.mdx index 61f568a..63f0255 100644 --- a/guides/dev/domain-settings.mdx +++ b/guides/dev/domain-settings.mdx @@ -50,6 +50,14 @@ Expected result: ## Next steps -- Domain privacy guide: `/guides/dev/domain-privacy` -- Blockchain REST API: `/api-reference/grpc-gateway-api` -- Authentication matrix: `/reference/authentication-matrix` + + + Protect sensitive domain data and access patterns. + + + Use gRPC-gateway routes for protocol-level interactions. + + + Match each API surface to the required credentials and headers. + + diff --git a/guides/dev/entities.mdx b/guides/dev/entities.mdx index 3822fac..6bce1c6 100644 --- a/guides/dev/entities.mdx +++ b/guides/dev/entities.mdx @@ -1,162 +1,186 @@ --- -title: 'Managing Entities' -description: 'Create and manage NFT-backed identities on the IXO blockchain using the IXO MultiClient SDK' +title: "Manage entities" +description: "Create, transfer, verify, and govern entity domains on the IXO Protocol with the IXO MultiClient SDK." --- - - Entities in IXO represent NFT-backed identities that bridge decentralized identifiers with tangible assets. Each entity consists of an IID Document, an NFT, and associated metadata, providing a robust framework for decentralized operations. - +This guide shows the chain-level message patterns for managing **entities** on the IXO Protocol using the [`@ixo/impactxclient-sdk`](https://www.npmjs.com/package/@ixo/impactxclient-sdk). For the data model, read [Entity domains](/guides/dev/ixo-domains) and [Domain configuration](/articles/domain-config) first. -## Creating an Entity +## Before you start -Create a new entity with a specified type and context information. +You need: -```typescript -const entityType = "asset"; -const context = [{ key: "class", val: "did:ixo:entity:protocol123" }]; -const response = await Entity.CreateEntity(entityType, context); -const entityDid = utils.common.getValueFromEvents(response, "wasm", "token_id"); -console.log({ entityDid }); -``` - - - #### Protocols as canonical classes - - Entities can be of different types (e.g., "asset") and include context information that defines their class and properties. The context helps establish the entity's relationship to protocols and inherited properties. - - -## Transferring Entity Ownership +- A funded IXO account on the network you target — see [Networks and endpoints](/reference/networks-and-endpoints). +- An offline signer (Cosmos-kit, Keplr, or `getOfflineSigner` from `cosmjs-utils`) — see the [SDK README on creating signers](https://github.com/ixofoundation/ixo-multiclient-sdk#creating-signers). +- The [`@ixo/impactxclient-sdk`](https://www.npmjs.com/package/@ixo/impactxclient-sdk) installed. -Transfer ownership of one or more entities to another party. - -```typescript -const entities = [entityDid]; -const recipientDid = "did:ixo:recipient123"; -const memo = "Transfer to new owner"; -await Entity.TransferEntity(WalletUsers.tester, entities, recipientDid, memo); +```bash +npm install @ixo/impactxclient-sdk ``` -## Managing Entity Accounts - -Entity accounts enable delegated operations and Capability-based permissions for entity management. - -### Creating an Entity Account +The signing client follows the canonical three-step pattern: compose, sign, broadcast. -Set up a named account for an entity to manage specific functions. +```ts +import { ixo, createSigningClient } from "@ixo/impactxclient-sdk"; -```typescript -const accountName = "treasury"; -await Entity.CreateEntityAccount(entityDid, accountName); +const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner); ``` -### Granting Account Authorization - -Authorize an account to perform specific operations on behalf of the entity. - -```typescript -const genericAuthMsg = "/cosmos.bank.v1beta1.MsgSend"; -await Entity.GrantEntityAccountAuthz( - entityDid, - "treasury", - WalletUsers.alice, - WalletUsers.tester, - genericAuthMsg -); +## Create an entity + +```ts +const message = { + typeUrl: "/ixo.entity.v1beta1.MsgCreateEntity", + value: ixo.entity.v1beta1.MsgCreateEntity.fromPartial({ + ownerAddress: signerAddress, + entityType: "asset", + context: [ + ixo.iid.v1beta1.Context.fromPartial({ + key: "class", + val: "did:ixo:entity:protocol123", + }), + ], + verification: [], + controller: [], + service: [], + linkedResource: [], + accordedRight: [], + linkedEntity: [], + linkedClaim: [], + }), +}; + +const response = await signingClient.signAndBroadcast(signerAddress, [message], "auto"); ``` -### Revoking Account Authorization +The chain returns a transaction with events that include the new entity DID. -Remove previously granted permissions from an entity account. + + Field names mirror the [`x/entity` proto definitions](https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo/entity/v1beta1). Inspect `entity.proto` for the authoritative field list and any version-specific changes. + -```typescript -await Entity.MsgRevokeEntityAccountAuthz( - entityDid, - "treasury", - WalletUsers.alice, - "/cosmos.bank.v1beta1.MsgSend" -); -``` +## Transfer entity ownership -## Updating Entity Status +`MsgTransferEntity` reassigns the underlying entity NFT to a new controller account. -Change an entity's verification status to indicate validation or approval. +```ts +const transferMsg = { + typeUrl: "/ixo.entity.v1beta1.MsgTransferEntity", + value: ixo.entity.v1beta1.MsgTransferEntity.fromPartial({ + id: entityDid, + ownerAddress: currentOwnerAddress, + recipientDid: "did:ixo:recipient123", + }), +}; -```typescript -const entityDids = [entityDid]; -await Entity.UpdateEntityVerified( - WalletUsers.tester, - entityDids, - relayerDid, - true -); +await signingClient.signAndBroadcast(currentOwnerAddress, [transferMsg], "auto"); ``` -## Entity Function Reference +## Update verification status - - - Creates a new entity. +A verifying authority (oracle, registry, or DAO controller) calls `MsgUpdateEntityVerified` to flip the verified flag for one or more entities it is permitted to attest. - **Parameters:** `entityType?, context?, relayerNodeDid?, relayerNode?, signer?` - +```ts +const verifyMsg = { + typeUrl: "/ixo.entity.v1beta1.MsgUpdateEntityVerified", + value: ixo.entity.v1beta1.MsgUpdateEntityVerified.fromPartial({ + id: entityDid, + relayerNode: relayerDid, + entityVerified: true, + }), +}; - - Transfers entity ownership. +await signingClient.signAndBroadcast(signerAddress, [verifyMsg], "auto"); +``` - **Parameters:** `signer?, entities[], recipientDid?, memo?` - +## Manage entity accounts + +Entities can hold named sub-accounts (for example `treasury`, `payouts`, `operations`) that can transact on behalf of the entity under explicit authz grants. + +```ts +const createAccountMsg = { + typeUrl: "/ixo.entity.v1beta1.MsgCreateEntityAccount", + value: ixo.entity.v1beta1.MsgCreateEntityAccount.fromPartial({ + id: entityDid, + ownerAddress: signerAddress, + name: "treasury", + }), +}; + +const grantMsg = { + typeUrl: "/ixo.entity.v1beta1.MsgGrantEntityAccountAuthz", + value: ixo.entity.v1beta1.MsgGrantEntityAccountAuthz.fromPartial({ + id: entityDid, + ownerAddress: signerAddress, + name: "treasury", + granteeAddress: granteeAddress, + grant: /* cosmos.authz.v1beta1.Grant */ undefined, + }), +}; + +const revokeMsg = { + typeUrl: "/ixo.entity.v1beta1.MsgRevokeEntityAccountAuthz", + value: ixo.entity.v1beta1.MsgRevokeEntityAccountAuthz.fromPartial({ + id: entityDid, + ownerAddress: signerAddress, + name: "treasury", + granteeAddress: granteeAddress, + msgTypeUrl: "/cosmos.bank.v1beta1.MsgSend", + }), +}; +``` - - Updates verification status. +Construct the `grant` value using `cosmos.authz.v1beta1.Grant.fromPartial({...})` with the matching authorization. See [Authentication and authorization](/guides/dev/authentication) and [Custom authorisations for IXO Claims](/guides/dev/authz-custom). + +## Verify the result + +Query the entity through the [Blocksync GraphQL API](/api-reference/blocksync-graphql-api): + +```graphql +query GetEntity($did: String!) { + entity(id: $did) { + id + type + status + relayerNode + owner + controller + accounts { + name + address + } + } +} +``` - **Parameters:** `signer?, entityDids[], relayerDid?, entityVerified?` - +Or use the gRPC gateway directly — see [gRPC gateway API](/api-reference/grpc-gateway-api) for the entity module endpoints. - - Creates an entity account. +## Troubleshooting - **Parameters:** `entityDid, name?, signer?` + + + The `entityType` value must match a type the chain accepts. Inspect module params via the gRPC gateway or query the `EntityList` endpoint to confirm allowed types on your network. - - - Grants account authorization. - - **Parameters:** `entityDid, name?, grantee?, signer?, genericAuthMsg?` + + The signer must be a current controller or relayer with the right capability. Confirm the signer address is in the entity's controller set or has an active authz grant. - - - Revokes authorization. - - **Parameters:** `entityDid, name?, grantee?, msgTypeUrl?, signer?` + + Account names are unique per entity. Pick a different name or revoke and re-grant authz on the existing account. -## Entity Data Structure - - -- **Entity DID**: Unique decentralized identifier -- **NFT**: Non-fungible token representing ownership -- **IID Document**: Interchain identity document with verification methods -- **Metadata**: Additional entity information and properties -- **Entity Accounts**: Named accounts with specific permissions - - -## Troubleshooting - - - - Ensure the entityType matches one of the supported types - - Verify the context information is properly formatted - - Check that the entity type is allowed in the module parameters - - - - - Confirm the signer has appropriate permissions for the operation - - Verify the relayer node DID is valid and active - - Check that the message type URL is correctly formatted - - - - - Ensure account names are unique within the entity - - Verify authorization message types match intended permissions - - Check that the grantee address is valid - +## Next steps + + + + Update controllers, services, resources, and accorded rights. + + + Decide what to keep on protocol vs in IXO Matrix. + + + Full SDK reference and module list. + + + Source of truth for message shapes. + + diff --git a/guides/dev/evaluation-engine.mdx b/guides/dev/evaluation-engine.mdx deleted file mode 100644 index e69de29..0000000 diff --git a/guides/dev/examples.mdx b/guides/dev/examples.mdx index 29b2aae..3c6d760 100644 --- a/guides/dev/examples.mdx +++ b/guides/dev/examples.mdx @@ -1,377 +1,238 @@ --- -title: 'Implementation Examples' -description: 'Code examples and tutorials for IXO development' +title: "Implementation examples" +description: "Worked end-to-end TypeScript examples for IXO MultiClient SDK and IXO Matrix Client SDK." --- - - This page provides practical code examples and tutorials to help you implement common patterns and use cases with the IXO SDKs. - +These examples follow the canonical patterns from the [`@ixo/impactxclient-sdk`](https://www.npmjs.com/package/@ixo/impactxclient-sdk) and [`@ixo/matrixclient-sdk`](https://www.npmjs.com/package/@ixo/matrixclient-sdk) READMEs. Use them as starting templates — exact field shapes are generated from the [chain proto definitions](https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo). -## Digital Twin Management +For the step-by-step explanation behind each pattern, read [Developer workflows](/guides/dev/workflows) first. -### Creating a Digital Twin +## Setup -```typescript -import { createClient } from "@ixo/impactxclient-sdk"; - -// Initialize client -const client = await createClient({ - rpcEndpoint: "https://rpc.ixo.world", - chainId: "ixo-5" -}); - -// Create digital twin entity -const entity = await client.createEntity({ - type: "Asset", - name: "Solar Panel Array", - description: "Renewable energy installation", - location: { - latitude: 51.5074, - longitude: -0.1278 - }, - metadata: { - capacity: "5kW", - installation_date: "2023-01-15" - } -}); - -console.log("Entity created:", entity.id); - -// Query entity -const entityData = await client.getEntity(entity.id); -console.log("Entity data:", entityData); +```bash +npm install @ixo/impactxclient-sdk @ixo/matrixclient-sdk ``` -### Updating Entity State - -```typescript -// Update entity state -await client.updateEntity(entity.id, { - status: "active", - metadata: { - ...entityData.metadata, - last_maintenance: "2023-06-10" - } -}); - -// Add relationships -await client.addEntityRelationships(entity.id, [ - { - type: "contains", - target: "did:ixo:entity/456", - properties: { - startDate: Date.now() - } - } -]); +```ts +import { + ixo, + createQueryClient, + createSigningClient, +} from "@ixo/impactxclient-sdk"; + +import { + createMatrixApiClient, + createMatrixRoomBotClient, + createMatrixStateBotClient, + createMatrixClaimBotClient, +} from "@ixo/matrixclient-sdk"; + +const RPC_ENDPOINT = "https://rpc.ixo.world"; +const HOME_SERVER_URL = "https://devmx.ixo.earth"; + +const queryClient = await createQueryClient(RPC_ENDPOINT); +const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner); ``` -## Secure Data Management - -### Creating a Data Room - -```typescript -import { createMatrixClient } from "@ixo/matrixclient-sdk"; - -// Initialize Matrix client -const matrix = await createMatrixClient({ - baseUrl: "https://matrix.ixo.world", - accessToken: "YOUR_ACCESS_TOKEN" -}); - -// Create encrypted room -const room = await matrix.createRoom({ - name: "Project Data Room", - encryption: true, - preset: "private_chat", - initialState: [{ - type: "m.room.encryption", - state_key: "", - content: { algorithm: "m.megolm.v1.aes-sha2" } - }] -}); - -console.log("Room created:", room.roomId); - -// Set room permissions -await matrix.setRoomPermissions(room.roomId, { - readAccess: ["@alice:ixo.world"], - writeAccess: ["@bob:ixo.world"] -}); +## Digital twin: create an entity + +```ts +const createEntity = async (signerAddress: string) => { + const message = { + typeUrl: "/ixo.entity.v1beta1.MsgCreateEntity", + value: ixo.entity.v1beta1.MsgCreateEntity.fromPartial({ + ownerAddress: signerAddress, + entityType: "asset", + context: [ + ixo.iid.v1beta1.Context.fromPartial({ + key: "class", + val: "did:ixo:entity:protocol123", + }), + ], + verification: [], + controller: [], + service: [], + linkedResource: [], + accordedRight: [], + linkedEntity: [], + linkedClaim: [], + }), + }; + + return signingClient.signAndBroadcast(signerAddress, [message], "auto"); +}; + +const entities = await queryClient.ixo.entity.v1beta1.entityList(); ``` -### Storing and Retrieving Data - -```typescript -// Store data -await matrix.sendEvent(room.roomId, "data.store", { - type: "ProjectMetrics", - data: { - energy_produced: "120kWh", - timestamp: Date.now() - }, - metadata: { - version: "1.0" - } -}); - -// Store file -const fileEvent = await matrix.sendFile(room.roomId, { - file: fileData, - filename: "metrics.json", - mimetype: "application/json" -}); +## Source an entity room (IXO Matrix) -// Retrieve data -const events = await matrix.getRoomEvents(room.roomId, { - types: ["data.store"], - limit: 10 -}); +Each entity has an associated encrypted Matrix room — its data room. Source it with the room bot, which creates the room if needed and invites the caller. -events.forEach(event => { - console.log("Data:", event.getContent().data); +```ts +const matrixRoomBotClient = createMatrixRoomBotClient({ + homeServerUrl: HOME_SERVER_URL, + botUrl: "https://devmx.ixo.earth/bots/room", + accessToken: matrixAccessToken, }); -``` -## Claims and Verification - -### Submitting a Claim - -```typescript -// Submit verification claim -const claim = await client.createClaim({ - entityId: entity.id, - type: "Production", - data: { - energy_produced: "120kWh", - timestamp: Date.now() - }, - evidence: { - type: "MeterReading", - hash: "Qm...", - uri: "https://..." - } -}); +const sourceRoomResponse = await matrixRoomBotClient.room.v1beta1.sourceRoomAndJoin( + "did:ixo:entity:abc...xyz", + ucanToken, +); -console.log("Claim created:", claim.id); +const roomId = sourceRoomResponse.roomId; ``` -### Verifying a Claim - -```typescript -import { createOracleClient } from "@ixo/oracle-agent-sdk"; +The `ucanToken` carries the caller's capability to act on the entity. The optional `accessToken` is the user's Matrix Client-Server access token, used only for the local join — never sent to the bot server. See [Matrix authentication](/api-reference/matrix-state-bot-api). -// Initialize oracle client -const oracle = await createOracleClient({ - did: "did:ixo:oracle/123", - endpoint: "https://oracle.ixo.world" -}); +## Upload telemetry into the data room -// Verify claim -const verification = await oracle.verify({ - claimId: claim.id, - data: claimData, - context: { - location: { - latitude: 51.5074, - longitude: -0.1278, - precision: 6 - }, - timestamp: Date.now() - } +```ts +const matrixApiClient = createMatrixApiClient({ + homeServerUrl: HOME_SERVER_URL, + accessToken: matrixAccessToken, }); -// Generate attestation -const attestation = await oracle.generateAttestation({ - verification, - method: "Ed25519Signature2020" -}); +const upload = await matrixApiClient.media.v1beta1.upload( + "telemetry-2025-04.json", + "application/json", + telemetryFile, +); -// Submit evaluation -const evaluation = await client.evaluateClaim(claim.id, { - status: "Approved", - verifier: oracle.did, - evidence: attestation -}); +const mxcUri = upload.content_uri; ``` -## Complete Use Cases - -### Digital MRV System +## Read or set room state via the State Bot -This example demonstrates a complete digital MRV (Measurement, Reporting, Verification) system for renewable energy: +Use the State Bot to attach structured profile or settings data to an entity room. -```typescript -// 1. Create project entity -const project = await client.createEntity({ - type: "Project", - name: "Solar Farm Alpha", - description: "10MW Solar Installation", - location: { latitude: 51.5074, longitude: -0.1278 } +```ts +const matrixStateBotClient = createMatrixStateBotClient({ + homeServerUrl: HOME_SERVER_URL, + botUrl: "https://devmx.ixo.earth/bots/state", + accessToken: matrixAccessToken, }); -// 2. Create device entities -const device = await client.createEntity({ - type: "Device", - name: "Smart Meter 001", - description: "Energy production meter", - metadata: { serial: "SM001", type: "production" } -}); - -// 3. Create relationships -await client.addEntityRelationships(project.id, [ - { type: "contains", target: device.id } -]); - -// 4. Create data room -const room = await matrix.createRoom({ - name: `${project.name} Data Room`, - encryption: true -}); +const stateData = await matrixStateBotClient.state.v1beta1.queryState( + roomId, + "impactsX", + "profile", + ucanToken, +); -// 5. Store device data -await matrix.sendEvent(room.roomId, "data.telemetry", { - deviceId: device.id, - readings: [ - { timestamp: Date.now(), value: "120", unit: "kWh" } - ] -}); - -// 6. Submit claim -const claim = await client.createClaim({ - entityId: project.id, - type: "EnergyProduction", - data: { - period: "2023-06", - total_production: "3600kWh" - } -}); - -// 7. Verify with oracle -const verification = await oracle.verify({ - claimId: claim.id, - data: await matrix.getRoomEvents(room.roomId, { - types: ["data.telemetry"], - limit: 100 - }) -}); - -// 8. Evaluate claim -await client.evaluateClaim(claim.id, { - status: "Approved", - verifier: oracle.did, - evidence: verification.attestation -}); - -// 9. Issue tokens -const tokens = await client.issueTokens({ - recipient: projectOwnerAddress, - amount: "3600", - denom: "carbon.credit", - metadata: { - project: project.id, - claim: claim.id, - period: "2023-06" - } -}); +await matrixStateBotClient.state.v1beta1.setState( + roomId, + "impactsX", + "profile", + JSON.stringify({ displayName: "Solar Farm Alpha", capacityKw: 5000 }), + ucanToken, +); ``` -### Secure Collaboration Platform - -This example demonstrates a secure collaboration platform for sensitive data: - -```typescript -// 1. Create Organisation -const org = await client.createEntity({ - type: "Organisation", - name: "Research Consortium", - description: "Collaborative research group" -}); - -// 2. Create project -const project = await client.createEntity({ - type: "Project", - name: "Climate Research Initiative", - description: "Data collection and analysis project" -}); - -// 3. Create relationship -await client.addEntityRelationships(org.id, [ - { type: "manages", target: project.id } -]); - -// 4. Create data room -const dataRoom = await matrix.createRoom({ - name: "Research Data Room", - encryption: true -}); - -// 5. Create discussion room -const discussionRoom = await matrix.createRoom({ - name: "Research Discussion", - encryption: true -}); - -// 6. Set permissions -const members = ["@alice:ixo.world", "@bob:ixo.world", "@charlie:ixo.world"]; - -await matrix.setRoomPermissions(dataRoom.roomId, { - readAccess: members, - writeAccess: members.slice(0, 2) // Only Alice and Bob can write -}); - -await matrix.setRoomPermissions(discussionRoom.roomId, { - readAccess: members, - writeAccess: members // All can participate in discussion -}); + + Always read state before overwriting. The State Bot does not merge — it replaces the value at the path you set. + + +## Claim flow: submit, evaluate, mint + +End-to-end flow for a digital MRV outcome: + +```ts +const collectionId = "12"; +const adminAddress = "ixo1..."; +const oracleAddress = "ixo1oracle..."; +const tokenContractAddress = "ixo1contract..."; + +// 1. Submit a claim referencing evidence stored in the data room +const submitClaimMsg = { + typeUrl: "/ixo.claims.v1beta1.MsgSubmitClaim", + value: ixo.claims.v1beta1.MsgSubmitClaim.fromPartial({ + creator: signerAddress, + claimId: "bafkreih...", + collectionId, + adminAddress, + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [submitClaimMsg], "auto"); + +// 2. Optional Claim Bot helpers (off-chain co-ordination) +const matrixClaimBotClient = createMatrixClaimBotClient({ + homeServerUrl: HOME_SERVER_URL, + botUrl: "https://devmx.ixo.earth/bots/claim", + accessToken: matrixAccessToken, +}); + +const claimRecord = await matrixClaimBotClient.claim.v1beta1.queryClaim( + collectionId, + "bafkreih...", + ucanToken, +); + +// 3. Evaluate after the Agentic Oracle has produced a verification +const evaluateMsg = { + typeUrl: "/ixo.claims.v1beta1.MsgEvaluateClaim", + value: ixo.claims.v1beta1.MsgEvaluateClaim.fromPartial({ + creator: signerAddress, + claimId: "bafkreih...", + collectionId, + oracle: oracleAddress, + adminAddress, + status: 1, // Approved + reason: 0, + verificationProof: "bafkrei-proof-cid", + amount: [], + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [evaluateMsg], "auto"); + +// 4. Mint outcome tokens against the approved claim +const mintMsg = { + typeUrl: "/ixo.token.v1beta1.MsgMintToken", + value: ixo.token.v1beta1.MsgMintToken.fromPartial({ + minter: signerAddress, + contractAddress: tokenContractAddress, + owner: recipientAddress, + mintBatch: [ + ixo.token.v1beta1.MintBatch.fromPartial({ + name: "CARBON", + index: "bafkreih...", + amount: "3600", + collection: "did:ixo:entity:collection456", + tokenData: [], + }), + ], + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [mintMsg], "auto"); +``` -// 7. Store research data -await matrix.sendFile(dataRoom.roomId, { - file: researchData, - filename: "climate_data_2023.csv", - mimetype: "text/csv" -}); + + The off-chain oracle call is your application code — see [Agentic Oracles ADK](/sdk-reference/oracle-adk) and [Build agentic oracles](/guides/ixo-oracles-architecture). + -// 8. Start discussion -await matrix.sendMessage(discussionRoom.roomId, { - msgtype: "m.text", - body: "I've uploaded the latest climate data. Let's discuss the findings." -}); +## Agentic Oracle integration -// 9. Create verification workflow -const verification = await oracle.createVerification({ - type: "DataQualityCheck", - subject: dataRoom.roomId, - rules: { - completeness: 0.95, - accuracy: 0.9 - } -}); +The off-chain oracle service is built with the [Agentic Oracles ADK](/sdk-reference/oracle-adk) and [Personal Agent ADK](/sdk-reference/oracle-adk). The on-chain side uses `@ixo/impactxclient-sdk` to record `MsgEvaluateClaim`. Wire the two together with whatever HTTP, MCP, or messaging layer your service exposes. -// 10. Generate report -const report = await verification.generateReport(); -await matrix.sendEvent(dataRoom.roomId, "verification.report", report); -``` +The IXO Oracles ecosystem is private. To request access, see [Build agentic oracles](/guides/ixo-oracles-architecture). -## Next Steps +## Next steps - - - Detailed API documentation + + + REST, RPC, GraphQL, and service APIs. - - - Learn more about the IXO SDKs + + Module-level features on protocol. - - - Source code and examples + + Matrix data rooms and bot clients. - - - Developer community and support + + Source code and reference implementations. - -{/* theme: info */} -> For technical support or questions about these examples, join our [Developer Community](https://ixofoundation.slack.com/archives/C04UERAUHQT) or contact our [Developer Relations Team](mailto:assistant@ixo.world). diff --git a/guides/dev/introduction.mdx b/guides/dev/introduction.mdx deleted file mode 100644 index c108a88..0000000 --- a/guides/dev/introduction.mdx +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: 'Implementation Guides' -icon: 'code-branch' -description: 'Step-by-step instructions for integrating IXO SDKs and tools into your applications' ---- - - -This section contains task guides for building on **IXO**—verifiable state, indexing, and protocol workflows—plus surfaces that participate in the **Qi Intelligent Cooperating System** when you add agents, Matrix, and oracle integrations. - - -For how state and Qi fit together, read [Introduction](/introduction), [What you can build](/guides/what-you-can-build), [Core concepts](/core-concepts), and [Qi: cooperation on verified workflows](/articles/qi-intelligent-cooperating-system). Agent and oracle concepts are covered in [Agentic Oracles](/articles/ixo-oracles). - -## Prerequisites - -- Install [IXO SDKs](/sdk-reference/index) -- Set up [Signing Client](https://www.npmjs.com/package/@ixo/impactxclient-sdk#signing-client) for transaction signing -- Access to [IXO Blocksync GraphQL](/api-reference/blocksync-graphql-api) for queries - - -Signing Client is required for transaction broadcasting when using the IXO MultiClient SDK. - - -## Quick Start - -### Entity Queries -Query entities through the Blocksync API: - -```graphql -query GetEntity($id: String!) { - entity(id: $id) { - id - type - status - } -} -``` - -### Available Data Queries -- Claims and Collections -- Tokens and Swaps -- Bonds and Entities -- Chain Information -- Transaction History - -## Implementation Modules - - - - Create and manage blockchain entities - - - Handle claims and collections - - - Manage tokens and perform swaps - - - Work with blockchain bonds - - - -Each module guide includes: -- Action steps with code examples -- Data retrieval queries -- Optional operations -- Complete function reference - -## Support - -Join our [Slack community](https://ixofoundation.slack.com/archives/C04UERAUHQT) for direct support and access to IXO Guru AI assistant. - -## Next Steps - - - - Learn about available SDKs - - - Explore the Blocksync API - - - View implementation examples - - diff --git a/guides/dev/ixo-claims.mdx b/guides/dev/ixo-claims.mdx index 699a1f2..aa40e71 100644 --- a/guides/dev/ixo-claims.mdx +++ b/guides/dev/ixo-claims.mdx @@ -46,13 +46,29 @@ Expected result: ## See also -- [Identity and credentials](/guides/dev/identity-and-credentials) — how claims relate to DIDs and verifiable credentials -- [Developer workflows](/guides/dev/workflows) — SDK-oriented create and evaluate patterns -- [Blockchain RPC API](/api-reference/rpc-api) -- [Registry API](/api-reference/registry-api) -- [Product and SDK map](/reference/product-and-sdk-map) -- [Networks and endpoints](/reference/networks-and-endpoints) -- [Authentication matrix](/reference/authentication-matrix) + + + See how claims relate to DIDs and verifiable credentials. + + + Follow SDK-oriented create and evaluate patterns. + + + Reference protocol RPC methods and request patterns. + + + Integrate registry endpoints for claim-linked records. + + + Confirm canonical product and SDK naming/routes. + + + Use the correct environment endpoints and chain details. + + + Match each API surface to required credentials. + + ## Troubleshooting @@ -62,4 +78,8 @@ Expected result: ## Next steps -Use the [API introduction](/api-reference/intro-apis) matrix to pick RPC, REST, GraphQL, or Registry for each step of your workflow. + + + Use the API matrix to choose RPC, REST, GraphQL, or Registry for each workflow step. + + diff --git a/guides/dev/ixo-domains.mdx b/guides/dev/ixo-domains.mdx index f2de76d..2a1ba31 100644 --- a/guides/dev/ixo-domains.mdx +++ b/guides/dev/ixo-domains.mdx @@ -1,322 +1,75 @@ --- -title: 'Entity Domains' -description: 'Create and manage digital domains for entities on the IXO Stack' +title: "Entity domains" +description: "How entity domains work on the IXO Protocol, and where to go for concept, task, and SDK details." --- - - Entity Domains provide a standardized way to register and manage digital twins of real-world entities on the IXO blockchain, with built-in support for decentralized identity, verifiable credentials, and relationship management. - - -## Overview - - - - Create and manage decentralized identifiers (DIDs) for entities, enabling sovereign control and cryptographic verification of identity claims. - - - - Establish and verify ownership rights through cryptographic proofs, with support for multiple controllers and delegated authority. - - - - Define and manage service endpoints that connect digital twins to external services, APIs, and data sources. - - - - Associate verifiable claims, documents, and other resources with entity domains to build comprehensive digital representations. - - - - Create and visualize connections between entities to model real-world relationships and dependencies. - - - - Manage financial accounts and transactions associated with entities, enabling economic interactions within the ecosystem. - - - -## Domain Properties - - - - ```typescript - interface DomainProperties { - did: string; // Decentralized identifier - controller: string[]; // Domain controllers - type: string; // Entity type - status: number; // Domain status - credentials: VerifiableCredential[]; // Domain credentials - } - ``` - - - - ```typescript - interface Service { - id: string; // Service identifier - type: string; // Service type - serviceEndpoint: string; // Endpoint URL - description?: string; // Optional description - } - ``` - - - - ```typescript - interface LinkedResource { - id: string; // Resource identifier - type: string; // Resource type - path: string; // Resource location - proof?: string; // Optional cryptographic proof - } - ``` - - - - ```typescript - interface AccordedRight { - type: string; // Right type - description?: string; // Optional description - } - ``` - - - - ```typescript - interface LinkedClaim { - id: string; // Claim identifier - type: string; // Claim type - } - ``` - - - - ```typescript - interface LinkedEntity { - id: string; // Entity identifier - } - ``` - - - - ```typescript - interface DomainAccount { - id: string; // Account identifier - } - ``` - - - -## Domain Registration - - - 1. **Create Domain Document** - - Specify entity type and class - - Define controllers - - Configure services - - Set up linked resources - - 2. **Submit Registration** - - Sign domain creation transaction - - Broadcast to blockchain - - Wait for confirmation - - Verify registration - - 3. **Configure Properties** - - Add verification methods - - Link resources - - Set up services - - Define relationships - - -## Implementation - - - ```typescript Create Domain - import { Entity } from '@ixo/client-sdk'; - - async function createEntityDomain( - creator: string, - entityType: string - ) { - const msg = { - typeUrl: "/ixo.entity.v1beta1.MsgCreateEntity", - value: { - creator, - entityType, - entityStatus: 1 - } - }; - - return await Entity.broadcast(msg); - } - - ```python - - ```typescript Update Domain - async function updateEntityDomain( - id: string, - updates: DomainProperties - ) { - const msg = { - typeUrl: "/ixo.entity.v1beta1.MsgUpdateEntity", - value: { - id, - ...updates - } - }; - - return await Entity.broadcast(msg); - } - ``` - - ```typescript Query Domain - async function queryEntityDomain( - did: string - ) { - const query = ` - query GetEntity($did: String!) { - entity(id: $did) { - id - type - status - controller - services { - id - type - endpoint - } - resources { - id - type - path - } - } - } - `; - - return await client.query({ - query, - variables: { did } - }); - } - ``` - - - -## Domain Management - - - - ```typescript - async function addDomainService( - entityId: string, - service: Service - ) { - const msg = { - typeUrl: "/ixo.entity.v1beta1.MsgAddEntityService", - value: { - entityId, - service - } - }; - - return await Entity.broadcast(msg); - } - ``` - - - - ```typescript - async function addLinkedResource( - entityId: string, - resource: LinkedResource - ) { - const msg = { - typeUrl: "/ixo.entity.v1beta1.MsgAddEntityResource", - value: { - entityId, - resource - } - }; - - return await Entity.broadcast(msg); - } - ``` - - - - ```typescript - async function updateEntityStatus( - entityId: string, - status: number - ) { - const msg = { - typeUrl: "/ixo.entity.v1beta1.MsgUpdateEntityStatus", - value: { - entityId, - status - } - }; - - return await Entity.broadcast(msg); - } - ``` - - - -## Best Practices - - - - - Use strong verification methods - - Implement key rotation - - Maintain controller list - - Document access policies +An **entity domain** is the on-chain representation of a real-world organisation, project, asset, deed, or device on the IXO Protocol. Each domain is anchored by a Decentralized Identifier (DID), governed by one or more controllers, and extended with services, resources, accorded rights, linked claims, relationships, and accounts. + +This page is a routing map. It does not duplicate concept, task, or SDK details — those live on the canonical pages below. + +## Where each detail lives + +| You want to... | Read this | +|---|---| +| Understand the data model and lifecycle | [Domain configuration](/articles/domain-config) | +| Understand the digital-twin model | [Digital twins](/guides/digital-twins) | +| Register a new domain end-to-end | [Domain registration](/guides/domain-registration) | +| Configure controllers, services, resources, rights | [Configure domain settings](/guides/dev/domain-settings) | +| Decide what to keep on protocol vs in IXO Matrix | [Domain privacy patterns](/guides/dev/domain-privacy) | +| Build with the SDK | [IXO MultiClient SDK](/sdk-reference/multiclient-sdk) and [`@ixo/impactxclient-sdk` README](https://github.com/ixofoundation/ixo-multiclient-sdk#readme) | +| Query domains and related state | [Blocksync GraphQL API](/api-reference/blocksync-graphql-api) | +| Inspect raw entity messages and queries | [gRPC gateway API](/api-reference/grpc-gateway-api) | + +## Minimal SDK reference + +Composing entity messages uses the same three-step pattern as every IXO Protocol module: create a query or signing client, compose a message, sign and broadcast. The `@ixo/impactxclient-sdk` package exposes proto-derived message factories under `ixo.*`. + + + The snippet below is a structural reference. For full installation, signer setup, and broadcast patterns see the [IXO MultiClient SDK README](https://github.com/ixofoundation/ixo-multiclient-sdk#readme) and the worked examples in [Developer workflows](/guides/dev/workflows). + + +```ts +import { ixo, createSigningClient } from "@ixo/impactxclient-sdk"; + +const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner); + +const message = { + typeUrl: "/ixo.entity.v1beta1.MsgCreateEntity", + value: ixo.entity.v1beta1.MsgCreateEntity.fromPartial({ + // See the entity proto for the full field set: + // https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo/entity/v1beta1 + ownerAddress: SIGNER_ADDRESS, + entityType: "asset", + context: [], + verification: [], + controller: [], + service: [], + linkedResource: [], + accordedRight: [], + linkedEntity: [], + linkedClaim: [], + }), +}; + +const fee = "auto"; +const response = await signingClient.signAndBroadcast(SIGNER_ADDRESS, [message], fee); +``` + +The full set of entity messages — `MsgCreateEntity`, `MsgUpdateEntity`, `MsgUpdateEntityVerified`, `MsgTransferEntity`, `MsgCreateEntityAccount`, `MsgGrantEntityAccountAuthz`, `MsgRevokeEntityAccountAuthz` — is generated from the [`x/entity` proto definitions](https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo/entity/v1beta1) and exposed under `ixo.entity.v1beta1.*` on the SDK. + +## Next steps + + + + The data model behind every entity domain. - - - - Validate endpoints - - Monitor availability - - Update stale endpoints - - Document service types + + Update controllers, services, resources, and accorded rights. - - - - Verify resource integrity - - Maintain proof chains - - Update broken links - - Document dependencies + + What to keep on protocol vs in IXO Matrix. - - - - Implement access control - - Validate transactions - - Monitor activities - - Regular audits + + The TypeScript SDK that exposes entity messages. - -## Developer Resources - - - - Entity module API documentation - - - - Canonical SDK guide and routing map - - - - Implementation examples - - - - Entity module source code - - - - - For technical support or questions about Entity Domains, join our [Developer Community](https://ixofoundation.slack.com/archives/C04UERAUHQT) or contact our [Developer Relations Team](mailto:assistant@ixo.world). - diff --git a/guides/dev/ixo-stack-sdks.mdx b/guides/dev/ixo-stack-sdks.mdx index 8859343..a06840d 100644 --- a/guides/dev/ixo-stack-sdks.mdx +++ b/guides/dev/ixo-stack-sdks.mdx @@ -1,63 +1,22 @@ --- -title: 'IXO Stack SDKs' -icon: 'code' -description: 'Developer entry point to SDK workflows, with the canonical SDK and kit overview in the SDK reference' +title: "IXO Stack SDKs" +icon: "code" +description: "Pointer page — SDK reference and developer guides for the IXO stack live in the linked locations." --- - -The canonical SDK and kit overview is now maintained at [IXO and Qi Developer Kits](/sdk-reference/index). -Use this page as a developer workflow entry point. - - -## Start here - - - - Choose the right SDK or kit, including Oracles Client SDK, Agentic Oracles ADK, and JAMBO PWA SDK. - - - Follow end-to-end implementation patterns for entities, claims, evaluation, and integrations. - - - Understand DID, claim, and credential relationships used across SDK workflows. - - - Review service and infrastructure APIs used by SDK-based implementations. - - - -## SDK quick links +The IXO Stack SDKs are documented in the [SDK reference](/sdk-reference/index). This page is a routing aid for builders looking for the developer entry point. - - Interchain protocol interactions and entity workflows. - - - Encrypted rooms, messaging, and shared state integrations. - - - Frontend agent-client interfaces for deployed oracles. - - - Scaffold, implement, and deploy oracle services. + + Canonical home for all SDKs and ADKs — types, methods, and install instructions. - - Personal conversational assistant integrations. + + Task-oriented entry point for building on the IXO stack. - - JAMBO PWA integrations with wallet-enabled workflows. - - - User authentication and transaction signing flows. + + End-to-end implementation patterns for entities, claims, evaluation, and integrations. - - Extend IXO services to offline and feature-phone channels. + + Build and run a USSD gateway to extend IXO services to feature phones. For architecture, see [IXO USSD](/articles/ixo-ussd). - -## Next steps - -- [IXO and Qi Developer Kits](/sdk-reference/index) — canonical SDK and kit overview -- [Developer workflows](/guides/dev/workflows) — implementation patterns for domains, claims, and verification -- [API reference](/api-reference/index) — IXO service APIs -- [Developer overview](/guides/dev/overview) — task-oriented entry points diff --git a/guides/dev/liquid-staking.mdx b/guides/dev/liquid-staking.mdx index 1c2f185..65e7e4a 100644 --- a/guides/dev/liquid-staking.mdx +++ b/guides/dev/liquid-staking.mdx @@ -1,133 +1,148 @@ --- -title: 'Managing Liquid Staking' -description: 'Stake and unstake tokens while maintaining liquidity on the IXO blockchain using the IXO MultiClient SDK' +title: "Manage liquid staking" +description: "Stake and unstake IXO tokens through the liquid staking module to receive stIXO." --- - -Liquid staking allows users to stake their tokens while maintaining liquidity through receipt tokens. This enables participation in network security while preserving the ability to transfer or use staked assets. - +The IXO `liquidstake` module lets users stake `uixo` and receive a liquid representation (`stuixo`) that can be transferred and used in bonds, AMMs, and DeFi while underlying delegations earn validator rewards. The module routes stake to a whitelisted validator set with weights, distributes rewards through `weighted_rewards_receivers`, and supports a circuit-breaker pause and burn-to-unstake-instantly for the protocol. -## Performing Liquid Staking +## Before you start -Stake your tokens and receive liquid staking tokens in return. +You need: -```typescript -const response = await MsgLiquidStake( - "1000000uixo", // Amount to stake - "staker_address" // Address of the staker -); +- An IXO account funded with `uixo` for staking and fees on the network you target — see [Networks and endpoints](/reference/networks-and-endpoints). +- An offline signer — see the [SDK README](https://github.com/ixofoundation/ixo-multiclient-sdk#creating-signers). +- Awareness that governance changes (params, whitelisted validators, reward receivers, pause) require `cosmos.gov.v1.MsgSubmitProposal` wrapping the relevant `MsgUpdate*` message — they are not callable directly by users. + +```bash +npm install @ixo/impactxclient-sdk ``` - - When you liquid stake IXO tokens, you receive ZERO liquid staking tokens that represent your staked position. These tokens are used in the IXO Perpetual Carbon Offsetting Protocol. - +```ts +import { ixo, createSigningClient } from "@ixo/impactxclient-sdk"; -## Performing Liquid Unstaking +const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner); +``` -Convert your liquid staking tokens back to the original tokens. +## Stake `uixo` for `stuixo` -```typescript -const response = await MsgLiquidUnstake( - "1000000uixo", // Amount to unstake - "staker_address" // Address of the staker -); -``` +```ts +const stakeMsg = { + typeUrl: "/ixo.liquidstake.v1beta1.MsgLiquidStake", + value: ixo.liquidstake.v1beta1.MsgLiquidStake.fromPartial({ + delegatorAddress: signerAddress, + amount: { denom: "uixo", amount: "1000000" }, + }), +}; -### Unstaking parameters +await signingClient.signAndBroadcast(signerAddress, [stakeMsg], "auto"); +``` - - - - **Type:** `string` - - **Description:** Amount of liquid tokens to unstake - - - - **Type:** `string` - - **Description:** Address of the staker performing the unstaking - - +Stake is distributed across the active whitelisted validator set in proportion to their `target_weight`. The minted `stuixo` amount reflects the current `nav` (net asset value) of the staked pool. -## Governance and Administration +## Unstake `stuixo` for `uixo` -### Submitting Parameter Update Proposals +```ts +const unstakeMsg = { + typeUrl: "/ixo.liquidstake.v1beta1.MsgLiquidUnstake", + value: ixo.liquidstake.v1beta1.MsgLiquidUnstake.fromPartial({ + delegatorAddress: signerAddress, + amount: { denom: "stuixo", amount: "1000000" }, + }), +}; -Create a governance proposal to update liquid staking parameters. +await signingClient.signAndBroadcast(signerAddress, [unstakeMsg], "auto"); +``` -```typescript -const response = await MsgSubmitProposalUpdateLiquidStakeParams( - "proposal_title", // Title of the proposal - "proposal_description", // Description of the proposal - "proposer_address" // Address of the proposer -); +Unstaking enqueues an unbonding entry in the staking module — the underlying `uixo` is returned after the chain unbonding period. + +## Governance-controlled operations + +The following messages cannot be broadcast by ordinary users — they must be wrapped in a `cosmos.gov.v1.MsgSubmitProposal` with the `liquidstake` module's authority as the signer. + +```ts +const updateParamsMsg = ixo.liquidstake.v1beta1.MsgUpdateParams.fromPartial({ + authority: govAuthority, + params: ixo.liquidstake.v1beta1.Params.fromPartial({ + liquidBondDenom: "stuixo", + }), +}); + +const updateValidatorsMsg = ixo.liquidstake.v1beta1.MsgUpdateWhitelistedValidators.fromPartial({ + authority: govAuthority, + whitelistedValidators: [ + ixo.liquidstake.v1beta1.WhitelistedValidator.fromPartial({ + validatorAddress: "ixovaloper1...", + targetWeight: "1", + }), + ], +}); + +const updateReceiversMsg = ixo.liquidstake.v1beta1.MsgUpdateWeightedRewardsReceivers.fromPartial({ + authority: govAuthority, + weightedRewardsReceivers: [ + ixo.liquidstake.v1beta1.WeightedAddress.fromPartial({ + address: "ixo1treasury...", + weight: "1", + }), + ], +}); + +const pauseMsg = ixo.liquidstake.v1beta1.MsgSetModulePaused.fromPartial({ + authority: govAuthority, + paused: true, +}); ``` -### Managing Whitelisted Validators +Wrap these as gov proposals using `cosmos.gov.v1.MsgSubmitProposal` (see the Cosmos SDK [gov module documentation](https://docs.cosmos.network/main/build/modules/gov)). -Update the list of validators that can receive delegations from the liquid staking pool. +## Burn-to-unstake (admin) -```typescript -const response = await MsgUpdateWhitelistedValidators( - ["validator1_address", "validator2_address"], // List of validator addresses - "admin_address" // Address of the admin -); +```ts +const burnMsg = { + typeUrl: "/ixo.liquidstake.v1beta1.MsgBurn", + value: ixo.liquidstake.v1beta1.MsgBurn.fromPartial({ + address: signerAddress, + amount: { denom: "stuixo", amount: "1000000" }, + }), +}; ``` - - Only whitelisted validators can receive delegations from the liquid staking module. This helps maintain security and reliability of the staking pool. - +`MsgBurn` removes `stuixo` from circulation without queuing an unbonding — used by the protocol to reconcile the supply. -## Liquid Staking Function Reference +## Verify the result - - - Stakes tokens and receives liquid tokens. - - **Parameters:** `amount: string, staker: string` - +Query staked balances and `stuixo` supply through the [gRPC gateway API](/api-reference/grpc-gateway-api) and `ixo.liquidstake.v1beta1` endpoints. Underlying delegations and unbonding entries are visible through the standard `cosmos.staking.v1beta1` queries. - - Unstakes liquid tokens back to original tokens. +## Troubleshooting - **Parameters:** `amount: string, staker: string` + + + `MsgLiquidStake` fails when the whitelist is empty. Wait for a governance proposal to populate `whitelisted_validators` before staking. - - - Submits parameter update proposal. - - **Parameters:** `title: string, description: string, proposer: string` + + When `MsgSetModulePaused` is `true`, all user-initiated stake/unstake messages are rejected. Check params via the gov query. - - - Updates the list of allowed validators. - - **Parameters:** `validators: string[], admin: string` + + `MsgLiquidStake.amount.denom` must equal the chain `bond_denom` (typically `uixo`). `MsgLiquidUnstake.amount.denom` must equal `liquid_bond_denom` (typically `stuixo`). + + + `MsgUpdateParams`, `MsgUpdateWhitelistedValidators`, `MsgUpdateWeightedRewardsReceivers`, and `MsgSetModulePaused` only accept the gov authority address as `authority`. -## Module Parameters - - - - **Whitelisted Validators**: List of validators eligible to receive delegations - - **Liquid Bonding Period**: Time required for unbonding liquid staked tokens - - **Fee Parameters**: Protocol fees for staking/unstaking operations - - **Minimum Stake**: Minimum amount that can be liquid staked - - -## Troubleshooting - - - - Ensure the staker has sufficient balance for the operation - - Verify the amount is within allowed limits (above minimum stake) - - Check that the staking token is supported by the module - - - - - Confirm the validator addresses are correctly formatted - - Verify the admin has the necessary permissions to update validators - - Ensure the validators are active on the network - - - - - Check that the proposal title and description meet required formats - - Verify the proposer has sufficient tokens for proposal deposit - - Ensure the parameters being proposed are valid - +## Next steps + + + + Module-level features and types. + + + Source of truth for liquid staking messages. + + + Use `stuixo` as a reserve token in bonds. + + + Submit governance proposals for `liquidstake` updates. + + diff --git a/guides/dev/overview.mdx b/guides/dev/overview.mdx index b78cb1e..5421ef9 100644 --- a/guides/dev/overview.mdx +++ b/guides/dev/overview.mdx @@ -16,7 +16,7 @@ description: 'Build AI-operable workflows on IXO: SDKs, APIs, and paths from sha Browse TypeScript SDKs and deployable gateway tools, including the IXO MultiClient SDK, IXO Matrix Client SDK, and IXO USSD gateway - + REST, RPC, GraphQL, and service API interfaces for IXO Protocol and application services @@ -63,7 +63,7 @@ description: 'Build AI-operable workflows on IXO: SDKs, APIs, and paths from sha - The IXO Protocol is a Cosmos SDK blockchain for coordinating, financing, and verifying real-world impacts. Core modules cover entity management, claims, tokens, bonds, and smart accounts. [Read the protocol overview](/articles/ixo-protocol). + The IXO Protocol is a Cosmos SDK blockchain for coordinating, financing, and verifying real-world impacts. Core modules cover entity management, claims, tokens, bonds, and smart accounts. [Read the protocol overview](/protocols/ixo-protocol). Domains are on-chain representations of real-world entities — organisations, projects, assets, and devices. Each domain has a Decentralized Identifier (DID), controllers, services, and a linked IXO Matrix data room. [Learn about digital twins](/guides/digital-twins). diff --git a/guides/dev/session-keys.mdx b/guides/dev/session-keys.mdx index 8feab0b..360cde4 100644 --- a/guides/dev/session-keys.mdx +++ b/guides/dev/session-keys.mdx @@ -1,175 +1,161 @@ --- -title: 'Session Keys' -description: 'Implement one-click signing in IXO web applications using session-based keys' +title: "Session signing with SignX" +description: "Sign transactions in browser apps without per-action wallet confirmations using the SignX SDK and the user's Impacts X mobile wallet." --- - - Session keys enable streamlined transaction signing in IXO web applications through Smart Accounts and secure mobile wallet integration. - +The IXO `@ixo/signx-sdk` orchestrates mobile-to-web authentication and transaction signing through QR code scanning by the Impacts X mobile wallet. A web app generates a QR code, the user scans it with their Impacts X app, and the SDK long-polls a relayer server until the wallet returns either a login payload or a signed-and-broadcast transaction. Once a transaction session is open, additional transactions are added to the same session without re-scanning the QR — the wallet activates the next transaction in sequence on each broadcast. -## Overview +This is the publicly documented signing path. There is no in-browser private key — every signature comes from the user's mobile wallet. -Session-based signing keys allow users to: -- Sign multiple transactions without repeated wallet confirmations -- Maintain security through time-limited authorizations -- Restrict signing capabilities to specific transaction types -- Control access through their IXO Mobile wallet +## Before you start -## Core Components +You need: - - - Flexible authentication system separating fee payment from transaction authorization - +- A web app (React or other) running over HTTPS. +- A reachable [`ixo-message-relayer`](https://github.com/ixofoundation/ixo-message-relayer) endpoint, or an IXO-operated equivalent for your network — see [Networks and endpoints](/reference/networks-and-endpoints). +- The Impacts X mobile app installed by your user ([App Store](https://apps.apple.com/app/impacts-x/id6444948058) / [Play Store](https://play.google.com/store/apps/details?id=com.ixo.mobile)). +- `@ixo/signx-sdk` and `@ixo/impactxclient-sdk` installed: - - Time-limited browser-based keys for specific transaction types - +```bash +npm install @ixo/signx-sdk @ixo/impactxclient-sdk +``` - - Master key control and authorization management - - +## Initialize the SignX client -## Implementation Flow +```ts +import { SignX } from "@ixo/signx-sdk"; - - 1. **Initial Access** - - User opens IXO web application - - System generates authorization request - - QR code displayed with SignX message +const signXClient = new SignX({ + endpoint: "https://your-message-relayer.example.com", + sitename: "Your dApp", + network: "mainnet", +}); +``` - 2. **Mobile Authorization** - - User scans QR with IXO Mobile - - Wallet validates SignX message - - User confirms authorization +`network` is one of `mainnet | testnet | devnet`. The `sitename` is shown to the user inside the Impacts X app on every confirmation. - 3. **Session Establishment** - - Browser receives signed payload - - Session key generated locally - - Transaction permissions configured - +## Log the user in -## Transaction Processing +`login()` returns the QR payload to render and starts long-polling for the wallet's response. Subscribe to `SIGN_X_LOGIN_SUCCESS` and `SIGN_X_LOGIN_ERROR` to receive the result. - - - ```typescript - try { - // 1. Create transaction - const tx = { - typeUrl: "/ixo.entity.v1beta1.MsgCreateEntity", - value: entityData - }; - - // 2. Sign with session key - const signedTx = await sessionKey.sign(tx); - - // 3. Broadcast to network - const result = await client.broadcast(signedTx); - - return result; - } catch (error) { - if (error.code === 'SESSION_EXPIRED') { - // Handle session expiry - await refreshSession(); - } else if (error.code === 'UNAUTHORIZED_TX_TYPE') { - // Handle unauthorized transaction type - throw new Error('Transaction type not allowed with current session key'); - } else { - // Handle other errors - throw error; - } - } - ``` - +```ts +const loginRequest = await signXClient.login({ matrix: true }); - - ```typescript - // Session key configuration - const sessionConfig = { - duration: "1h", // Time limit - allowedTypes: [ // Permitted transactions - "MsgCreateEntity", - "MsgUpdateEntity" - ], - restrictions: { // Optional limits - maxTransactions: 100, - maxAmount: "1000uixo" - }, - network: { // Network configuration - chainId: "ixo-5", - rpcUrl: "https://rpc.ixo.world" - } - }; - ``` - +signXClient.on("SIGN_X_LOGIN_SUCCESS", (event) => { + const { name, address, pubKey, did, algo, matrix } = event.data; + // persist the user; pubKey is hex-encoded, decode if you need bytes. +}); - - ```typescript - // Monitor session status - sessionKey.on('expiring', async (timeLeft) => { - if (timeLeft < 300000) { // 5 minutes - await notifyUser('Session expiring soon'); - } - }); - - // Handle session cleanup - window.addEventListener('beforeunload', () => { - sessionKey.cleanup(); - }); - ``` - - +signXClient.on("SIGN_X_LOGIN_ERROR", (error) => { + // user cancelled, polling timed out, or the wallet returned an error. +}); +``` -## Security Considerations +Pass `{ useDeeplink: true }` on mobile devices so the SDK opens the Impacts X app via deeplink before polling — this prevents some mobile browsers from cancelling the long-polling request when the user navigates away. - - - - Automatic session expiration - - Configurable duration - - Forced re-authorization - +## Sign and broadcast a transaction - - - Transaction type restrictions - - Optional spending limits - - Granular permissions - +Build the transaction body using the `@ixo/impactxclient-sdk` registry, then pass the hex-encoded `txBody` to `signXClient.transact()`. The wallet signs the transaction and broadcasts it on the user's behalf. - - - Mobile wallet control - - Session revocation - - Access monitoring - - +```ts +import { createRegistry, ixo } from "@ixo/impactxclient-sdk"; +import { toHex } from "@cosmjs/encoding"; + +const registry = createRegistry(); + +const messages = [ + { + typeUrl: "/ixo.entity.v1beta1.MsgCreateEntity", + value: ixo.entity.v1beta1.MsgCreateEntity.fromPartial({ + ownerAddress: user.address, + entityType: "asset", + context: [], + verification: [], + controller: [], + service: [], + linkedResource: [], + accordedRight: [], + linkedEntity: [], + linkedClaim: [], + }), + }, +]; + +const txBodyHex = toHex(registry.encodeTxBody({ messages, memo: "" })); + +const transactRequest = await signXClient.transact({ + address: user.address, + did: user.did, + pubkey: user.pubKey, + timestamp: new Date().toISOString(), + transactions: [{ sequence: 1, txBodyHex }], +}); + +signXClient.on("SIGN_X_TRANSACT_SUCCESS", (event) => { + // event.data.transactionHash, event.data.code (0 on success) +}); -## Best Practices +signXClient.on("SIGN_X_TRANSACT_ERROR", (error) => { + // wallet rejected, broadcast failed, or session timed out. +}); +``` + +If `transactRequest.sessionHash` is present a new session was opened — render a QR with `transactRequest`. If it is absent the transaction was added to the existing session — call `signXClient.pollNextTransaction()` and update the UI to indicate the next signature is pending in the wallet. + +The wallet returns the chain's broadcast result (`code`, `transactionHash`, …) directly through `SIGN_X_TRANSACT_SUCCESS`. + +## Manage the session + +Every transaction extends the session's `validUntil` timestamp. Inspect `signXClient.transactSessionHash` to know whether a session is active and `signXClient.transactSequence` for the current sequence the wallet is being asked to sign. + +```ts +window.addEventListener("beforeunload", () => { + signXClient.stopPolling("Page closing", "SIGN_X_TRANSACT_ERROR"); +}); +``` + +Sessions are intentionally not persisted across browser refresh — `transactSessionHash` lives in memory only. After a refresh, the next `transact()` call starts a new session and renders a fresh QR. + +## Transaction-type restrictions + +Restricting which message types a session can sign is enforced **on the wallet** — the Impacts X app inspects each transaction body against the user's saved policy before signing. The web SDK does not impose its own filter. To restrict the messages a session can sign in your dApp, build the txBody only for the message types your flow needs and refuse to call `transact()` for anything else; pair this with smart-account authenticators (see [Manage smart accounts](/guides/dev/smart-accounts)) for an on-chain enforcement layer. + +When you build a `MsgGrant` (`cosmos.authz.v1beta1.MsgGrant`) with a `GenericAuthorization`, the `msg` field is the **fully qualified message URL**, e.g. `/ixo.entity.v1beta1.MsgCreateEntity`. The same convention applies everywhere transaction filtering is configured. + +## Verify the result + +`SIGN_X_TRANSACT_SUCCESS` returns the transaction hash directly. To independently verify, query `cosmos.tx.v1beta1.GetTx` on the [gRPC gateway API](/api-reference/grpc-gateway-api) with that hash, or fetch the transaction from the [Blocksync GraphQL API](/api-reference/blocksync-graphql-api). + +## Troubleshooting - - - Validate QR code sources - - Handle session expiry gracefully - - Implement proper error handling - - Monitor session status + + Confirm `endpoint` points to a reachable Message Relayer for the same `network` as the user's wallet, and that `network` matches the chain the user logged in on. Check the relayer is healthy. - - - - Use appropriate session durations - - Restrict transaction types - - Monitor active sessions - - Implement session cleanup + + Mobile browsers may cancel ongoing requests when navigating to deeplinks. Pass `useDeeplink: true` to `login`, `matrixLogin`, `dataPass`, and as the third argument to `transact` so the SDK opens the deeplink first and waits 300 ms before polling. + + + The wallet may reject if the message type is outside the user's signing policy, the chain ID does not match, or the user manually denies. `SIGN_X_TRANSACT_ERROR` carries the reason. Re-issue the transaction after the user adjusts their policy. + + + `transactSessionHash` is cleared when the relayer reports the session expired. The next `transact()` call starts a new session — surface this to the user (a fresh QR is needed). Call `stopPolling(message, event, false)` to stop polling without clearing the session if you want to retain it. -## Related Resources +## Next steps - - - Learn about IXO Smart Account system + + + Methods, events, and types. - - - Implement secure transaction signing + + Source of truth for the SDK. + + + Add on-chain enforcement of which message types may be signed. + + + Combine SignX with Cosmos `x/authz` and `x/feegrant`. diff --git a/guides/dev/smart-accounts.mdx b/guides/dev/smart-accounts.mdx index 550630b..d478196 100644 --- a/guides/dev/smart-accounts.mdx +++ b/guides/dev/smart-accounts.mdx @@ -1,166 +1,155 @@ --- -title: 'Managing Smart Accounts' -description: 'Create and configure accounts with advanced authentication capabilities on the IXO blockchain using the IXO MultiClient SDK' +title: "Manage smart accounts" +description: "Add, remove, and toggle authenticators on IXO smart accounts to extend Cosmos SDK signing with conditional rules." --- - -Smart accounts provide a robust and extensible framework for authenticating transactions on the IXO blockchain. Unlike traditional authentication methods, smart accounts allow you to use multiple types of authenticators, each with their own set of rules and conditions for transaction approval. - +The IXO `smartaccount` module replaces the default Cosmos SDK signature ante handler with an opt-in pluggable system. Each account can register one or more **authenticators** — signature verifiers, message filters, spend-limit contracts, or composite logic — that execute on every transaction the account opts in to. If no authenticators are selected, transactions fall back to the standard Cosmos SDK signature flow. -## Understanding Smart Accounts +## Before you start - - Smart accounts operate as a replacement for the default Cosmos SDK authentication mechanism through an ante handler (executed before transaction messages are processed). Key components include: - - - **Circuit Breaker**: Allows the module to be disabled if necessary - - **Authenticator Selection**: Users opt-in to using authenticators for each message - - **Authenticator Execution**: Multiple authenticators can be combined to create complex authentication logic - +You need: - - If no authenticators are selected, transactions default to the classic Cosmos SDK authentication method using standard signatures. - +- An IXO account with `uixo` for fees on the network you target — see [Networks and endpoints](/reference/networks-and-endpoints). +- An offline signer — see the [SDK README](https://github.com/ixofoundation/ixo-multiclient-sdk#creating-signers). +- An authenticator type and config payload to register. The supported types are defined in the [smartaccount types proto](https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo/smartaccount/v1beta1). -## Managing Authenticators - -### Adding an Authenticator +```bash +npm install @ixo/impactxclient-sdk +``` -Add a new authenticator to a smart account to enhance its security capabilities. +```ts +import { ixo, createSigningClient } from "@ixo/impactxclient-sdk"; -```typescript -const response = await MsgAddAuthenticator( - "smart_account_address", // Address of the smart account - "authenticator_address" // Address of the authenticator -); +const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner); ``` -### Removing an Authenticator +## Add an authenticator -Remove an authenticator from a smart account when it's no longer needed. +```ts +const addAuthenticatorMsg = { + typeUrl: "/ixo.smartaccount.v1beta1.MsgAddAuthenticator", + value: ixo.smartaccount.v1beta1.MsgAddAuthenticator.fromPartial({ + sender: signerAddress, + authenticatorType: "SignatureVerification", + data: new TextEncoder().encode(JSON.stringify({ pubkey: pubkeyHex })), + }), +}; -```typescript -const response = await MsgRemoveAuthenticator( - "smart_account_address", // Address of the smart account - "authenticator_address" // Address of the authenticator -); +await signingClient.signAndBroadcast(signerAddress, [addAuthenticatorMsg], "auto"); ``` -## Using Smart Accounts +The chain assigns an `id` to each authenticator on success. Read it from transaction events to reference the authenticator in subsequent transactions. + +## Remove an authenticator -### Sending Transactions with Authenticators +```ts +const removeAuthenticatorMsg = { + typeUrl: "/ixo.smartaccount.v1beta1.MsgRemoveAuthenticator", + value: ixo.smartaccount.v1beta1.MsgRemoveAuthenticator.fromPartial({ + sender: signerAddress, + id: 1n, + }), +}; +``` + +## Pause the module (governance) -Execute a transaction that uses the smart account's authenticator for verification. +`MsgSetActiveState` is the circuit breaker — only the module's gov authority can broadcast it. -```typescript -const response = await MsgSendWithAuthenticator( - "smart_account_address", // Address of the smart account - "recipient_address", // Address of the recipient - "1000000uixo" // Amount to send -); +```ts +const setActiveMsg = ixo.smartaccount.v1beta1.MsgSetActiveState.fromPartial({ + authority: govAuthority, + active: false, +}); ``` -## Composite Authenticators +When `active` is `false`, the smart-account ante handler is skipped and all transactions use the default Cosmos SDK signature path. + +## Use authenticators on a transaction -Smart accounts support composite authenticators that combine multiple authentication methods for enhanced security and flexibility. +A transaction opts in to specific authenticators via the **`AuthenticatorTxExtension`** TX extension. The full pattern depends on your signing flow — see the [smartaccount module README](https://github.com/ixofoundation/ixo-blockchain/tree/main/x/smartaccount) and the [README for the IXO MultiClient SDK](https://github.com/ixofoundation/ixo-multiclient-sdk) for current helpers. The extension carries the list of authenticator IDs to use for each signer. -### Composite authenticator types +## Composite authenticators + +Composite authenticators combine sub-authenticators using boolean logic. - - **Description:** Requires all sub-authenticators to approve - - **Logic:** `authenticate(a) && authenticate(b) && ...` + Approves only when every sub-authenticator approves: `auth(a) && auth(b) && ...`. - - **Description:** Requires at least one sub-authenticator to approve - - **Logic:** `authenticate(a) || authenticate(b) || ...` + Approves when at least one sub-authenticator approves: `auth(a) || auth(b) || ...`. + + + Multi-signature where signatures are split across sub-authenticators (one signer per sub-authenticator). -### Example Configurations - - - ``` - AllOf( - SignatureVerification(usersPubKey), - AnyOf( - MessageFilter(SwapMsg1), - MessageFilter(SwapMsg2) - ), - CosmwasmAuthenticator(spendLimitContract, params) - ) - ``` - This configuration allows a hot key to execute only swap messages and fails if the transaction would leave the user with a balance below a certain threshold. - - - - ``` - PartitionedAllOf(pubkey1, pubkey2, pubkey3) - ``` - This creates a simple multi-signature scheme requiring signatures from multiple keys to authorize transactions. - - - - ``` - AllOf( - SignatureVerification(cosignerPubKey), - AnyOf(...user_authenticators) - ) - ``` - This requires an off-chain cosigner service to approve all transactions, providing an additional layer of security. - - -## Smart Account Function Reference +Example shapes: + +```text +// One-click trading: hot key restricted to swap messages with on-chain spend-limit guard +AllOf( + SignatureVerification(usersPubKey), + AnyOf( + MessageFilter(SwapMsg1), + MessageFilter(SwapMsg2) + ), + CosmwasmAuthenticator(spendLimitContract, params) +) + +// Multisig (2-of-3): each signer satisfies one branch +PartitionedAllOf(pubkey1, pubkey2, pubkey3) + +// Cosigner protection: cosigner approves alongside a user-selected set +AllOf( + SignatureVerification(cosignerPubKey), + AnyOf(...userAuthenticators) +) +``` - - - Adds an authenticator to a smart account. +## Authentication phases - **Parameters:** `smartAccount: string, authenticator: string` - +Each authenticator runs through a three-phase lifecycle on every transaction: - - Removes an authenticator from a smart account. +1. **Authenticate** — verify the transaction is authorized. +2. **Track** — record any state changes the authenticator needs (committed regardless of transaction outcome). +3. **Confirm execution** — validate the post-execution effects. - **Parameters:** `smartAccount: string, authenticator: string` - +## Verify the result - - Sends a transaction using an authenticator. +Query an account's authenticators through the `ixo.smartaccount.v1beta1.Query/AccountAuthenticators` endpoint on the [gRPC gateway API](/api-reference/grpc-gateway-api). Module params (including `is_smart_account_active`) are read from `Query/Params`. - **Parameters:** `smartAccount: string, recipient: string, amount: string` +## Troubleshooting + + + + `authenticatorType` must match one of the registered types in the chain's `smartaccount` module. Check `Query/Params.maximum_unauthenticated_gas` and the module's registered types. + + + `MsgRemoveAuthenticator` fails when `id` does not exist for `sender`. Query `AccountAuthenticators` to confirm the id. + + + When `is_smart_account_active` is `false`, `MsgAddAuthenticator` and `MsgRemoveAuthenticator` are rejected. The module is gated by gov via `MsgSetActiveState`. + + + Ensure the TX extension lists the correct authenticator IDs in the order matching the signer set, and that the data payload registered with `MsgAddAuthenticator` is the canonical encoding for that authenticator type. -## Authentication Lifecycle - -Smart account authentication follows a three-phase process to ensure security and flexibility: - - - 1. **Authenticate**: Verifies the transaction is authorized - 2. **Track**: Records any state changes required for authentication, committed regardless of transaction success - 3. **Confirm Execution**: Allows authenticators to validate the transaction's effects post-execution - - -## Troubleshooting - - - - Ensure the smart account and authenticator addresses are correctly formatted - - Verify the authenticator is authorized for the operation - - Check that the authenticator ID is valid and exists on the account - - - - - Confirm the smart account has sufficient balance for the transaction and fees - - Verify the recipient address is valid - - Check that the authentication logic is correctly configured - - - - - Ensure all required signatures are provided for partitioned authenticators - - Verify the composition logic matches your security requirements - - Check that each sub-authenticator is correctly configured - - - - Smart accounts are currently controlled by a "circuit breaker" parameter (`is_smart_account_active`). If this parameter is set to false, the module will not be used and transactions will fall back to classic Cosmos SDK authentication. - +## Next steps + + + + Module-level features and types. + + + Source of truth for smart-account messages. + + + Issue scoped session keys backed by smart-account authenticators. + + + Use Cosmos authz alongside smart-account authenticators. + + diff --git a/guides/dev/tokens.mdx b/guides/dev/tokens.mdx index 142f380..586dc7a 100644 --- a/guides/dev/tokens.mdx +++ b/guides/dev/tokens.mdx @@ -1,260 +1,218 @@ --- -title: 'Managing Tokens' -description: 'Create, mint, transfer, and manage EIP-1155 compatible tokens on the IXO blockchain using the IXO MultiClient SDK' +title: "Manage tokens" +description: "Create, mint, transfer, retire, and govern IXO Protocol tokens with the IXO MultiClient SDK." --- - -The Token module implements EIP-1155 compatible multi-token smart contracts on the IXO blockchain. This standard supports both fungible and non-fungible tokens within a single contract, allowing for efficient batch operations and versatile token management. - +The IXO Protocol token module wraps the `ixo1155` smart contract — a CosmWasm implementation of the EIP-1155 multi-token standard. Each token domain has a token class (entity DID), a fixed cap, and supports both fungible and non-fungible balances within a single contract. -## Creating a Token Domain +This guide shows the chain-level message patterns. For the data model and contract details, read the [`x/token` proto definitions](https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo/token/v1beta1) and the [`@ixo/impactxclient-sdk` README](https://github.com/ixofoundation/ixo-multiclient-sdk#readme). -Create a new token domain with defined properties and parameters. +## Before you start -```typescript -const response = await CreateToken( - "TokenName", // Name of the token - "Token Description", // Description of the token - 1000000, // Cap (maximum supply) of the token - "TokenClass" // Class of the token -); -``` +You need: -### Token domain creation parameters +- An IXO account with sufficient `uixo` for fees on the network you target — see [Networks and endpoints](/reference/networks-and-endpoints). +- An offline signer — see the [SDK README on creating signers](https://github.com/ixofoundation/ixo-multiclient-sdk#creating-signers). +- The token protocol entity DID (the value used as `class`). Token class is validated against an existing entity. +- For minting, a deployed token contract address (set via `MsgCreateToken`). +- For credit transfers, a valid `WithdrawPaymentAuthorization` if you act on behalf of another account — see [Custom authorisations for IXO Claims](/guides/dev/authz-custom). - - - - **Type:** `string` - - **Description:** The name of the token - - - - **Type:** `string` - - **Description:** A brief description of the token - - - - **Type:** `number` - - **Description:** The maximum supply of the token - - - - **Type:** `string` - - **Description:** The class or category of the token - - - - **Type:** `WalletUsers` - - **Description:** Wallet user signing the transaction - - - - - Token classes determine the behavior and properties of tokens. Common classes include "carbon", "impact", and "governance". - - -## Minting Tokens - -Issue new tokens for a specified contract in batches. - -```typescript -const response = await MintToken( - "contractAddress1234", // Contract address for the token - [ - { - name: "Batch1", - index: "1", - amount: 1000, - collection: "Collection1" - } - ] -); +```bash +npm install @ixo/impactxclient-sdk ``` -### Batch minting structure - - - - - **Type:** `string` - - **Description:** Identifier for the batch - - - - **Type:** `string` - - **Description:** Unique index within the collection - - - - **Type:** `number` - - **Description:** Quantity of tokens to mint - - - - **Type:** `string` - - **Description:** Collection the batch belongs to - - - -## Transferring Tokens +```ts +import { ixo, createSigningClient } from "@ixo/impactxclient-sdk"; -Transfer tokens to another address individually or in batches. - -```typescript -const response = await TransferToken( - [ - { - id: "tokenId1234", // ID of the token - amount: 100 // Amount to transfer - } - ], - "recipientAddress1234" // Address of the recipient -); +const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner); ``` -### Batch Transfers - -For transferring multiple tokens in a single transaction: - -```typescript -const response = await TransferTokenBatch( - [ - { id: "tokenId1", amount: 100 }, - { id: "tokenId2", amount: 50 } - ], - "recipientAddress1234" -); +## Create a token + +`MsgCreateToken` registers a new token name under a token-protocol entity. Cap `"0"` means unlimited supply. + +```ts +const createMsg = { + typeUrl: "/ixo.token.v1beta1.MsgCreateToken", + value: ixo.token.v1beta1.MsgCreateToken.fromPartial({ + minter: signerAddress, + class: "did:ixo:entity:protocol123", + name: "CARBON", + description: "Verified carbon offset units", + image: "ipfs://bafy.../image.png", + tokenType: "ixo1155", + cap: "1000000", + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [createMsg], "auto"); ``` -## Token Lifecycle Management - -### Retiring Tokens - -Retire tokens to remove them from circulation while maintaining their transaction history. - -```typescript -const response = await RetireToken( - "tokenId1234", // ID of the token - 100 // Amount to retire -); +## Mint tokens + +`MsgMintToken` issues new units in batches against an existing token contract. Each batch references a unique `index` and a `collection` DID. + +```ts +const mintMsg = { + typeUrl: "/ixo.token.v1beta1.MsgMintToken", + value: ixo.token.v1beta1.MsgMintToken.fromPartial({ + minter: signerAddress, + contractAddress: tokenContractAddress, + owner: ownerAddress, + mintBatch: [ + ixo.token.v1beta1.MintBatch.fromPartial({ + name: "CARBON", + index: "bafkreih...", + amount: "1000", + collection: "did:ixo:entity:collection456", + tokenData: [], + }), + ], + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [mintMsg], "auto"); ``` -### Stopping Tokens - -Permanently halt all operations for a token. +## Transfer tokens + +`MsgTransferToken` moves balances between accounts. All tokens in a single message must belong to the same contract. + +```ts +const transferMsg = { + typeUrl: "/ixo.token.v1beta1.MsgTransferToken", + value: ixo.token.v1beta1.MsgTransferToken.fromPartial({ + owner: signerAddress, + recipient: recipientAddress, + tokens: [ + ixo.token.v1beta1.TokenBatch.fromPartial({ + id: "bafkreih...", + amount: "100", + }), + ], + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [transferMsg], "auto"); +``` -```typescript -const response = await StopToken( - "tokenId1234" // ID of the token -); +## Retire tokens + +`MsgRetireToken` permanently removes tokens from circulation while preserving their on-chain history. Use this for end-claims such as voluntary carbon retirement. + +```ts +const retireMsg = { + typeUrl: "/ixo.token.v1beta1.MsgRetireToken", + value: ixo.token.v1beta1.MsgRetireToken.fromPartial({ + owner: signerAddress, + tokens: [ + ixo.token.v1beta1.TokenBatch.fromPartial({ + id: "bafkreih...", + amount: "50", + }), + ], + jurisdiction: "ZA-WC-7700", + reason: "Voluntary retirement on behalf of buyer X", + }), +}; ``` -### Transferring Tokens -Put tokens into a "transferred" state when these are moved to a different registry system. This specifically applies to Internationally Transferred Mitigation Outcomes (ITMOs) - standardized units representing greenhouse gas emission reductions that can be transferred between countries under Article 6.2 of the Paris Agreement. +The `jurisdiction` field follows the format `[-[-]]`. Only the country code is required. + +## Transfer credit (ITMO state change) + +`MsgTransferCredit` flips tokens to a "transferred" state when units are moved off-protocol to a different registry — for example, Internationally Transferred Mitigation Outcomes (ITMOs) under Article 6.2 of the Paris Agreement. It accepts an optional `authorization_id` for delegated transfers. + +```ts +const creditTransferMsg = { + typeUrl: "/ixo.token.v1beta1.MsgTransferCredit", + value: ixo.token.v1beta1.MsgTransferCredit.fromPartial({ + owner: signerAddress, + tokens: [ + ixo.token.v1beta1.TokenBatch.fromPartial({ + id: "bafkreih...", + amount: "100", + }), + ], + jurisdiction: "CH", + reason: "ITMO transfer to Swiss national registry", + authorizationId: "auth-2025-001", + }), +}; +``` -```typescript -const response = await TransferToken( - "tokenId1234", // ID of the token - 100 // Amount to transfer -); +## Cancel, pause, or stop a token + +| Operation | Message | Effect | +|---|---|---| +| Cancel batches | `MsgCancelToken` | Owner cancels specific token batches with a reason. | +| Pause minting | `MsgPauseToken` | Minter halts further minting on a contract. `paused: true` to halt, `false` to resume. | +| Stop the contract | `MsgStopToken` | Minter permanently stops the token contract. Irreversible. | + +```ts +const pauseMsg = { + typeUrl: "/ixo.token.v1beta1.MsgPauseToken", + value: ixo.token.v1beta1.MsgPauseToken.fromPartial({ + minter: signerAddress, + contractAddress: tokenContractAddress, + paused: true, + }), +}; ``` -## Querying Token Data +## Verify the result -Retrieve token information using the IXO Blocksync GraphQL API. +Query token state through the [Blocksync GraphQL API](/api-reference/blocksync-graphql-api): ```graphql -query MyQuery { - token(id: "tokenId1234") { +query Token($id: String!) { + token(id: $id) { id name description cap class - owner + minter minted transferred + retired + cancelled } } ``` -## Token Function Reference +Or read directly from the token contract via the [gRPC gateway API](/api-reference/grpc-gateway-api). - - - Creates a new token. - - **Parameters:** `name: string, description: string, cap: number, tokenClass: string, signer?: WalletUser` - - - - Mints new tokens. - - **Parameters:** `contractAddress: string, batches: MintBatch[]` - - - - Transfers tokens. - - **Parameters:** `tokens: TokenBatch[], toAddress?: string` - - - - Transfers multiple tokens. - - **Parameters:** `tokens: TokenBatch[], toAddress: string` - - - - Retires tokens. +## Troubleshooting - **Parameters:** `tokenId: string, amount: number` + + + `class` must be a valid entity DID for an existing token-protocol entity. Confirm the entity exists and that you control it. - - - Stops token operations. - - **Parameters:** `tokenId: string` + + `MsgMintToken` will fail if the new total would exceed the token `cap`. Either raise the cap by recreating the token or split issuance across additional token names. - - - Grants contract authorization. - - **Parameters:** `granter: string, grantee: string, contractId: string, msgTypeUrl: string` + + Minting is rejected on paused contracts and on stopped contracts. Issue `MsgPauseToken` with `paused: false` to resume; `MsgStopToken` cannot be reversed. - - - Executes contract operations. - - **Parameters:** *Varies by implementation* + + Delegated `MsgTransferCredit` requires a `WithdrawPaymentAuthorization` referencing the supplied `authorization_id`. See [Custom authorisations for IXO Claims](/guides/dev/authz-custom). -## Token Properties - - - - **ID**: Unique identifier for the token - - **Name**: Human-readable name - - **Description**: Detailed description - - **Cap**: Maximum supply limit - - **Class**: Category determining behavior - - **Owner**: Address controlling the token - - **Minted**: Amount already created - - **Transferred**: Amount sent to other addresses - - **Retired**: Amount removed from circulation - - -## Troubleshooting - - - - Ensure the token name is unique - - Verify the cap is a positive number - - Check that the token class is supported - - Confirm the signer has sufficient permissions - - - - - Verify the contract address is correct - - Ensure the batch details are properly formatted - - Check that minting won't exceed the token cap - - Confirm you have authorization to mint - - - - - Verify the recipient address is valid - - Ensure sufficient token balance - - Check that the token ID exists - - Confirm the token is not paused or stopped - +## Next steps + + + + Full SDK reference including signing client setup. + + + Source of truth for token messages. + + + Add bonding-curve pricing and reserves to tokens. + + + Delegate token operations safely. + + diff --git a/guides/dev/ussd-gateway.mdx b/guides/dev/ussd-gateway.mdx index de1ff92..a4cd459 100644 --- a/guides/dev/ussd-gateway.mdx +++ b/guides/dev/ussd-gateway.mdx @@ -84,12 +84,7 @@ cp env.example .env -To target the IXO testnet instead of mainnet: - -```bash -IXO_API_URL=https://api.testnet.ixo.world -IXO_BLOCKCHAIN_URL=https://rpc.testnet.ixo.world -``` +To target the IXO testnet instead of mainnet, set `IXO_API_URL` and `IXO_BLOCKCHAIN_URL` to the testnet rows from [Networks and endpoints](/reference/networks-and-endpoints). ## Step 3 — Set up the database and start the server @@ -199,7 +194,17 @@ pnpm build && node dist/src/migrations/run-migrations.js ## Next steps -- [USSD gateway API reference](/api-reference/ussd-api) — request and response format, session endpoints, error codes -- [IXO USSD gateway — architecture overview](/articles/ixo-ussd) — state machine design and integration model -- [Architecture patterns guide](https://github.com/ixoworld/ixo-ussd/blob/main/docs/ARCHITECTURE_PATTERNS_GUIDE.md) — how to build custom USSD flows -- [IXO networks and endpoints](/reference/networks-and-endpoints) — mainnet and testnet connection details + + + Review request/response formats, session endpoints, and error codes. + + + Understand the state machine design and integration model. + + + Build custom USSD flows with reusable architecture patterns. + + + Use the right mainnet and testnet connection details. + + diff --git a/guides/dev/workflows.mdx b/guides/dev/workflows.mdx index 282756b..6c0dcab 100644 --- a/guides/dev/workflows.mdx +++ b/guides/dev/workflows.mdx @@ -1,139 +1,188 @@ --- title: "Developer workflows" icon: "diagram-project" -description: "End-to-end patterns for the IXO MultiClient SDK: clients, entities, claims, and evaluation—aligned with implementation examples in this docs repo." +description: "End-to-end IXO MultiClient SDK patterns: query client, signing client, entities, claims, and oracle-assisted evaluation." --- -These workflows follow the same patterns as [Implementation examples](/guides/dev/examples). Method names and payloads can change between SDK releases—confirm types and exports in [`@ixo/impactxclient-sdk`](https://www.npmjs.com/package/@ixo/impactxclient-sdk) and the [ixo-multiclient-sdk repository](https://github.com/ixofoundation/ixo-multiclient-sdk) before shipping. +These workflows show the canonical message patterns from the [`@ixo/impactxclient-sdk` README](https://github.com/ixofoundation/ixo-multiclient-sdk#readme). For full type definitions, see [`@ixo/impactxclient-sdk`](https://www.npmjs.com/package/@ixo/impactxclient-sdk) and the [proto definitions](https://github.com/ixofoundation/ixo-blockchain/tree/main/proto/ixo). - There is **no single blessed CLI** for every IXO operation in this docs set. Prefer the SDK, Cosmos-compatible wallets, or deployment-specific CLIs your operator documents. For HTTP examples (for example Emerging Platform domains), see [Domain registration](/guides/domain-registration). + There is **no single blessed CLI** for every IXO operation. Prefer the SDK, Cosmos-compatible wallets, or deployment-specific CLIs your operator documents. For HTTP-oriented domain examples, see [Domain registration](/guides/domain-registration). ## Prerequisites -1. Install dependencies: `@ixo/impactxclient-sdk` (and optional `@ixo/oracle-agent-sdk` for verification flows). +1. Install dependencies: `@ixo/impactxclient-sdk`. For Agentic Oracle integration, see [Agentic Oracles ADK](/sdk-reference/oracle-adk). 2. Choose **RPC endpoint** and **chain ID** from [Networks and endpoints](/reference/networks-and-endpoints). -3. Choose **auth** for each surface from [Authentication matrix](/reference/authentication-matrix); on-chain writes require a funded signer (wallet or key management you control). +3. Choose **auth** for each surface from [Authentication matrix](/reference/authentication-matrix). On-chain writes require a funded signer (wallet or key management you control). -## 1. Initialize the client +```bash +npm install @ixo/impactxclient-sdk +``` + +## 1. Initialize query and signing clients + +Reads use `createQueryClient`. Writes need a signer-backed `createSigningClient`. Both target the same RPC endpoint. ```typescript -import { createClient } from "@ixo/impactxclient-sdk"; +import { + ixo, + createQueryClient, + createSigningClient, +} from "@ixo/impactxclient-sdk"; -const client = await createClient({ - rpcEndpoint: "https://rpc.ixo.world", - chainId: "ixo-5", -}); +const RPC_ENDPOINT = "https://rpc.ixo.world"; + +const queryClient = await createQueryClient(RPC_ENDPOINT); +const signingClient = await createSigningClient(RPC_ENDPOINT, offlineSigner); ``` -**Signing:** production flows attach a signer compatible with the chain (for example Keplr, Cosmostation, or a custodial signer). The examples below assume `client` can submit transactions for your account. +**Errors:** RPC misconfiguration surfaces as connection timeouts or JSON-RPC errors. Try a different node if your operator allows; confirm TLS and `chainId` against the network row in [Networks and endpoints](/reference/networks-and-endpoints). -**Errors:** RPC misconfiguration often surfaces as connection timeouts or JSON-RPC errors. Retry with a different node if the operator allows; confirm TLS and `chainId` match the network. +For signer setup (Cosmos-kit, Keplr, or `getOfflineSigner` from `cosmjs-utils`), see [SDK README — Creating signers](https://github.com/ixofoundation/ixo-multiclient-sdk#creating-signers). -## 2. Register or manage a domain (digital twin) +## 2. Register an entity (digital twin) -Create an entity that backs your domain / digital twin (type and fields depend on your protocol): +Compose `MsgCreateEntity`, sign and broadcast. ```typescript -const entity = await client.createEntity({ - type: "Asset", - name: "Solar Panel Array", - description: "Renewable energy installation", - location: { latitude: 51.5074, longitude: -0.1278 }, - metadata: { - capacity: "5kW", - installation_date: "2023-01-15", - }, -}); - -console.log("Entity id:", entity.id); - -const entityData = await client.getEntity(entity.id); +const createEntityMsg = { + typeUrl: "/ixo.entity.v1beta1.MsgCreateEntity", + value: ixo.entity.v1beta1.MsgCreateEntity.fromPartial({ + ownerAddress: signerAddress, + entityType: "asset", + context: [ + ixo.iid.v1beta1.Context.fromPartial({ + key: "class", + val: "did:ixo:entity:protocol123", + }), + ], + verification: [], + controller: [], + service: [], + linkedResource: [], + accordedRight: [], + linkedEntity: [], + linkedClaim: [], + }), +}; + +const response = await signingClient.signAndBroadcast( + signerAddress, + [createEntityMsg], + "auto", +); ``` -**Update state** (example): +Read the resulting entity through the query client: ```typescript -await client.updateEntity(entity.id, { - status: "active", - metadata: { - ...entityData.metadata, - last_maintenance: "2023-06-10", - }, -}); +const entities = await queryClient.ixo.entity.v1beta1.entityList(); ``` -**Errors:** invalid `type` / metadata vs module expectations may return failed transactions—inspect `codespace` and `code` in the broadcast result and compare to protocol docs. +**Errors:** invalid `entityType` or context key/value pairs that the chain does not accept return failed transactions. Inspect `code` and `rawLog` on the broadcast response. ## 3. Submit a claim ```typescript -const claim = await client.createClaim({ - entityId: entity.id, - type: "Production", - data: { - energy_produced: "120kWh", - timestamp: Date.now(), - }, - evidence: { - type: "MeterReading", - hash: "Qm...", - uri: "https://...", - }, -}); - -console.log("Claim id:", claim.id); +const submitClaimMsg = { + typeUrl: "/ixo.claims.v1beta1.MsgSubmitClaim", + value: ixo.claims.v1beta1.MsgSubmitClaim.fromPartial({ + creator: signerAddress, + claimId: "bafkreih...", + collectionId: "12", + adminAddress: collectionAdminAddress, + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [submitClaimMsg], "auto"); ``` -**Errors:** missing `entityId`, schema mismatch, or insufficient authorization produce chain errors or rejected messages. Cross-check [Claims](/guides/dev/claims) and your entity’s controller keys. +**Errors:** missing `collectionId`, schema mismatch, or insufficient authorization produce chain errors. Cross-check [Claims management](/guides/dev/ixo-claims) and [Custom authorisations for IXO Claims](/guides/dev/authz-custom). -## 4. Evaluate or verify a claim (oracle-assisted) +## 4. Evaluate a claim (oracle-assisted) -Illustrative pattern combining oracle client and evaluation (see [Implementation examples](/guides/dev/examples) for full context): +An Agentic Oracle returns a determination off-chain; the on-chain record is written by `MsgEvaluateClaim`. The example below assumes an Agentic Oracle service exposes a verify endpoint your code calls — see [Agentic Oracles ADK](/sdk-reference/oracle-adk) for the canonical SDK home and [Build agentic oracles](/guides/ixo-oracles-architecture) for the architecture. ```typescript -import { createOracleClient } from "@ixo/oracle-agent-sdk"; - -const oracle = await createOracleClient({ - did: "did:ixo:oracle/123", - endpoint: "https://oracle.ixo.world", -}); - -const verification = await oracle.verify({ - claimId: claim.id, - data: claimData, - context: { timestamp: Date.now() }, +const verification = await callOracleVerify({ + oracleEndpoint: "https://oracle.example", + claimId: "bafkreih...", }); -const evaluation = await client.evaluateClaim(claim.id, { - status: "Approved", - verifier: oracle.did, - evidence: verification, -}); +const evaluateMsg = { + typeUrl: "/ixo.claims.v1beta1.MsgEvaluateClaim", + value: ixo.claims.v1beta1.MsgEvaluateClaim.fromPartial({ + creator: signerAddress, + claimId: "bafkreih...", + collectionId: "12", + oracle: oracleAddress, + adminAddress: collectionAdminAddress, + status: 1, + reason: 0, + verificationProof: verification.proofCid, + amount: [], + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [evaluateMsg], "auto"); ``` -**Errors:** oracle `401`/`403` usually means wrong operator credential or DID; chain-side `evaluateClaim` failures often point to authorization or claim state. + + `callOracleVerify` is a placeholder for whatever HTTP, MCP, or SDK call your Agentic Oracle exposes. The on-chain side is what `@ixo/impactxclient-sdk` covers — the off-chain agent service is your application code. + -## 5. Issue and rely on verifiable credentials +**Errors:** oracle `401`/`403` typically means wrong operator credential or DID. Chain-side `MsgEvaluateClaim` failures usually point to authorization (no `EvaluateClaimAuthorization`) or claim state. -Credential **issuance and verification** are governed by your program’s issuer keys, schemas, and registry or Matrix storage—see [Credential issuance](/platforms/Emerging/credential-issuance) and [Identity and credentials](/guides/dev/identity-and-credentials). Implement issuance in the component that holds the issuer key; verifiers should check signature, issuer DID, schema, and revocation/status lists. +## 5. Issue tokens against an evaluated claim -For HTTP-oriented credential flows on Emerging, use the platform API docs ([Emerging API](/platforms/Emerging/emerging-api)) and the same auth rules as other service APIs. +After approval, mint tokens with `MsgMintToken` against your token contract — see [Manage tokens](/guides/dev/tokens) for the full message family. + +```typescript +const mintMsg = { + typeUrl: "/ixo.token.v1beta1.MsgMintToken", + value: ixo.token.v1beta1.MsgMintToken.fromPartial({ + minter: signerAddress, + contractAddress: tokenContractAddress, + owner: recipientAddress, + mintBatch: [ + ixo.token.v1beta1.MintBatch.fromPartial({ + name: "CARBON", + index: "bafkreih...", + amount: "3600", + collection: "did:ixo:entity:collection456", + tokenData: [], + }), + ], + }), +}; + +await signingClient.signAndBroadcast(signerAddress, [mintMsg], "auto"); +``` + +## 6. Verifiable credentials + +Credential issuance and verification are governed by your program's issuer keys, schemas, and registry or IXO Matrix storage — see [Credential issuance](/platforms/Emerging/credential-issuance) and [Identity and credentials](/articles/identity-and-credentials). Implement issuance in the component that holds the issuer key; verifiers should check signature, issuer DID, schema, and revocation/status lists. For HTTP-oriented credential flows on Emerging, see [Emerging API](/platforms/Emerging/emerging-api) and the matching auth rules in [Authentication matrix](/reference/authentication-matrix). ## Error handling - **HTTP service calls:** use [Error handling](/api-reference/errors) for status codes; add retry/backoff for `429` and transient `5xx`. -- **GraphQL (Blocksync):** partial errors may appear in a top-level `errors` array while `data` is non-null—always check both; unauthenticated introspection may be disabled on some deployments. +- **GraphQL (Blocksync):** partial errors may appear in a top-level `errors` array while `data` is non-null — always check both. Unauthenticated introspection may be disabled on some deployments. - **DID resolution:** if resolution fails, confirm the DID is registered on the expected network and that you query the correct registry or indexer endpoint. ## Next steps + + Module-level features on protocol. + - Canonical SDK and kit overview with route selection guidance + Canonical SDK overview and route selection. + + + Worked end-to-end flows. - - Module-level features on-chain + + Build the off-chain side of evaluation. diff --git a/guides/domain-registration.mdx b/guides/domain-registration.mdx index 218be2e..808662a 100644 --- a/guides/domain-registration.mdx +++ b/guides/domain-registration.mdx @@ -125,7 +125,7 @@ For a platform-scoped walkthrough (DAO stages, relayer assignment, GraphQL statu Model entities, protocols, and relationships - + How DIDs, claims, and verifiable credentials connect diff --git a/guides/registry.mdx b/guides/registry.mdx index c460fb7..1120b5e 100644 --- a/guides/registry.mdx +++ b/guides/registry.mdx @@ -38,6 +38,14 @@ A successful integration should show: ## Next steps -- Registry API reference: `/api-reference/registry-api` -- Claims guide: `/guides/dev/ixo-claims` -- Networks and endpoints: `/reference/networks-and-endpoints` + + + Integrate registry services and endpoint operations. + + + Connect registry data to claims and verification workflows. + + + Select the correct environment endpoints and chain details. + + diff --git a/guides/users/ussd.mdx b/guides/users/ussd.mdx index 548fe63..30e4745 100644 --- a/guides/users/ussd.mdx +++ b/guides/users/ussd.mdx @@ -88,4 +88,8 @@ If you see "Service temporarily unavailable", the server may be briefly offline. ## Next steps -- [IXO USSD gateway overview](/articles/ixo-ussd) — how the USSD gateway works for operators and developers + + + Learn how the USSD gateway works for operators and developers. + + diff --git a/platforms/Emerging/concepts.mdx b/platforms/Emerging/concepts.mdx index 6620aad..668c268 100644 --- a/platforms/Emerging/concepts.mdx +++ b/platforms/Emerging/concepts.mdx @@ -33,6 +33,14 @@ Emerging Platform concepts depend on canonical IXO products: ## Next steps -- Read `/platforms/Emerging/digital-identifiers` for identity structure. -- Read `/platforms/Emerging/credential-issuance` for credential lifecycle. -- Continue to `/platforms/Emerging/emerging-dmrv` for household-energy implementation. + + + Understand identity structure and DID modeling. + + + Review credential lifecycle and issuance flow. + + + Continue to solution implementation for household-energy workflows. + + diff --git a/platforms/Emerging/credential-issuance.mdx b/platforms/Emerging/credential-issuance.mdx index ca5539d..a9e8737 100644 --- a/platforms/Emerging/credential-issuance.mdx +++ b/platforms/Emerging/credential-issuance.mdx @@ -55,4 +55,4 @@ In **Emerging Household Energy**, credentials support household, device, and rep - Schema reference: [ITMO schema](/platforms/Emerging/itmo-schema) - Identity model: [Digital identifiers](/platforms/Emerging/digital-identifiers) - dMRV capability: [dMRV](/platforms/Emerging/dmrv) -- Developer overview: [Identity and credentials](/guides/dev/identity-and-credentials) +- Developer overview: [Identity and credentials](/articles/identity-and-credentials) diff --git a/platforms/Emerging/digital-identifiers.mdx b/platforms/Emerging/digital-identifiers.mdx index 361973a..1e487ef 100644 --- a/platforms/Emerging/digital-identifiers.mdx +++ b/platforms/Emerging/digital-identifiers.mdx @@ -53,7 +53,7 @@ This platform capability is used by: - **Impact Hub Registry** for entity and claim records: [Emerging registry](/platforms/Emerging/registry) - **IXO Matrix** for encrypted payload storage when data should not be on-chain: [IXO Matrix](/articles/ixo-matrix) -For a single developer-oriented overview of DID, claims, and verifiable credentials together, see [Identity and credentials](/guides/dev/identity-and-credentials). +For a single developer-oriented overview of DID, claims, and verifiable credentials together, see [Identity and credentials](/articles/identity-and-credentials). ## Related pages diff --git a/platforms/Emerging/distributor-onboarding.mdx b/platforms/Emerging/distributor-onboarding.mdx index 7194289..c272209 100644 --- a/platforms/Emerging/distributor-onboarding.mdx +++ b/platforms/Emerging/distributor-onboarding.mdx @@ -64,6 +64,14 @@ After this guide, a distributor is ready to: ## Next steps -- Identity and domain setup: `/platforms/Emerging/domain-registration` -- Claim and credential flow: `/platforms/Emerging/credential-issuance` -- Household implementation guides: `/platforms/Emerging/household-monitoring` + + + Register and manage solution entities and domain records. + + + Implement claim, credential, and verification lifecycle steps. + + + Continue with household monitoring and operations guidance. + + diff --git a/platforms/Emerging/emerging-dmrv.mdx b/platforms/Emerging/emerging-dmrv.mdx index 521ae85..c9cf32c 100644 --- a/platforms/Emerging/emerging-dmrv.mdx +++ b/platforms/Emerging/emerging-dmrv.mdx @@ -59,8 +59,14 @@ This solution implementation depends on: ## Next steps -- Track SDG-linked outcomes: `/platforms/Emerging/sdg-monitoring` -- Continue with digital certification references: `/platforms/Emerging/digital-certification` + + + Continue with SDG monitoring workflows and reporting patterns. + + + Continue with certification standards and credential outputs. + + --- title: 'Emerging Household Energy dMRV' icon: 'chart-line' diff --git a/platforms/Emerging/energy-systems.mdx b/platforms/Emerging/energy-systems.mdx index 7b9cbf8..1e93d8b 100644 --- a/platforms/Emerging/energy-systems.mdx +++ b/platforms/Emerging/energy-systems.mdx @@ -147,7 +147,7 @@ graph TD ## Implementation Guide -1. [Set up your development environment](/guides/dev/introduction) +1. [Set up your development environment](/guides/dev/overview) 2. [Create digital twins](/guides/digital-twins) for your devices and entities 3. [Configure monitoring](/platforms/Emerging/household-monitoring) and verification rules 4. [Implement dMRV](/platforms/Emerging/emerging-dmrv) for impact tracking diff --git a/platforms/Emerging/intro-emerging.mdx b/platforms/Emerging/intro-emerging.mdx index 22d458e..60031ba 100644 --- a/platforms/Emerging/intro-emerging.mdx +++ b/platforms/Emerging/intro-emerging.mdx @@ -146,7 +146,7 @@ The **Emerging Platform** is the reusable IXO platform layer for digital identit Join our Slack for technical discussions - + Explore detailed implementation guides diff --git a/reference/glossary.mdx b/reference/glossary.mdx index 6ff50b5..a67da58 100644 --- a/reference/glossary.mdx +++ b/reference/glossary.mdx @@ -9,7 +9,7 @@ Use this page to disambiguate vocabulary used across guides and API docs. For st - Stable identifier for an entity, often in the `did:ixo:` namespace; see [Identity and credentials](/guides/dev/identity-and-credentials). + Stable identifier for an entity, often in the `did:ixo:` namespace; see [Identity and credentials](/articles/identity-and-credentials). @@ -29,7 +29,7 @@ Use this page to disambiguate vocabulary used across guides and API docs. For st - Party authorized to update a DID document or domain record within protocol rules; see [Identity and credentials](/guides/dev/identity-and-credentials). + Party authorized to update a DID document or domain record within protocol rules; see [Identity and credentials](/articles/identity-and-credentials). diff --git a/reference/networks-and-endpoints.mdx b/reference/networks-and-endpoints.mdx index d03082f..73c53b4 100644 --- a/reference/networks-and-endpoints.mdx +++ b/reference/networks-and-endpoints.mdx @@ -14,18 +14,30 @@ This page is the canonical home for endpoint and network literals used across IX ## Endpoint matrix - + - **Environment / context in docs:** Developer example - **Canonical literal:** `https://rpc.ixo.world` - **Source:** [Implementation examples](/guides/dev/examples) - + + - **Environment / context in docs:** USSD gateway, developer testing + - **Canonical literal:** `https://rpc.testnet.ixo.world` + - **Source:** [USSD gateway](/guides/dev/ussd-gateway) + + + - **Environment / context in docs:** Emerging platform examples - **Canonical literal:** `https://rest.emerging.eco` - **Source:** [gRPC gateway API](/api-reference/grpc-gateway-api) + + - **Environment / context in docs:** USSD gateway, developer testing + - **Canonical literal:** `https://api.testnet.ixo.world` + - **Source:** [USSD gateway](/guides/dev/ussd-gateway) + + - **Environment / context in docs:** Developer example - **Canonical literal:** `https://matrix.ixo.world` diff --git a/sdk-reference/index.mdx b/sdk-reference/index.mdx index 5b03f99..d310dc4 100644 --- a/sdk-reference/index.mdx +++ b/sdk-reference/index.mdx @@ -165,7 +165,7 @@ The IXO Software Development Kits and Qi tooling fast-track building custom appl ## Next steps - + Start building with our developer guides diff --git a/sdk-reference/jambo-wallet-sdk.mdx b/sdk-reference/jambo-wallet-sdk.mdx index 7c28a1e..6681a8f 100644 --- a/sdk-reference/jambo-wallet-sdk.mdx +++ b/sdk-reference/jambo-wallet-sdk.mdx @@ -117,7 +117,7 @@ The JAMBO P2PSend, Stake, and dAppStore repositories are private. [Reach out to - + Start building with our developer guides diff --git a/sdk-reference/matrix-client-sdk.mdx b/sdk-reference/matrix-client-sdk.mdx index e47a7a5..eec32de 100644 --- a/sdk-reference/matrix-client-sdk.mdx +++ b/sdk-reference/matrix-client-sdk.mdx @@ -97,7 +97,7 @@ This GitHub repository is private. Request access by contacting the IXO World te Request repository access - + Start building with our developer guides diff --git a/sdk-reference/multiclient-sdk.mdx b/sdk-reference/multiclient-sdk.mdx index 013506c..975300d 100644 --- a/sdk-reference/multiclient-sdk.mdx +++ b/sdk-reference/multiclient-sdk.mdx @@ -121,7 +121,7 @@ For detailed API documentation and examples, refer to the [IXO MultiClient SDK m ## Worked examples in docs -Step-by-step TypeScript flows (client, entity, claim, evaluation) live in [Developer workflows](/guides/dev/workflows) and [Implementation examples](/guides/dev/examples). Conceptual mapping of DIDs, claims, and VCs is in [Identity and credentials](/guides/dev/identity-and-credentials). +Step-by-step TypeScript flows (client, entity, claim, evaluation) live in [Developer workflows](/guides/dev/workflows) and [Implementation examples](/guides/dev/examples). Conceptual mapping of DIDs, claims, and VCs is in [Identity and credentials](/articles/identity-and-credentials). @@ -130,7 +130,7 @@ Step-by-step TypeScript flows (client, entity, claim, evaluation) live in [Devel View the source code - + Start building with our developer guides diff --git a/sdk-reference/oracle-adk.mdx b/sdk-reference/oracle-adk.mdx index 793c261..4496f75 100644 --- a/sdk-reference/oracle-adk.mdx +++ b/sdk-reference/oracle-adk.mdx @@ -75,7 +75,7 @@ This repository is private. [Reach out to us](https://linktr.ee/ixo_world) to be Request repository access - + Start building with our developer guides diff --git a/sdk-reference/signx-sdk.mdx b/sdk-reference/signx-sdk.mdx index 7d7e551..ebceef5 100644 --- a/sdk-reference/signx-sdk.mdx +++ b/sdk-reference/signx-sdk.mdx @@ -80,7 +80,7 @@ For detailed API documentation and examples, refer to the [SignX SDK README](htt View the source code - + Start building with our developer guides