-
Notifications
You must be signed in to change notification settings - Fork 106
feat: add Keeta namespace #183
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sc4l3r
wants to merge
1
commit into
ChainAgnostic:main
Choose a base branch
from
sc4l3r:feat/keeta-namespace
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| --- | ||
| namespace-identifier: keeta | ||
| title: Keeta | ||
| author: ["@sc4l3r"] | ||
| discussions-to: https://github.com/ChainAgnostic/namespaces/pull/XXXX | ||
| status: Draft | ||
| type: Informational | ||
| created: 2026-04-27 | ||
| requires: ["CAIP-2"] | ||
| --- | ||
|
|
||
| # Namespace for Keeta | ||
|
|
||
| [Keeta][keeta-home] is a Delegated Proof of Stake (DPoS) Layer-1 designed for high-throughput asset transfers, real-world asset tokenization, and built-in compliance primitives (KYC, sanctions, ACLs). | ||
| The protocol uses a [Directed Acyclic Graph (DAG)][whitepaper] of per-account block chains rather than a single linearly-ordered ledger, which lets independent accounts publish concurrently and lets the network achieve sub-second finality. | ||
|
|
||
| The `keeta` namespace describes both the public Keeta main network and any of its sibling networks -- the test, staging, and dev networks, and any privately-launched **sub-network** (a private instance that runs the same protocol but with isolated transaction visibility and its own validator set). | ||
| All networks share the same key-pair format, address encoding, and operation set, so a single Keeta key pair can be used across networks and the only thing that distinguishes one from another in CAIP terms is its `networkId`. | ||
|
|
||
| ## Rationale | ||
|
|
||
| Registering the `keeta` namespace enables standard CAIP-2 chain identifiers for every Keeta network distinguished by their numeric `networkId`. | ||
| Keeta does not run an EVM or similar and has no smart-contract addresses. | ||
| Therefore, CAIP profiles in this namespace focus on identifying networks, accounts (keyed and identifier-style), and tokens, not contracts. | ||
|
|
||
| ## Governance | ||
|
|
||
| Keeta uses Delegated Proof of Stake. | ||
| Token holders elect representatives, which vote on the validity of vote staples (atomic groups of blocks). | ||
| Network-wide policy -- for example, the right to create new tokens or storage accounts -- is expressed as permissions on the [Network Account][accounts], a deterministically-generated identifier account that exists once per network. | ||
|
|
||
| Protocol changes are coordinated by Keeta Token Genesis LLC and the validator set. | ||
| The reference implementation is published as the [`@keetanetwork/keetanet-client`][sdk] TypeScript SDK; the protocol specification is described in the [Keeta whitepaper][whitepaper]. | ||
|
|
||
| ## References | ||
|
|
||
| - [Keeta home][keeta-home] - public site and ecosystem overview. | ||
| - [Keeta whitepaper][whitepaper] - protocol specification, DAG model, consensus, and account model. | ||
| - [Keeta documentation][keeta-docs] - developer guide, SDK reference, and anchor framework. | ||
| - [Keeta SDK source][sdk] - the canonical reference implementation that defines `NetworkIDs`, address encoding, and key algorithms cited by the CAIP profiles in this namespace. | ||
| - [Public network resources][official-links] - wallet, block explorer, and faucet endpoints for the public main and test networks. | ||
|
|
||
| [keeta-home]: https://keeta.com/ | ||
| [whitepaper]: https://keeta.com/whitepaper.pdf | ||
| [keeta-docs]: https://docs.keeta.com/ | ||
| [sdk]: https://github.com/KeetaNetwork/keetanet-client | ||
| [official-links]: https://docs.keeta.com/other-documentation/official-links | ||
| [accounts]: https://docs.keeta.com/components/accounts | ||
|
|
||
| ## Copyright | ||
|
|
||
| Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,190 @@ | ||
| --- | ||
| namespace-identifier: keeta-caip10 | ||
| title: Keeta - Account ID Specification | ||
| author: ["@sc4l3r"] | ||
| discussions-to: https://github.com/ChainAgnostic/namespaces/pull/XXXX | ||
| status: Draft | ||
| type: Standard | ||
| created: 2026-04-27 | ||
| requires: ["CAIP-2", "CAIP-10"] | ||
| --- | ||
|
|
||
| # CAIP-10 | ||
|
|
||
| _For context, see the [CAIP-10][] specification._ | ||
|
|
||
| ## Introduction | ||
|
|
||
| Every [account][accounts] on a Keeta network -- whether it is a key-pair-backed account (ECDSA secp256k1, ECDSA secp256r1, or Ed25519), a token, a storage account, a network account, or a multisig -- is addressed by a single base32-encoded **public key string** with the prefix `keeta_`. | ||
|
|
||
| The body of the address self-identifies its account type via its first base32 characters (e.g. `aa` is a secp256k1 keyed account, `am` is a token, `aq` is a storage account, `ai` is a Network Account), and ends in a checksum. | ||
|
|
||
| This profile uses the full canonical `keeta_...` form as the [CAIP-10][] `account_address`. | ||
|
|
||
| ## Specification | ||
|
|
||
| ### Semantics | ||
|
|
||
| The inputs are: | ||
|
|
||
| - A Keeta `networkId` (defined in the [Keeta CAIP-2 Profile][CAIP-2 Profile]) identifying which network the account lives on. | ||
| - A Keeta canonical address string, of the form `keeta_<base32 body>`, returned by the SDK as `account.publicKeyString.toString()` (or accepted by `Account.fromPublicKeyString()`). | ||
|
|
||
| The body of a Keeta address is the [RFC 4648][rfc4648] base32 encoding of a byte sequence that encodes an account-type indicator, the public key material, and a truncated hash checksum. | ||
| RFC 4648 base32 is case-insensitive; the canonical form on Keeta and in this profile is lowercase with no padding (see [Canonicalization](#canonicalization)). | ||
| The exact byte layout may change in future protocol versions; the SDK is the authoritative source for encoding and decoding (see [Resolution Mechanics](#resolution-mechanics)). | ||
|
|
||
| The account-type indicator occupies the high bits of the encoded body, so the characters immediately following `keeta_` reflect the account's key algorithm and identifier type. | ||
| The following two-character prefixes are reserved by the SDK for the account types listed below as of `keetanet-client` version `0.16.1`: | ||
|
|
||
| | First chars (after `keeta_`) | Account type | | ||
| | :--------------------------- | :------------------------------------- | | ||
| | `aa`, `ab`, `ac`, `ad` | Keyed account, ECDSA secp256k1 | | ||
| | `ae`, `af`, `ag`, `ah` | Keyed account, Ed25519 | | ||
| | `ay`, `az`, `a2`, `a3` | Keyed account, ECDSA secp256r1 (P-256) | | ||
| | `ai`, `aj`, `ak`, `al` | Network Account (one per network) | | ||
| | `am`, `an`, `ao`, `ap` | Token account | | ||
| | `aq`, `ar`, `as`, `at` | Storage account | | ||
| | `a4`, `a5`, `a6`, `a7` | Multisig identifier account | | ||
|
|
||
| This table is illustrative and reflects the current SDK encoding; it is **not** normative for type discrimination. | ||
| Implementations MUST NOT switch on these prefixes to determine an account's type; instead, parse the address with a Keeta SDK and use `account.isToken()`, `account.isStorage()`, `account.isNetwork()`, and `account.isMultisig()` (see [Resolution Mechanics](#resolution-mechanics)). | ||
|
|
||
| #### Canonicalization | ||
|
|
||
| A Keeta address is **case-insensitive**: per RFC 4648, two base32-encoded bodies that differ only in letter case decode to the same byte sequence and therefore identify the same account. | ||
| For [CAIP-10][] purposes the canonical form is **all-lowercase**, and producers MUST lowercase the body before emitting a CAIP-10 string. | ||
| Consumers MUST treat differently-cased CAIP-10 strings whose lowercased forms are equal as identifiers for the same account, and SHOULD lowercase incoming CAIP-10 strings before using them as cache or lookup keys. | ||
| The literal prefix `keeta_` is always lowercase. | ||
|
|
||
| ### Syntax | ||
|
|
||
| A Keeta [CAIP-10][] account identifier MUST take the form: | ||
|
|
||
| ``` | ||
| keeta:<networkId>:<address> | ||
| ``` | ||
|
|
||
| Where: | ||
|
|
||
| - `keeta` is the namespace. | ||
| - `<networkId>` is a CAIP-2 reference for a Keeta network as defined by the [Keeta CAIP-2 Profile][CAIP-2 Profile]. | ||
| - `<address>` is the canonical Keeta public key string, **including** its `keeta_` prefix. | ||
|
|
||
| The `<address>` segment MUST match: | ||
|
|
||
| ``` | ||
| ^keeta_[a-z2-7]+$ | ||
| ``` | ||
|
|
||
| A regex match is necessary but not sufficient for validity as it does not verify the type indicator, checksum, or body length. | ||
| Implementations MUST validate addresses using the Keeta SDK or by following the steps in [Resolution Mechanics](#resolution-mechanics). | ||
|
|
||
| ### Resolution Mechanics | ||
|
|
||
| To validate a Keeta CAIP-10 identifier: | ||
|
|
||
| 1. Split on `:` and verify the namespace is `keeta`. | ||
| 2. Validate `<networkId>` against the [Keeta CAIP-2 Profile][CAIP-2 Profile]. | ||
| 3. Lowercase the body of `<address>` (the part after `keeta_`) to obtain its canonical form; see [Canonicalization](#canonicalization). | ||
| 4. Decode `<address>` using the Keeta public-key-string codec; verify the type byte and checksum. | ||
| 5. Optionally, query a node on the indicated network to confirm the account exists and to retrieve its info: | ||
|
|
||
| ```ts | ||
| import * as KeetaNet from "@keetanetwork/keetanet-client"; | ||
|
|
||
| const account = KeetaNet.lib.Account.fromPublicKeyString( | ||
| "keeta_aabfo65nbz4toez4ouzit3ej5elpcjnatv6p6vxtgj5gj4x4cbs3nkytnpniyhi", | ||
| ); | ||
| const client = KeetaNet.Client.fromNetwork("test"); | ||
| const { info } = await client.getAccountInfo(account); | ||
| ``` | ||
|
|
||
| Implementations SHOULD validate the checksum by round-tripping through `Account.fromPublicKeyString()` before treating the identifier as well-formed. | ||
|
|
||
| Implementations SHOULD use the methods of a Keeta SDK (e.g. `account.isToken()`, `account.isStorage()`) to determine the type of an account. | ||
|
|
||
| Note that account _existence_ is not required for a CAIP-10 string to be valid -- Keeta accounts come into existence when their first block is published, and a freshly-derived keyed address may be a perfectly valid recipient before any block has ever been published to its chain. | ||
|
|
||
| ## Rationale | ||
|
|
||
| Keeta addresses are designed to be self-describing: the `keeta_` prefix and the algorithm-tag prefix are part of the canonical form everywhere -- wallet UIs, block explorers, the SDK, and on-chain metadata. | ||
| Stripping `keeta_` to "save space" inside a CAIP-10 string would force every consumer to reattach it before handing the address to the SDK, and would cause CAIP-10 strings to disagree with how the same address is rendered everywhere else in the ecosystem. | ||
|
|
||
| The resulting form fits comfortably within the [CAIP-10][] `account_address` length budget of 128 characters: the currently longest possible Keeta address is `keeta_` (6 chars) plus a 63-char body for compressed ECDSA secp256k1 / secp256r1 keys = 69 chars total; Ed25519 and identifier accounts are 67 chars total. | ||
|
|
||
| ### Backwards Compatibility | ||
|
|
||
| This is the first [CAIP-10][] specification for the `keeta` namespace, so there are no legacy identifiers to support. | ||
|
|
||
| ## Test Cases | ||
|
|
||
| Valid (test network, `networkId = 1413829460`): | ||
|
|
||
| ``` | ||
| # Keyed secp256k1 account | ||
| keeta:1413829460:keeta_aabfo65nbz4toez4ouzit3ej5elpcjnatv6p6vxtgj5gj4x4cbs3nkytnpniyhi | ||
| ``` | ||
|
|
||
| Valid forms on other networks: | ||
|
|
||
| ``` | ||
| # Mainnet, keyed Ed25519 account | ||
| keeta:21378:keeta_ae23cu2wimbyuvib6p77aw7zchgjmfia3fauuhy6mh44xa57buokkhifpsnxo | ||
|
|
||
| # Mainnet token account | ||
| keeta:21378:keeta_anqdilpazdekdu4acw65fj7smltcp26wbrildkqtszqvverljpwpezmd44ssg | ||
|
|
||
| # Mainnet storage account | ||
| keeta:21378:keeta_aqltdal4rshtky5iehd765y3mdjkcmku5d4ulo5fgonzqrxulwepnogq33mle | ||
|
|
||
| # Mainnet Network Account | ||
| keeta:21378:keeta_alwerxoezkupzhifvpo5yvoazlsdqaweov66mokhq7xl4h5ow36v5xu6ek3js | ||
| ``` | ||
|
|
||
| Non-canonical (decode to a valid account but MUST be lowercased before being used as a CAIP-10 identifier; see [Canonicalization](#canonicalization)): | ||
|
|
||
| ``` | ||
| # Uppercase body — same account as the lowercase form | ||
| keeta:21378:keeta_AE23CU2WIMBYUVIB6P77AW7ZCHGJMFIA3FAUUHY6MH44XA57BUOKKHIFPSNXO | ||
| ``` | ||
|
|
||
| Invalid: | ||
|
|
||
| ``` | ||
| # Missing keeta_ prefix on the address | ||
| keeta:21378:ae23cu2wimbyuvib6p77aw7zchgjmfia3fauuhy6mh44xa57buokkhifpsnxo | ||
|
|
||
| # Wrong namespace casing | ||
| Keeta:21378:keeta_ae23cu2wimbyuvib6p77aw7zchgjmfia3fauuhy6mh44xa57buokkhifpsnxo | ||
|
|
||
| # Hex networkId (see Keeta CAIP-2 Profile) | ||
| keeta:0x5382:keeta_ae23cu2wimbyuvib6p77aw7zchgjmfia3fauuhy6mh44xa57buokkhifpsnxo | ||
| ``` | ||
|
|
||
| ## Additional Considerations | ||
|
|
||
| ### Security | ||
|
|
||
| Keeta addresses encode their algorithm and type in the leading body characters and end in a checksum, so single-character typos and accidental cross-pasting between account types (e.g. sending to a token address instead of a keyed account) are detectable on the client side without a network round-trip. | ||
| Implementations SHOULD perform this check before signing a transaction that references a counterparty CAIP-10. | ||
|
|
||
| The same key pair derives to the same `keeta_...` address on every Keeta network, but the `<networkId>` segment of a CAIP-10 string is not redundant: the on-chain _state_ of an account (balances, permissions, certificates, history) is per-network, and applications MUST treat `keeta:21378:keeta_...` and `keeta:1413829460:keeta_...` as different accounts even when the address bodies are identical. | ||
|
|
||
| ## References | ||
|
|
||
| - Keeta [accounts] - account types, identifier accounts, and address derivation. | ||
| - Keeta [SDK source][sdk] - `lib/account.d.ts` defines the `keeta_` prefix, the algorithm tag bytes, and the `PublicKeyString` codec. | ||
| - [Keeta CAIP-2 Profile][CAIP-2 Profile] - the network-id portion of the identifier. | ||
| - [RFC 4648][rfc4648] - the base32 alphabet used for the address body. | ||
|
|
||
| [CAIP-2 Profile]: ./caip2.md | ||
| [accounts]: https://docs.keeta.com/components/accounts | ||
| [sdk]: https://github.com/KeetaNetwork/keetanet-client | ||
| [rfc4648]: https://datatracker.ietf.org/doc/html/rfc4648 | ||
| [CAIP-2]: https://chainagnostic.org/CAIPs/caip-2 | ||
| [CAIP-10]: https://chainagnostic.org/CAIPs/caip-10 | ||
|
|
||
| ## Copyright | ||
|
|
||
| Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
keeta_prefix is up for discussion. Keeta addresses always include the prefix but according to caip-10 theaccount_addressmust follow[-.%a-zA-Z0-9]{1,128}which doesn't allow for_.Would it be possible to add
_to the allowed character set or should we strip the prefix?