From c6b0b87d700aa2a22421a73a3716aa20d6a3b9e1 Mon Sep 17 00:00:00 2001 From: umr1352 Date: Thu, 31 Jul 2025 11:05:40 +0200 Subject: [PATCH 1/5] IOTA CAIP-10 first draft --- iota/caip10.md | 210 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 iota/caip10.md diff --git a/iota/caip10.md b/iota/caip10.md new file mode 100644 index 0000000..37728f7 --- /dev/null +++ b/iota/caip10.md @@ -0,0 +1,210 @@ +--- +namespace-identifier: iota-caip10 +title: IOTA - Account ID Specification +author: Enrico Marconi (@UMR1352) +status: Draft +type: Informational +created: 2025-07-28 +requires: CAIP-2, CAIP-10 +--- + + + +# CAIP-10 + +*For context, see the [CAIP-10] specification.* + +## Introduction + +This document defines how IOTA addresses can be encoded as [CAIP-10]'s account IDs. + +## Specification + +### Semantics + + + +In IOTA's object-based model, account addresses are just a subset of the whole +address namespace, which is shared among objects, packages, and accounts. + +Therefore, an IOTA address may refer to either an object, a package or a more +traditional key-based account. Most importantly, it is impossible to distinguish +what an IOTA address refers to without querying a node. + +Nonetheless, all IOTA addresses can own assets (i.e. other objects), with the +only difference being that key-derived address are the only types of address that +can execute transactions. + +### Syntax + + + +An IOTA [CAIP-10]'s account ID is a case-sensitive string that is computed by appending +an IOTA address to an IOTA [CAIP-2 Profile]'s chain ID, interlieved by the `:` character. + +The syntax of an IOTA address matches the following regular expression: + +``` +0x[0-9a-f]{64} +``` + +Hence, the regular expression that matches the whole [CAIP-10]'s account ID is: + +``` +iota:(mainnet|testnet|devnet|[0-9a-f]{8}):0x[0-9a-f]{64} +``` + +### Resolution Mechanics + + + +Any Account ID, conforming to the aforementioned syntax is a valid IOTA Account ID, +indipendently of whether it is already in use by a wallet or on-chain object. + +It is possible to check whether a given Account ID refers to a key-pair derived address, +an object, or a smart contract package by invoking the `iota_getObject` JSON-RPC API. + +For instance, checking IOTA address `0x53e4567ccafa5f36ce84c80aa8bc9be64e0d5ae796884274aef3005ae6733809` with + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "method": "iota_getObject", + "params": [ + "0x53e4567ccafa5f36ce84c80aa8bc9be64e0d5ae796884274aef3005ae6733809", + { + "showType": true, + "showOwner": true, + "showPreviousTransaction": false, + "showDisplay": false, + "showContent": false, + "showBcs": false, + "showStorageRebate": false, + } + ] +} +``` + +yields the following response: + +```json +{ + "jsonrpc": "2.0", + "result": { + "data": { + "objectId": "0x53e4567ccafa5f36ce84c80aa8bc9be64e0d5ae796884274aef3005ae6733809", + "version": "1", + "digest": "33K5ZXJ3RyubvYaHuEnQ1QXmmbhgtrFwp199dnEbL4n7", + "type": "0x2::coin::Coin<0x2::iota::IOTA>", + "owner": { + "AddressOwner": "0xc8ec1d5b84dd6289e193b9f88de4a994358c9f856135236c3e75a925e1c77ac3" + } + } + }, + "id": 1 +} +``` + +which shows that address `0x53e4567ccafa5f36ce84c80aa8bc9be64e0d5ae796884274aef3005ae6733809` is actually +an IOTA object of type `0x2::coin::Coin<0x2::iota::IOTA>` - i.e. an IOTA Coin - owned by address +`0xc8ec1d5b84dd6289e193b9f88de4a994358c9f856135236c3e75a925e1c77ac3`. + +If we were to do the same for the coin owner's address +`0xc8ec1d5b84dd6289e193b9f88de4a994358c9f856135236c3e75a925e1c77ac3` we'd get the following response: + +```json +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "error": { + "code": "notExists", + "object_id": "0xc8ec1d5b84dd6289e193b9f88de4a994358c9f856135236c3e75a925e1c77ac3" + } + } +} +``` + +Which hints at the fact that address `0xc8ec1d5b84dd6289e193b9f88de4a994358c9f856135236c3e75a925e1c77ac3` is not +an object, but a key-derived address. + +## Rationale + + + +IOTA addresses are lowercase-hex encoded 32 bytes string, which in the case of key-pair derived addresses - i.e. +traditional accounts - are computed by hashing with the `blake2b` algorithm a public key's bytes prepended by a +single tag byte that identifies the type of key used - e.g. `ed25519`, `secp256k1`, etc. + +As already mentioned above, all IOTA addresses can own assets and funds. + +## Test Cases + + + +``` +# IOTA Mainnet +iota:mainnet:0x7b4a34f6a011794f0ecbe5e5beb96102d3eef6122eb929b9f50a8d757bfbdd67 + +# IOTA Testnet +iota:testnet:0x2d3eef6122eb929b9f50a8d757bfbdd677b4a34f6a011794f0ecbe5e5beb9610 + +# IOTA Devnet +iota:devnet:0x929b9f50a8d757bfbdd677b4a34f6a011794f0ecbe5e5beb96102d3eef6122eb + +# IOTA custom network +iota:f3aa51bd:0xe5e5beb96102d37b4a34f6a011794f0ecbeef6122eb929b9f50a8d757bfbdd67 +``` + +## References + + + +[CAIP-2 Profile]: ./caip2.md +[CAIP-2]: https://chainagnostic.org/CAIPs/caip-2 +[CAIP-10]: https://chainagnostic.org/CAIPs/caip-10 +[IOTA Docs]: https://docs.iota.org +[IOTA RPC API]: https://docs.iota.org/iota-api-ref +[IOTA Object Model]: https://docs.iota.org/developer/iota-101/objects/object-model + +## Copyright + +Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/). From 13e6d143cbc4a72ae424be3e87837ec31e31ea9c Mon Sep 17 00:00:00 2001 From: Enrico Marconi <31142849+UMR1352@users.noreply.github.com> Date: Thu, 9 Oct 2025 11:01:55 +0200 Subject: [PATCH 2/5] Update iota/caip10.md Co-authored-by: Bumblefudge --- iota/caip10.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iota/caip10.md b/iota/caip10.md index 37728f7..6bc2ab0 100644 --- a/iota/caip10.md +++ b/iota/caip10.md @@ -83,7 +83,7 @@ validate the results, calculate checksums, persist session metadata or nonces, etc. --> Any Account ID, conforming to the aforementioned syntax is a valid IOTA Account ID, -indipendently of whether it is already in use by a wallet or on-chain object. +independently of whether it is already in use by a wallet or on-chain object. It is possible to check whether a given Account ID refers to a key-pair derived address, an object, or a smart contract package by invoking the `iota_getObject` JSON-RPC API. From 14f33806fc871ae1294a10a4377b501b60eba67f Mon Sep 17 00:00:00 2001 From: Enrico Marconi <31142849+UMR1352@users.noreply.github.com> Date: Thu, 9 Oct 2025 11:02:57 +0200 Subject: [PATCH 3/5] Update iota/caip10.md Co-authored-by: Bumblefudge --- iota/caip10.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iota/caip10.md b/iota/caip10.md index 6bc2ab0..0e4252f 100644 --- a/iota/caip10.md +++ b/iota/caip10.md @@ -160,7 +160,7 @@ CAIP-10 identifiers was arrived at, history and pre-history, etc.--> IOTA addresses are lowercase-hex encoded 32 bytes string, which in the case of key-pair derived addresses - i.e. traditional accounts - are computed by hashing with the `blake2b` algorithm a public key's bytes prepended by a -single tag byte that identifies the type of key used - e.g. `ed25519`, `secp256k1`, etc. +IOTA address currently supports pure Ed25519, Secp256k1, Secp256r1, and MultiSig with corresponding flag bytes of 0x00 (not prepended), 0x01, 0x02, and 0x03, respectively. As already mentioned above, all IOTA addresses can own assets and funds. From 860093ce9ecd6cc2a00c99ed2f6b0c72d9ef0e19 Mon Sep 17 00:00:00 2001 From: Enrico Marconi <31142849+UMR1352@users.noreply.github.com> Date: Thu, 9 Oct 2025 11:03:07 +0200 Subject: [PATCH 4/5] Update iota/caip10.md Co-authored-by: Bumblefudge --- iota/caip10.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iota/caip10.md b/iota/caip10.md index 0e4252f..1c6167a 100644 --- a/iota/caip10.md +++ b/iota/caip10.md @@ -159,7 +159,7 @@ an object, but a key-derived address. CAIP-10 identifiers was arrived at, history and pre-history, etc.--> IOTA addresses are lowercase-hex encoded 32 bytes string, which in the case of key-pair derived addresses - i.e. -traditional accounts - are computed by hashing with the `blake2b` algorithm a public key's bytes prepended by a +traditional accounts - are computed by hashing with the `blake2b` algorithm a public key's bytes. If the signature scheme to be computed with those bytes is anything other than `Ed25519`, the public key bytes have a sigil prepended **before** hashing. IOTA address currently supports pure Ed25519, Secp256k1, Secp256r1, and MultiSig with corresponding flag bytes of 0x00 (not prepended), 0x01, 0x02, and 0x03, respectively. As already mentioned above, all IOTA addresses can own assets and funds. From 08d26a1a5c6a2e2d34a8309d34202cb1dedce224 Mon Sep 17 00:00:00 2001 From: Enrico Marconi <31142849+UMR1352@users.noreply.github.com> Date: Mon, 20 Oct 2025 14:30:23 +0200 Subject: [PATCH 5/5] Update iota/caip10.md Co-authored-by: Bumblefudge --- iota/caip10.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iota/caip10.md b/iota/caip10.md index 1c6167a..de3a0c3 100644 --- a/iota/caip10.md +++ b/iota/caip10.md @@ -82,7 +82,7 @@ section below if possible, as well as an explanation of any steps needed to validate the results, calculate checksums, persist session metadata or nonces, etc. --> -Any Account ID, conforming to the aforementioned syntax is a valid IOTA Account ID, +Any Account ID conforming to the aforementioned syntax is a valid IOTA Account ID, independently of whether it is already in use by a wallet or on-chain object. It is possible to check whether a given Account ID refers to a key-pair derived address,