From a7cd4287ead62b450f306fb9765e0e8753b3e45e Mon Sep 17 00:00:00 2001
From: elliedavidson <118024407+elliedavidson@users.noreply.github.com>
Date: Thu, 13 Feb 2025 10:23:40 -0500
Subject: [PATCH 01/14] docs: add page describing the message-passing groups
current goals and status
---
docs/messaging-working-group.md | 68 +++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
create mode 100644 docs/messaging-working-group.md
diff --git a/docs/messaging-working-group.md b/docs/messaging-working-group.md
new file mode 100644
index 0000000..699065b
--- /dev/null
+++ b/docs/messaging-working-group.md
@@ -0,0 +1,68 @@
+# Message Passing Working Group
+
+## L2 Interop Overall Goal:
+A user can bridge assets between any two Lns within 3 slots or less of the slower chain.
+
+Things required to achieve this goal:
+* Message passing protocols to physically relay information from one chain to another. Different protocols have different tradeoffs and security properties, and different L2s may use different protocols.
+* Common, abstracted interface for devs to interact with messaging protocols. Devs should not have to worry about the underlying protocol to bridge between chains. Cross-chain applications should be able to be built on top of any messaging protocol that supports the interface. See [ERC-7841's](https://github.com/elliedavidson/ERCs/blob/d7c16c21f0a012ef391783322ae9b6f0eb0b56bc/ERCS/erc-7841.md) *Motivation* section for details about this goal.
+
+This working group focuses on the second point.
+
+## Current Working Group Status
+We are currently working on 3 tasks:
+
+1. Agreeing that such an interface is useful.
+2. Agreeing whether goal 1 listed below is in scope for this working group. We will iterate through each goal below until we reach rough consensus among core contributors.
+3. Identifying core contributors to move this consensus forward quickly. We will ask for feedback from the broader group periodically.
+4. Establishing commitments and timelines from core projects to implement the interface once it is finalized.
+
+### Timeline:
+* 2/17/2025: Core contibutors identified.
+* 2/24/2025: Agreement on goals has been reached among core contributors, broader group feedback welcome.
+* 3/2/2025: Agreement on properties of interface has been reached among core contributors, broader group feedback welcome.
+* 3/9/2025: Agreement on interface has been reached among all core contributors, broader group feedback welcome.
+* 3/16/2025: Publish updated or new ERC, reach out to devs explicitly to get feedback.
+* 3/30/2025: All changes to interface are finalized. Implementation begins
+
+
+## Goals:
+### 1. Interface supports only the most common use cases: bridging and cross-chain function calls.
+
+Reasoning:
+* Supporting all use cases results in a more complex interface. This may lead developers to use wrapper contracts to simplify the interface or to not adopt the interface at all, defeating the purpose of the interface.
+* Edge cases can be handled by the messaging protocol itself. Some edge use cases may depend on the specific messaging protocol used.
+
+#### 1a. Developers should not need to use wrapper contracts to interact with the interface.
+
+### 2. Interface should be VM-agnostic.
+
+Reasoning:
+* Our goal is to connect the entire ecosystem of Lns, including the many Lns using different VMs.
+* We will need to balance this goal with goal 1; we shouldn't make the interface overly complex to achieve this goal.
+
+### 3. Interface should be proof-agnostic.
+
+Reasoning:
+* Many proof systems will be used in the underlying messaging protocols. This interface should be compatible with any of those protocols. Otherwise, the interface does not achieve its primary goal abstracting the underlying messaging protocol from developers.
+
+### 4. Interface should be protocol-agnostic.
+
+Reasoning:
+* Many messaging protocols will be used. This interface should be compatible with any of those protocols.
+
+### 5. Interface is compatible with any Ln↔Ln messaging.
+
+Reasoning:
+* Both L2 <> L2 messaging and L1 <> L2 messaging are core use cases. If we want to create a unified developer experience, the interface needs to support both using the same abstractions.
+* L3 <> L2 messaging is a less common use case, but should be supported.
+* Key Question: Should it be an explicit goal of this interface to support L1 <> L1 messaging?
+
+## Miscellaneous Questions (to be addressed later)
+* Should the interface include gas quoting?
+* Should the interface be pull or push-based?
+* Should the interface use Ethereum specific addresses?
+* Should the interface defined specific message formats for specific use cases?
+* Should the interface use 7786-style attributes
+* Why don't existing messaging designs cover our use cases?
+* How should cross-chain addresses be represented?
\ No newline at end of file
From de23115260be0343838b485b994afbba297e031a Mon Sep 17 00:00:00 2001
From: elliedavidson <118024407+elliedavidson@users.noreply.github.com>
Date: Mon, 24 Feb 2025 21:01:28 +0200
Subject: [PATCH 02/14] Update messaging-working-group.md
---
docs/messaging-working-group.md | 53 +++++++++++++++++++++++++++++----
1 file changed, 47 insertions(+), 6 deletions(-)
diff --git a/docs/messaging-working-group.md b/docs/messaging-working-group.md
index 699065b..ddac1f5 100644
--- a/docs/messaging-working-group.md
+++ b/docs/messaging-working-group.md
@@ -27,7 +27,7 @@ We are currently working on 3 tasks:
## Goals:
-### 1. Interface supports only the most common use cases: bridging and cross-chain function calls.
+### 1. Interface supports only the most common use cases: bridging and cross-chain function calls. --> We'll start with 90% of uses cases, aiming to make those APIs simple, and then we can add more complex use cases from there.
Reasoning:
* Supporting all use cases results in a more complex interface. This may lead developers to use wrapper contracts to simplify the interface or to not adopt the interface at all, defeating the purpose of the interface.
@@ -35,29 +35,70 @@ Reasoning:
#### 1a. Developers should not need to use wrapper contracts to interact with the interface.
-### 2. Interface should be VM-agnostic.
+### 2. Interface should be VM-agnostic. --> Agree
Reasoning:
* Our goal is to connect the entire ecosystem of Lns, including the many Lns using different VMs.
* We will need to balance this goal with goal 1; we shouldn't make the interface overly complex to achieve this goal.
-### 3. Interface should be proof-agnostic.
+### 3. Interface should be proof-agnostic. --> Agree
Reasoning:
* Many proof systems will be used in the underlying messaging protocols. This interface should be compatible with any of those protocols. Otherwise, the interface does not achieve its primary goal abstracting the underlying messaging protocol from developers.
-### 4. Interface should be protocol-agnostic.
+### 4. Interface should be protocol-agnostic. --> Agree
Reasoning:
* Many messaging protocols will be used. This interface should be compatible with any of those protocols.
-### 5. Interface is compatible with any Ln↔Ln messaging.
+### 5. Interface is compatible with any Ln↔Ln messaging. --> Agree
Reasoning:
* Both L2 <> L2 messaging and L1 <> L2 messaging are core use cases. If we want to create a unified developer experience, the interface needs to support both using the same abstractions.
* L3 <> L2 messaging is a less common use case, but should be supported.
* Key Question: Should it be an explicit goal of this interface to support L1 <> L1 messaging?
+### 6. Making it happen soon
+
+Glacis --> TODO investigate
+OZ adapts - 2-4 weeks / adapter --> 3 months for at least 3 adapters
+ Axelar
+ Wormhole
+ Hyperlane
+ LZ
+ Chainlink
+
+ Parallel track - public support from major protocols to advertise this
+
+### 7. Support m / n messsage aggregation
+
+### 8. Data transfer
+
+### 9. Only narrow casting vs broadcasting to begin with
+3 ways: push, pull, read
+
+push -
+pull -
+
+Push vs Pull
+A push protocol allows for the entire cross-chain transmission lifecycle, up to and including delivery to a receiver, to be arranged on the source chain without a user transaction on the destination chain. The protocol may rely on third party relayers to complete the lifecycle.
+
+A pull protocol requires a user (or application) to complete the lifecycle with a transaction on the destination chain. The protocol can be said to require self-relaying.
+
+push + local pull
+push + execute
+don't need to worry about broadcast (for now
+
+### 10. Gas is out of scope (for now)
+
+### 11. Interface does not enforce ordering
+
+### 12. Liveness
+The protocol MUST guarantee Safety: A message is delivered at the destination if and only if it was sent at the source. The delivery process must ensure a message is only delivered once the sending transaction is finalized, and not delivered more than once. Note that there can be multiple messages with identical parameters that must be delivered separately.
+The protocol MUST guarantee Liveness: A sent message is delivered at the destination eventually, assuming Liveness and censorship-resistance of the source and destination chains.
+
+
+
## Miscellaneous Questions (to be addressed later)
* Should the interface include gas quoting?
* Should the interface be pull or push-based?
@@ -65,4 +106,4 @@ Reasoning:
* Should the interface defined specific message formats for specific use cases?
* Should the interface use 7786-style attributes
* Why don't existing messaging designs cover our use cases?
-* How should cross-chain addresses be represented?
\ No newline at end of file
+* How should cross-chain addresses be represented?
From ea2fb3fdb038e245dc82fd9e46086067f928fd55 Mon Sep 17 00:00:00 2001
From: elliedavidson <118024407+elliedavidson@users.noreply.github.com>
Date: Tue, 25 Feb 2025 00:02:34 +0200
Subject: [PATCH 03/14] Update messaging-working-group.md
---
docs/messaging-working-group.md | 47 +++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/docs/messaging-working-group.md b/docs/messaging-working-group.md
index ddac1f5..25631ac 100644
--- a/docs/messaging-working-group.md
+++ b/docs/messaging-working-group.md
@@ -99,6 +99,53 @@ The protocol MUST guarantee Liveness: A sent message is delivered at the destina
+
+### Message Format
+
+Message {
+ payload: bytes
+ source address: bytes
+ source chain id: bytes
+ destination adress: bytes
+ destination chain: bytes
+ nonce: uint32
+}
+
+packet_id - unique id, bytes
+
+// destination addr
+fn send (payload, (destination address?), destination chain) -> packet id
+
+
+// Won't support for now
+fn recv (packet id) -> Message
+
+
+ function executeMessage(
+ string calldata sourceChain, // [CAIP-2] chain identifier
+ string calldata sender, // [CAIP-10] account address
+ bytes calldata payload,
+ bytes[] calldata attributes
+ ) external payable returns (bytes4);
+
+
+
+ Gas
+
+ source chain:
+ pay_gas(packet id) payable
+
+ estimate_gas(gas_limit, destination id, ) -> cost on origin gas token
+
+ // Didn't add enough gas in the beginning
+ add_gas (
+
+
+
+
+Questions:
+* Should we allow tx hash as unique id?
+
## Miscellaneous Questions (to be addressed later)
* Should the interface include gas quoting?
* Should the interface be pull or push-based?
From a05ea6a3d2ae8924fa0a5fdac48f724c2b0d37c6 Mon Sep 17 00:00:00 2001
From: Joxes <91908708+Joxess@users.noreply.github.com>
Date: Wed, 12 Feb 2025 14:25:07 -0300
Subject: [PATCH 04/14] docs: add ERC-7683 mermaids (#12)
---
docs/intent-types.md | 50 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/docs/intent-types.md b/docs/intent-types.md
index 2c70133..1cf13b7 100644
--- a/docs/intent-types.md
+++ b/docs/intent-types.md
@@ -11,3 +11,53 @@ Intents are also considered a proper solution to minimize the consequences of li
[ERC-7683](https://github.com/ethereum/ERCs/blob/master/ERCS/erc-7683.md) proposes a standard API for cross-chain value-transfer systems. A participant called a filler fulfills intents in the destination initiated by users and is paid out through a settlement system. Users are protected since their funds are escrowed in the origin chain and are released when the action is verified, commonly through a message passed and validated.
A CrossChainOrder is initiated (gasless or not gasless) and is resolved even when partitioned into several "legs." Note that the standard does not impose an opinion on the validation mechanism used to verify when an intent is completed.
+
+For a gasless cross-chain Flow:
+
+```mermaid
+---
+config:
+ theme: dark
+ fontSize: 48
+---
+
+sequenceDiagram
+ participant User
+ participant Filler
+ participant OriginSettler as IOriginSettler (Chain A)
+ participant DestinationSettler as IDestinationSettler (Chain B)
+
+ User-->Filler: sign GaslessCrossChainOrder (off-chain)
+ Filler->>OriginSettler: openFor(order, signature, originFillerData)
+ OriginSettler->>OriginSettler: emit Open(orderId, resolvedOrder)
+ Note over OriginSettler: Emits Open with fill instructions
+ Note over Filler: Bridging or messaging flow to
relay fill data cross-chain
+
+ Filler->>DestinationSettler: fill(orderId, originData, fillerData)
+ DestinationSettler->>DestinationSettler: Validates & finalizes fill
+```
+
+For an on-chain cross-chain flow:
+
+```mermaid
+---
+config:
+ theme: dark
+ fontSize: 48
+---
+
+sequenceDiagram
+ participant User
+ participant OriginSettler as IOriginSettler (Chain A)
+ participant Filler
+ participant DestinationSettler as IDestinationSettler (Chain B)
+
+ User->>OriginSettler: open(order)
+ OriginSettler->>OriginSettler: emit Open(orderId, resolvedOrder)
+ Note over OriginSettler: Emits Open with fill instructions
+
+ Filler->>DestinationSettler: fill(orderId, originData, fillerData)
+ DestinationSettler->>DestinationSettler: Validates & finalizes fill
+```
+
+This standard intentionally does not prescribe the specifics of final settlement logic or how cancellations (e.g., revoking an unfilled order) should be handled. Implementations may choose to use any cross-chain messaging system.
From 3e20402a48bbeb615be7a5a623d0efa2eb15f6ad Mon Sep 17 00:00:00 2001
From: Aram Kocharyan
Date: Fri, 28 Feb 2025 22:34:54 +0400
Subject: [PATCH 05/14] Docs: Atomic Swaps with Local Verification (#16)
* docs: add atomic swaps with local verification
* Add sequence diagram
* Fix typo
* add standartization section
* Fix typo
* Simplify
* Rephrease the standartization section
* Add node about settlement time
* Fix formatting of time calculation
* Add Security Considerations section
* Add reference in intent types
---
docs/README.md | 1 +
docs/atomic-swaps.md | 101 +++++++++++++++++++++++++++++++++++++++++++
docs/intent-types.md | 26 +++++++++++
3 files changed, 128 insertions(+)
create mode 100644 docs/atomic-swaps.md
diff --git a/docs/README.md b/docs/README.md
index e198b62..f1865e7 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -12,6 +12,7 @@
## Intents
- [Intent Types](intent-types.md)
+- [Intents with Atomic Swaps](atomic-swaps.md)
## Miscellaneous
diff --git a/docs/atomic-swaps.md b/docs/atomic-swaps.md
new file mode 100644
index 0000000..a0988b7
--- /dev/null
+++ b/docs/atomic-swaps.md
@@ -0,0 +1,101 @@
+# Atomic Swaps with Local Verification
+
+This proposal introduces a mechanism for achieving asset interoperability between Ethereum L2s (and beyond) using Atomic Swaps. The approach does not require a cross-chain messaging protocol, does not introduce new trust assumptions, and remains open and permissionless for any network to participate. It leverages an enhanced version of HTLCs (PreHTLC) in conjunction with recent advancements in local verification techniques, such as running a light client in the browser (e.g., Helios), to achieve two primary objectives:
+
+- Trustless – Users should be able to transfer assets between chains without ever losing control of their funds.
+- Permissionless – Networks should be able to join the protocol without approvals or gatekeepers.
+
+## Intents with PreHTLC
+
+PreHTLC introduces three key improvements over [traditional HTLCs](https://en.bitcoin.it/wiki/Hash_Time_Locked_Contracts):
+
+- Delegated secret management – The Solver is responsible for managing secrets, reducing operational complexity for users.
+- Multiple Solver selection – Users can designate multiple Solvers to fulfill the transaction, mitigating Solver liveness risks.
+- Incentive alignment – A reward/slash mechanism ensures that Solvers are economically incentivized to execute transactions promptly.
+
+This document does not exhaustively cover all [edge cases](https://docs.train.tech/protocol-spec/edge-cases) and [implementation details](https://docs.train.tech) but instead provides a high-level overview of the core process.
+
+## Protocol Walkthrough
+
+```mermaid
+sequenceDiagram
+ participant P1 as User
+ participant SC as Source Chain
+ participant P2 as Solver
+ participant DC as Destination Chain
+
+
+ P1->>SC: commit()
+ SC-->>P2: TokenCommitted
+ P2->>DC: lock()
+ DC-->>P1: TokenLocked(hashlock)
+ P1->>SC: addLock(hashlock)
+ SC-->>P2: TokenLockAdded
+ P2->>SC: redeem(secret)
+ SC-->>P1: User Funds Recieved
+ P2->>DC: redeem(secret)
+ DC-->>P2: Solver Funds Recieved
+```
+
+The following outlines the end-to-end execution when Alice transfers 1 ETH from Starknet to Optimism.
+
+### 1. Transaction initiation
+
+- Alice accesses the Bridge dApp, connects her wallet, and selects the Starknet → Optimism transfer route.
+- The dApp queries the Solver Discovery contract to retrieve a list of available Solvers supporting the route.
+- Alice submits a commit transaction on Starknet, locking 1 ETH and specifying the set of Solvers.
+
+At this point, the locked funds are subject to one of two conditions:
+
+- A `Hashlock` is added once the auction winner is determined.
+- If no Solver successfully acts on this transaction before the `Timelock` expires, Alice can reclaim her funds.
+
+### 2. Solver selection via Auction
+
+- An auction is initiated, where Solvers (e.g., Bob and John) compete for the user's request.
+- Bob wins the auction, generates a secret `S`, computes `Hashlock = HASH(S)`, and locks 1 ETH for Alice on Optimism.
+
+> The auction is completely off-chain, and its sole responsibility is to connect the user with the best solver. The user can skip this step by directly committing to an already known or preferred solver.
+
+### 3. Local verification of the destination transaction
+
+- The dApp performs local verification by monitoring Bob’s transaction on Optimism.
+- If a light client is available, it is utilized for validation. Otherwise, the dApp queries multiple RPC endpoints or a user-specified node.
+- Upon confirming the transaction, the `Hashlock` is retrieved.
+
+#### 3.1 Security considerations
+
+The security of the exchange relies on this step, where the dApp retrieves the `Hashlock`. It is crucial to ensure that the `Hashlock` is correct.
+
+The worst-case scenario occurs when all of the following happen simultaneously:
+
+- There is no Light Client for the destination network.
+- Only a single RPC provider is available for that network.
+- This single RPC provider is also the solver matched with the user.
+
+Even in this case, the user still has the ability to manually verify the destination Hashlock and decide whether to proceed with the transaction.
+
+### 4. Finalization
+
+- Once `Hashlock` is verified, Alice signs a transaction that assigns the `Hashlock` to her previously committed funds and sets the `receiver` to Bob.
+
+At this stage, both chains (Starknet and Optimism) hold funds locked under the same `Hashlock`. The only remaining step is secret revelation.
+
+### 5. Secret disclosure and fund release
+
+- Bob monitors Starknet for confirmation that the commitment is locked in his favor with the expected `Hashlock`.
+- Upon verification, Bob reveals the secret `S` on both chains, proving `HASH(S) = Hashlock`, thereby unlocking and claiming his funds while simultaneously releasing Alice's funds.
+
+## Standardization
+
+The PreHTLC contracts are ownerless, immutable, and have no external dependencies. Their sole responsibility is to ensure that two parties can execute a trustless cross-chain swap. Other components—such as Auction, Discovery, dApp, and Solver—are complementary and can be customized or omitted entirely to suit different use cases.
+
+## Conclusion
+
+By integrating an intent/solver-based framework with PreHTLCs and local verification, this protocol achieves:
+
+- Sub-30-second (`2 x src_block_time + 2 x dst_block_time`) settlement times for cross-chain transfers.
+- Neither Users’ nor Solvers’ funds are ever controlled by an intermediary.
+- Any blockchain network can be onboarded without requiring explicit permission.
+
+This approach ensures a scalable and trustless mechanism for cross-chain asset transfers without relying on third-party validators or external security mechanisms.
diff --git a/docs/intent-types.md b/docs/intent-types.md
index 1cf13b7..6598352 100644
--- a/docs/intent-types.md
+++ b/docs/intent-types.md
@@ -61,3 +61,29 @@ sequenceDiagram
```
This standard intentionally does not prescribe the specifics of final settlement logic or how cancellations (e.g., revoking an unfilled order) should be handled. Implementations may choose to use any cross-chain messaging system.
+
+## Intents with Atomic Swaps
+
+[This proposal](atomic-swaps.md) introduces a mechanism for achieving asset interoperability between Ethereum L2s (and beyond) using Atomic Swaps. The approach does not require a cross-chain messaging protocol, does not introduce new trust assumptions, and remains open and permissionless for any network to participate.
+
+```mermaid
+sequenceDiagram
+ participant P1 as User
+ participant SC as Source Chain
+ participant P2 as Solver
+ participant DC as Destination Chain
+
+
+ P1->>SC: commit()
+ SC-->>P2: TokenCommitted
+ P2->>DC: lock()
+ DC-->>P1: TokenLocked(hashlock)
+ P1->>SC: addLock(hashlock)
+ SC-->>P2: TokenLockAdded
+ P2->>SC: redeem(secret)
+ SC-->>P1: User Funds Recieved
+ P2->>DC: redeem(secret)
+ DC-->>P2: Solver Funds Recieved
+```
+
+This approach ensures a scalable and trustless mechanism for cross-chain asset transfers without relying on third-party validators or external security mechanisms.
From 926381d8f57522b39ea15c73b767c14f8eda1d3a Mon Sep 17 00:00:00 2001
From: Joxes <91908708+Joxess@users.noreply.github.com>
Date: Mon, 3 Mar 2025 12:57:20 -0300
Subject: [PATCH 06/14] docs: Introduce interop nomenclatures (#24)
---
NOMENCLATURE.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/NOMENCLATURE.md b/NOMENCLATURE.md
index d4badc3..19d0b64 100644
--- a/NOMENCLATURE.md
+++ b/NOMENCLATURE.md
@@ -1,9 +1,67 @@
# Nomenclature
+This document defines the common terminology and conventions to be used across all interoperability standards and related documents in this repository.
+
+## Core Terminology
+
+- **L1 (or Layer 1)**: A blockchain that is self-reliant on its validator set for its security and consensus properties. While it may refer to any blockchain that fits this definition, it commonly refers to the Ethereum Mainnet.
+- **L2 (or Layer 2)**: A blockchain aimed to scale the L1 in a trust minimized way while maintaining a "safe bridge" between them. Blockchains in this category include Rollups and Plasma solutions, and may also include other less-secure solutions such as Validiums and Optimiums. For a detailed characterization of this category, please refer to [L2Beat](https://l2beat.com/).
+- **L3 (or Layer 3)**: A blockchain that follow a similar structure to the L2 <> L1 structure but with an L2 underneath.
+- **General-Purpose Chain**: A chain that supports arbitrary logic.
+- **App-Specific Chain**: A chain that supports only specific types of applications or functionalities.
+- **Origin Chain**: The chain where a user starts a cross-chain operation. In the context of assets, this could be where the user's funds or assets currently reside.
+- **Destination Chain**: The chain where the desired side effects of a cross-chain operation are received or executed. In the context of assets, this could be where the user receives the funds.
+- **Bridge**: A system enabling communication between chains. Others may use the term "Gateway".
+- **User**: The end-user initiating a cross-chain operation.
+- **Sender**: The account/contract initiating a message on the origin chain.
+- **Receiver**: The account/contract receiving a message on the destination chain.
+- **Relayer**: An entity facilitating message transmission between chains.
+
+
## Addresses
+- **Chain Identifier**: A unique identifier for a blockchain used as part of the address formated. Do not confuse it with the Chain ID introduced in [EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md), even though it may be used as a reference in some cases.
+- **Chain Name**: A human-readable identifier for a blockchain.
+
## Assets
+- **Single `Mint` and `Burn`**: A pattern used in cross-chain operation where tokens are burned (supply decreased) on origin chain and minted (supply increased) on destination chain to simulate the effect of tokens "moving" between chains. Both token contracts should represent the same asset. These operations are not subject to market conditions and follow fixed output rules (e.g., maintaining 1:1 equivalence over time). This approach is sometimes referred to as `crosschainBurn`/`crosschainMint` or `bridgeBurn`/`bridgeMint`.
+
+- **`Deposit` and `mint` / `Burn` and `Withdraw`**: A pattern used in cross-chain operations where tokens are deposited into a contract acting as escrow on the origin chain, triggering the minting of tokens on the destination chain. Similarly, tokens can be burned on one chain to facilitate their withdrawal on another. These operations are not subject to market conditions and follow fixed output rules (e.g., maintaining 1:1 equivalence over time). This approach is sometimes referred to as `Lock` and `Unlock`.
+
## Intents
+- **`Fill`**: The act of a participant (called a `filler` or `solver`) executing a user's cross-chain intent on the destination chain(s) - for example, delivering tokens or executing a swap that the user requested.
+- **`Leg`**: A portion of the user's intent that can be executed independently from the others. All legs must be executed for an intent to be considered fulfilled.
+- **Resource Lock**: A contract-based escrow mechanism that holds a user’s deposited assets until a cross-chain operation is verified and settled. It might supports conditional allocations—allowing designated parties to claim portions of the locked tokens based on predetermined conditions.
+- **Settlement**: The process that happens after a successful fill where the system verifies the fill was executed correctly and handles the financial aspects —specifically, releasing the user's deposited funds to pay the filler for their service. The contract responsible for managing deposits and payments is called the **Settler** and may use a cross-chain verification method.
+
## Messaging
+
+- **Message**: Information transmitted between chains.
+ - **`send`**: The act of marking information on the origin chain to be transmitted to another chain(s). Functions in existing implementations are tipically named as `sendMessage` or others.
+ - **Aggregation**: Combining multiple cross-chain messages (possibly from multiple origin chains) to finalize them on the destination chain in a single transaction or proof.
+ - **`receive`**: Used to denote the act of receiving a message. Depending on the context, receiving a message may have its own flow or involve multiple steps. Functions in existing implementations are tipically named as `receiveMessage`, `relayMessage`, `validateMessage`, `executeMessage` or others.
+- **`Metadata`**: Information about the message (sender, receiver, nonce, etc.)
+ - **`ChainId`**: Referes the chain identifier. Existing implementations might refer to it as "domain" instead of "chain," or simply as the destination.
+- **`Payload`**: The actual data orinstructions being transmitted.
+- **Verification**: The process of validating cross-chain messages.
+- **Push-based**: A full cross-chain transmission lifecycle (including destination execution) can be arranged by a transaction on the origin chain, typically relying on in-protocol methods or third-party relayers.
+- **Pull-based**: Requires a user (or application) to complete the lifecycle on the destination chain (so-called “self-relaying”).
+
+
+
+---
+
+
+
+## Updates:
+
+This document should be updated when:
+1. New standards introduce novel concepts
+2. Existing terminology requires clarification
+3. Community feedback suggests improvements
+
+## Acknowledgments
+
+This document draws its terminology and nomenclature from established (or proposed) Ethereum/Blockchain standards—see the standard references throughout this repository—as well as widely accepted sources such as L2Beat, and aims to reflect the general consensus.
From 842600e1ba130240a810749f4533791cecd524fe Mon Sep 17 00:00:00 2001
From: Joxes <91908708+Joxess@users.noreply.github.com>
Date: Fri, 7 Mar 2025 14:40:27 -0300
Subject: [PATCH 07/14] Feat: Create chain-specific addresses user stories
(#25)
* Create csa-user-stories.md
* improve user stories and allow chain discovery
* add DS1
* add us5 and feedback
* split sharing address/name case and apply feedback
---
docs/csa-user-stories.md | 116 +++++++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
create mode 100644 docs/csa-user-stories.md
diff --git a/docs/csa-user-stories.md b/docs/csa-user-stories.md
new file mode 100644
index 0000000..0c85171
--- /dev/null
+++ b/docs/csa-user-stories.md
@@ -0,0 +1,116 @@
+# Chain-Specific Addresses: Users-Stories
+
+This document outlines the user stories as a goal for implementing chain-specific addresses. These stories capture key use cases and acceptance criteria for both end-users and developers, and do not express an opinion on specific implementations.
+
+**End-users** refers to those who consume the production release, and **developers** are those who integrate or build on top of it.
+
+## End-User Stories
+
+### US1: Basic Send to Another Chain
+
+**As an end-user**:
+
+I want to send asset to any address, regardless of which chain it is on.
+
+**Rationale**: I should be able to send assets as easily as if everything was on a single chain.
+
+> 📌
+> **Acceptance Criteria:**
+> - Wallet detects and shows the destination chain when address is provided.
+> - Error prevention if sending to a non-existent account (e.g. non-registered address given a name).
+> - The chain-specific address should be clearly visualized.
+> - Clear separation between source and destination chain.
+> - Optional: Transfer method and costs are shown afterwards (Intents/Bridges).
+
+### US2: Human-Readable Name Usage Across Chains
+
+**As an end-user**:
+
+I want to send assets using a human-readable Name.
+
+**Rationale**: I want to avoid dealing with raw addresses.
+
+> 📌
+> **Acceptance Criteria:**
+> - The Human-Readable name to chain-specific addresses conversion is unambiguous; the wallet must display the checksum for safety.
+> - Validates the existence of resolved addresses.
+> - Chain information is shown.
+> - Optional: shows full-resolved machine address.
+
+### US3: Send Asset Error Prevention
+
+**As an end-user**:
+
+I want to be warned if I’m sending to potentially inexistent chain or address.
+
+**Rationale**: I can avoid losing funds.
+
+> 📌
+> **Acceptance Criteria:**
+> - All US2 acceptance criteria apply here.
+> - If account is not found, warn about non-existent account.
+> - If chain is not found, warn about a non-existent destination chain.
+> - Optional: If chain identifier is intuitively distinguishable (e.g. ENS domains or CAIP-2 chain identifier mispellings), suggest correction and let the user decide whether to continue.
+
+### US4: Sharing a Cross-Chain Address
+
+**As an end-user:**
+
+I want to share a complete, unambiguous machine address so that the recipient knows exactly which chain and address they are sending funds to.
+
+**Rationale**: I can receive funds, preventing losses.
+
+> 📌
+> **Acceptance Criteria:**
+> - Cross-chain address should be deterministically resolved into raw address + chain identifier.
+> - No ambiguity is allowed.
+> - Optional: US6 (see below) is triggered if chain is unknown.
+
+### US5: Sharing a Name
+
+**As an end-user:**
+
+I want to share a human-readable name that can be resolved to one (or more) cross-chain addresses so that it’s more user-friendly and still prevents accidental misrouting.
+
+**Rationale**: Sharing a name is more conveniente than a raw address.
+
+> 📌
+> **Acceptance Criteria:**
+> - The human-readable name must be deterministically resolved into at least one cross-chain address.
+> - If a name corresponds to multiple cross-chain addresses, default to one or show options.
+> - Checksum should guard against accidental collisions.
+
+### US6: Support for Unknown Chains
+
+**As an end-user**:
+
+I want to send assets to addresses on chains that my wallet hasn't explicitly integrated with.
+
+**Rationale**: I shouldn't be limited to only sending assets to chains that my wallet already knows about.
+
+> 📌
+> **Acceptance Criteria:**
+> - Validates the existence of the chain through a trusted provider (e.g. bridging service in the short term, and through an on-chain list of chain configs in the long term).
+> - Fetch chain config and confirms compatibility.
+> - Validates the existence of resolved addresses.
+> - Shows confirmation with chain information.
+> - Clearly indicates this is a new/unknown chain to the user.
+> - Optional: Allows user to save chain for future use.
+
+
+## Developer Stories
+
+### DS1: Parsing and Validating Addresses
+
+**As an wallet/dApp developer**:
+
+I want a straightforward API to parse a chain-specific address (e.g., "chain:0x123...") and validate its correctness,
+so that I can accept user inputs and avoid sending transactions to invalid or ambiguous destinations.
+
+**Rationale**: I can reduce the risk of ambiguity and then error.
+
+> 📌
+> **Acceptance Criteria:**
+> - There is libraries that accepts a chain-specific string and outputs a result (e.g., {`chainIdentifier`, `rawAddress`}, which are based in ehtereum-lists/chains, ERC-7785 or others).
+> - Distinguishable for cases where the same address format is used (e.g. in the case of raw addresses in EVM)
+> - confirm chain identifiers against a known registry.
From 6951e96e8b7b9ad14b1072edb482f69e81fc3396 Mon Sep 17 00:00:00 2001
From: Joxes <91908708+Joxess@users.noreply.github.com>
Date: Mon, 10 Mar 2025 10:45:33 -0300
Subject: [PATCH 08/14] feat: add chain-specific addresses properties (#11)
* add comparison table
* add chain-specific addresses properties
* add comparison as reference
* separate user and machine errors
* remove a should-have property
"Support for both user-facing and programmatic formats"
* move security properties into must-have
* correct caip-10 format
* update comparison table
* update table
Correct EVM support in ERC-7828
* update table
Clarify readability feature
* remove flexibility field
* improve checksum field
clarify ERC-3770 status
* improve chain list field
* add status field
* improve properties
* update comparison table
* add ensip-9 and ensip-11
* add address layers
* add ensip-9 and ensip-11 comparison
* separation of concerns and feedback
* correct title
Cross-Chain Addressing -> Naming
Co-authored-by: Francisco Giordano
* improve csa properties
* feat: Interoperable address spec (#14)
* docs: address types draft with trivial resolvers
* fix: initial feedback by joxes
* feat: ens resolver spec
* fix: fixes from self-review
* feat: checksum as a layer of defense on human-readable names
* feat: interoperable addresses explainer doc (#28)
* docs: address types draft with trivial resolvers
* fix: initial feedback by joxes
* feat: ens resolver spec
* fix: fixes from self-review
* feat: checksum as a layer of defense on human-readable names
* docs: interoperable address explainer
---------
Co-authored-by: Francisco Giordano
Co-authored-by: teddy
---
PROPERTIES.md | 100 +++++++++++-
docs/addresses-current-efforts.md | 24 +++
docs/interoperable-address-explainer.md | 52 +++++++
specs/address-types.md | 197 ++++++++++++++++++++++++
4 files changed, 372 insertions(+), 1 deletion(-)
create mode 100644 docs/interoperable-address-explainer.md
create mode 100644 specs/address-types.md
diff --git a/PROPERTIES.md b/PROPERTIES.md
index ccb8d12..59c2028 100644
--- a/PROPERTIES.md
+++ b/PROPERTIES.md
@@ -1,3 +1,101 @@
# Properties
-[WIP]
+This document outlines the required properties for existing interoperability tracks. For each one, properties are categorized as:
+
+- **Must-have**: Core requirements that any solution MUST implement
+- **Should-have**: Important features that solutions SHOULD implement
+- **Nice to have**: Optional features that improves the solution
+- **Non-Goals**: Explicitly out of scope
+
+# Chain-Specific Addresses
+
+L2s and interconnected chains complicate how we identify accounts and targets for transactions. This becomes clear when looking at common scenarios:
+* Same address on different chains representing completely different entities (or some of them do not "exist").
+* Different addresses across chains representing the same logical entity.
+
+From the integration perspective, we can separate cross-chain identification into two distinct concerns:
+
+- **Cross-Chain Naming**: Human-readable names or identifiers that can be resolved to cross-chain addresses (e.g., alice@rollup.eth).
+- **Cross-Chain Addressing**: Machine-readable addresses for uniquely identifying addresses across chains (e.g., eth:rollup:0x123...abc).
+
+_For a comparison of current efforts, see [here](./docs/addresses-current-efforts.md)._
+
+The following properties outline the requirements for solutions in both spaces.
+
+## Cross-Chain Addressing
+
+### Must-have
+
+1. **Address Uniqueness**
+- Unique (and thus, canonical) identification of addresses per chain
+- Prevention of cross-chain ambiguity
+
+2. **Format Compatibility**
+- Support for arbitrary "blockchain" address formats (not constrained to EVM)
+- Consistent encoding/decoding of its format
+
+3. **Implementation Requirements**
+- Deterministic resolution from chain identifier + address
+- Clear error handling for invalid identifiers
+- Support for checksums and pre-validations
+
+### Should-have
+
+1. **Extensibility**
+- Support for chain hierarchies (L1/L2/L3)
+- Support for future chain types and formats
+- Flexibility in implementation details
+
+2. **Integration Support**
+- Alignment with existing standards (DIDs, CAIP-10)
+
+### Nice to Have
+
+- Resolution path using on-chain config registries
+
+### Non-Goals
+
+- Human readability as primary concern
+- Enforcing specific name resolution services
+- Standardizing chain identifiers (covered by other standards)
+
+## Cross-Chain Naming
+
+### Must-have
+
+1. **Name Resolution**
+- Deterministic resolution to cross-chain addresses
+- Support for hierarchical naming patterns
+- Clear chain identification within names
+
+2. **User Interface**
+- _Human_-readable format
+- Reasonable length for manual validation
+- Clear syntax for separating name and chain components
+
+3. **Wallet Implementation Requirements**
+- Trusted verification method (e.g. on-chain registry)
+- Safe handling of malformed or invalid names
+
+### Should-have
+
+1. **Integration Support**
+- Compatibility with name service resolution (ENS, etc.)
+- Alignment with identity standards (DIDs)
+
+2. **Error Prevention**
+- Support for checksums at the name level
+
+### Nice to have
+- Reliance path in on-chain config registries
+
+### Non-Goals
+- Enforcing specific name resolution services
+
+## Message Passing
+
+[To be added]
+
+## Cross-Chain Intents
+
+[To be added]
diff --git a/docs/addresses-current-efforts.md b/docs/addresses-current-efforts.md
index c27c436..8505857 100644
--- a/docs/addresses-current-efforts.md
+++ b/docs/addresses-current-efforts.md
@@ -16,6 +16,30 @@ A core challenge in Ethereum's multichain landscape is disambiguating addresses
[ERC-7828](https://ethereum-magicians.org/t/erc-7828-chain-specific-addresses-using-ens/21930) builds on top of [ERC-7785](https://ethereum-magicians.org/t/erc-7785-onchain-registration-of-chain-identifiers/21299), to integrate with ENS, enabling the storage of chain names within an existing chain ID mapping and moving registrations away from centralized registries. Address formats could take the form of `alice@rollup` or `alice.rollup.eth`, which can be resolved on-chain through wallets.
+## ENSIP-9: Multichain Address Resolution
+
+[ENSIP-9](https://github.com/ensdomains/ensips/blob/master/ensips/9.md) introduces a unified way for ENS resolvers to store and return addresses for different blockchains by overloading the `addr` function. Rather than proposing a textual format like `chain:address`, ENSIP-9 leverage from coin types (following [SLIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md)). This allows resolvers to identify each blockchain by its unique coin type and store the address in its native binary form (such as 20-byte hex for Ethereum, base58-decoded bytes for Bitcoin, etc).
+
+### ENSIP-11: EVM compatible Chain Address Resolution
+
+[ENSIP-11](https://github.com/ensdomains/ensips/blob/master/ensips/11.md) extends ENSIP-9 by introducing a dedicated range of coin types for EVM chains. This range prevents collision with existing [SLIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) coin types.
+
+## Comparison
+
+The existing approaches to chain-specific addresses represent an evolution in thinking about cross-chain identification rather than competing solutions. Some standards builds upon lessons learned from previous implementations while other targets other aspects or they could built on top of.
+
+| **Feature** | ERC-3770 | CAIP-10 | ERC-7828 | ENSIP-9/ENSIP-11 |
+| --- | --- | --- | --- | --- |
+| **Scope** | Primarily a UI/UX layer standard for human-readable prefixes | A universal account identifier format (machine-readable) for all blockchains | On-chain naming integration with ENS (for chain names and addresses), EVM-focused | ENS resolver-level standards for storing/retrieving multi-chain addresses |
+| **Status** | Draft (Fully defined) | Final (Fully defined) | Draft (Incomplete) | Final/Draft |
+| **Format Example** | `chain:address` | `chain_namespace:chain_reference:address` | `address:chain.eth` or `address@chain.eth` | Still uses typical `.eth` format |
+| **Human Readability (_best-case scenario_)** | Medium | Medium | High | High (from typical ENS format) |
+| **Technical Compatibility** | EVM only (but extensible) | All chains | EVM only (potential non-EVM support) | Blockchain that are part of [SLIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) or follows EVM `chainId` specs |
+| **ENS Integration** | Not Required | Not Required | Required | Required |
+| **DID Compatibility** | | | | |
+| **Checksum Support** | Incomplete (ERC-55 only) | No | Yes | Yes |
+| **Usage of lists** | Yes (referencing github.com/ethereum-lists/chains) | No | Yes (requires ERC-7785 aka onchain registry) | Base in [SLIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) |
+
# Additional Considerations
Unique chain identifiers rely on social consensus to avoid collisions that could break integrations. The transition from off-chain registries to on-chain methods in the Ethereum ecosystem has been widely discussed and documented [here](chain-registries.md).
diff --git a/docs/interoperable-address-explainer.md b/docs/interoperable-address-explainer.md
new file mode 100644
index 0000000..333eb67
--- /dev/null
+++ b/docs/interoperable-address-explainer.md
@@ -0,0 +1,52 @@
+Introducing: Interoperable Addresses
+====
+
+Interoperable Addresses is a standard defining address formats for a multi-chain world.
+
+For a normal user, they look like this:
+
+
+
+ 3::vitalik.eth@eth#5966be0f
+
+
+
+- 3::
: the Interoperable Address Resolver version, which your wallet may very well omit.
+- vitalik.eth
: A human-readable name, specific to a chain. Supported by (anything looking like) ENS.
+- eth
: A human-readable chain name, defined by either https://github.com/ethereum-lists/chains if available (same registry for ERC-3770) or CAIP-2 in all other cases.
+- 5966be0f
: A checksum so you can at a glance validate what you see matches what you expect to be under the hood.
+
+---
+
+For nerds and computers, however, they look like this:
+
+
+
+ 3:eip155:1:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#5966be0f
+
+
+
+- 3:
: Interoperable Address version.
+- eip155:1
: CAIP-2 id of chain where the naming registry is located
+- 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
: Address where to find the naming registry
+- eip155:1
: CAIP-2 id of chain we are referring to
+- 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
: Chain-specific address we are targeting in that chain
+- 5966be0f
: Checksum of all previous fields, to make sure nothing got lost in transit
+
+---
+
+The Interoperable Address is a format for strings to:
+- Fully specify an address on a particular chain (using CAIP-10), supporting any EVM-ecosystem chain and any chain on SLIP-044.
+- Also include the information to display it to a human in a readable way, as displayed above.
+
+Some of its features are:
+- Uses mature technologies such as CAIP-10 and ENS.
+- Is extensible for future resolving mechanisms (eg: ERC-7785, when/if it reaches production).
+- Resolution of Interoperable Addresses to human readable names is fully deterministic.
+- Edge cases are securely abstractable to a library/SDK for wallets.
+- Does not enshrine a particular ENS contract, making it flexible for a future naming-only rollup, instances on other rollups or even an ENS fork.
+
+And, in all honesty, it has some drawbacks as well:
+- Exposes a version number to users (although that can be mitigated by wallet UX)
+- Supporting different name resolution contracts mean human-readable name -> machine address resolution can produce different results (which is mitigated by the checksum)
+- Wallets will have to maintain a set of name resolving contracts considered trustworthy, with a trust model similar to RPC urls (can be taken care of by a library/SDK, but user overrides should be supported).
diff --git a/specs/address-types.md b/specs/address-types.md
new file mode 100644
index 0000000..3828beb
--- /dev/null
+++ b/specs/address-types.md
@@ -0,0 +1,197 @@
+# Cross-chain interoperable addresses specification
+This document, in its current state, aims to be the starting point for a future address format called 'Interoperable Address' whose aims & properties are fully described in [a separate document](../PROPERTIES.md)
+
+Requires: CAIP-10
+
+## Abstract
+An extensible way to describe an address specific to one chain which includes the information to securely condense it into a human-readable name.
+
+## Out of scope concerns
+Similarly to CAIP-10, this specification is not concerned with the mapping from a chain id to a network name, which might not be surjective (eg: the case where if there are multiple EIP-155 chains with chain id 8453, which one should we call Base?), regarding that resolution a social-layer problem until a future ERC decides to tackle it. Efforts in that front are tracked in [the chain registires document](../docs/chain-registries.md)
+
+## Definitions
+Account id
+: A string which unambiguously corresponds to an address on a specific chain (EVM or not).
+
+Human-readable name
+: A shorter representation of an account id
+
+Interoperable address
+: A string which includes both an account id and a _resolver specification_ which, together with this (and potentially future) ERCs, allows conversion to a human-readable name in a way that requires no further trust assumptions than those the wallet software executing said conversion already operates under.
+
+## Machine address format definition
+
+### Syntax
+
+```bnf
+ ::= ::#
+ ::= :
+ ::= [0-9]{1,4}
+ ::= [-.%a-zA-Z0-9]* // same as CAIP-10 account address format
+ ::= [0-9a-f]{8}
+```
+
+### Semantics
+- Similarly to CAIP-10, the resolver payload has `%` as a valid character to enable URL-escaping of arbitrary characters
+ - The rules for wether to parse URL escaping in a resolver payload are specific to the resolver version
+ - The rules for wether to parse URL escaping in a CAIP-10 account address are specific to its CAIP-2 chain namespace
+- To maintain the bijectivity of account ids and therefore interoperable addresses to on-chain addresses:
+ - In CAIP-2 namespaces where there is a canonicalization scheme (such as EIP-55 in EIP-155 chains) it SHOULD be used.
+ - In CAIP-2 namespaces where addresses have an *optional* checksum field, it MUST be omitted and the checksum defined in the standard be used without redundancy
+ - In CAIP-2 namespaces where addresses are raw hexadecimal data without an EIP-55-equivalent capitalization scheme, the lowercase `a-f` characters MUST be used instead of uppercase ones.
+ - In the case of EIP-155 chains, EIP-55 canonicalization MUST be used
+- The checksum MUST be the hexadecimal representation first four bytes of the keccak-256 hash of UTF-8 representation of the interoperable address from it's beginning up to and including the hash `#` character separating the checksum from the rest of the address.
+
+## Human-readable name format definition
+
+### Syntax
+```bnf
+ ::= =
+ ::= [0-9]{1,4}
+ ::= [@-.%a-zA-Z0-9]*
+```
+
+## Rationale
+- In order to guarantee future resolvers don't share prefixes with existing resolvers in an ambiguous way, and therefore human-readable names are always mappable to a single machine address, this standard defines the human-readable names to start with the resolver version. (TODO: ideally we should be smarter about this and resolve it in a way that doesn't expose this implementation quirk to users)
+- Similarly to CAIP-10, arbitrary characters can be url-encoded.
+
+## Resolver version definitions
+
+### `0` : No resolution
+This is used to indicate no resolution, with the human-readable name being equal to the machine address. The machine address MUST be shown in full.
+
+#### Examples:
+Machine address
+: `0:::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#6164da10`
+
+Human-readable name
+: `0:::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#6164da10`
+
+### `1` : No resolution, compact format
+This is used to indicate no resolution, but removing all redundant information that can be verified by the wallet. It is equivalent to the CAIP-10 account id, with the canonicalization caveat described above.
+
+#### Examples:
+Machine address
+: `1:::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#b50c58f9`
+
+Human-readable name
+: `1::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045`
+
+### `2` : ERC-3770 chain name resolution only
+The human-readable name in this approach is consistent with the address format defined in ERC-3770, and similarly depends on the EF's mapping of chain ids to names maintained in github at: https://github.com/ethereum-lists/chains
+
+#### Human-readable name format
+
+```bnf
+ ::= 2:::
+```
+Since wallet software can always validate the checksum, it MUST be removed.
+
+EIP-55 or applicable scheme is used for canonicalization only.
+
+#### Examples:
+
+Machine address
+: `2:::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#bc797def`
+
+Human-readable name
+: `2::eth:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045`
+
+### `3` : ENSIP-11 + ENSIP-19 for raw address resolution + ethereum-lists chain name resolution
+This resolver relies on the centralized [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) list for ENS standards compliance and on the one used by ERC-3770 to define the short chain names.
+
+The machine address, in turn, specifies what will the source of truth be for the `raw address -> ens-like name` mapping, expecting it to conform to ENSIP-11.
+
+The chain/contract on which the ENSIP-11 contract used to resolve the human-readable name resides is abstracted away from the user, but implementing wallets MUST maintain a list of those considered trustworthy and warn the user or choose to display the machine address in full when the contract it instructs to use is outside the set.
+
+Also, wallets MAY have a default registry they use for converting human-readable names into machine addresses. This means different wallets could potentially resolve the same human-readable name to different machine addresses which potentially also map to different raw addresses. This should be mitigated by wallets' choices of valid and default registries.
+
+#### Human-readable name format
+
+```bnf
+ ::= 3::@#
+ ::= |
+```
+
+#### Machine-address format
+
+```bnf
+ ::= 3:::#
+```
+
+#### `machine address -> human-readable name` resolution
+1. Extract CAIP-2 `chainId` and raw address from ``.
+ - Failure mode: wallet can't call the contract (eg: does not have access to an rpc of that chain)
+ - Failure mode: `chainId` is not an EVM address
+2. Look up in wallet's 'trusted registry' set (which MAY be locally updated by the user) and see if the contract is contained in it. If it is not, issue a warning to the user.
+3. Extract `chainId` and raw address from ``.
+4. Convert `chainId` from step above into ENSIP-11 `coinType`
+5. Compute the namehash for the ENSIP-19 reverse resolution from the results of step 3 and 4
+ - TODO: check if ambiguities or other edge cases are possible when converting from CAIP-10 into the raw form required by ENSIP-11
+6. Call `resolver(bytes32 node)`on the contract obtained in step 1, using the value from the step above for `node`.
+7. Call `name(bytes32 node)` on the contract returned by the step above. Save the response as the ``.
+8. Check direct resolution of name obtained in the step above, and fail the resolution if it does not match, as described in ENSIP-19
+9. For the ``, extract the CAIP-2 chain id from ``. If said chain has an entry in ethereum-lists, display its shortname. Otherwise, display the raw CAIP-2 chain id.
+10. Append the checksum from the machine address.
+
+#### `human-readable name -> machine address ` resolution
+1. Let the user input a destination chain name, and convert it to a CAIP-2 chainId.
+2. Convert the result from step 1 into an ENSIP-11 `coinType`.
+3. Let the user input a unicode string instead of the punycode-encoded name.
+4. Convert the string from step 3 into a punycode-encoded name.
+5. Compute the punycode-encoded name's namehash.
+6. Call `addr(namehash, coinType)` on the wallet's default resolver, with the values from steps 5 and 2 respectively.
+ - If it returns the zero address, prompt the user to pick another trusted resolver where the name is defined.
+ - Failure mode: name cant be resolved with trusted resolvers.
+7. Construct `` with the resolver used in the step above.
+8. Construct `` with the address returned in step 6 and the destination chain from step 1.
+9. The user should obviously not be prompted for the checksum, but it MUST be displayed somewhere in the wallet UI for the user to optionally validate with the receiver that they are using the same resolver.
+10. Wallets MAY choose to display the full machine address as well.
+
+#### Pre-validations
+- The CAIP-2 `chain_id` included within both CAIP-10 account ids can be mapped to a valid ENSIP-11 `coinType` which extends both ENSIP-9 and SLIP44
+
+#### Semantics
+- ENS uses [punycode](https://www.unicode.org/reports/tr46/) to encode non-ascii characters, which SHOULD be rendered by wallets. In cases where the wallet could infer the presence of non-ascii characters to be unlikely (eg: depending on locale), a warning MAY also be issued to the user.
+- `` is to be the fully qualified name, including the TLD.
+- For chains listed in `ethereum-lists/chains`, the short name MUST be used, taking precedence over the CAIP-2 chain id.
+
+#### Rationale
+This is proposed as a way to have functional human readable names with existing tooling and infrastructure, while being flexible in not enshrining a particular contract to allow for future changes on where & how names are resolved. Future developments in chain configs and name registries should improve upon it's decentralization characteristics and render it obsolete in the long-term.
+
+Since it's possible for users' wallets to use different name registries by default when computing a machine address from a human-readable name, the checksum for the machine address is provided as a layer of defense against losing funds either by mis-configuration or deliberate attacks taking advantage of the differences between the data contained in different naming registries.
+
+#### Examples:
+
+Machine address
+: `3:eip155:1:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e::eip155:10xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#5966be0f`
+
+Human-readable name
+: `3::vitalik.eth@eth`
+
+#### Security considerations
+- If the resolver lives in the destination/source chains, then securing a trustworthy RPC is already in scope of the wallet's responsibilities to operate safely
+- If the resolver lives in L1 or a name-specific rollup, then presumably it's feasible to run a light client of said network as part of the infrastructure trusted by the wallet
+
+## Requirements for wallet software
+- When parsing the CAIP-10 `account_address` for a CAIP-2 chain namespace where URL-escaping or the `%` character is not part of valid addresses, finding URL-encoded data MUST be treated as an error.
+- Wallet software MUST perform all relevant pre-validations, including verifying the checksum, and report any errors to the user, for every defined resolver. Wallets MAY reject an interoperable address solely on the basis of these checks failing.
+- TODO: what to do when a machine address' resolver version is not supported by the wallet
+ - option 1: show it as is -> easiest
+ - option 2: convert it to resolver `1` -> guarantees not-that-bad-to-read address is shown to the user, might impose extra constraints on existing resolvers.
+
+## Recommendations for rollups
+TODO: probably coupled to ERC-7785, currently out of scope
+
+## Rationale
+- URL-escaping of characters might be necessary for future resolvers
+- Checksum algorithm is independent of used resolution method to allow wallets to validate an interoperable address' checksum despite not being able to generate its human-readable name
+- Ideally we'd want the resolution method to be fully abstracted away from the user, but that might not be achievable in every case. The next best thing is to prefix every human-readable name with a string denoting which method to use, which prevents the user ever being prompted to choose different addresses based on the resolution method used for each, which would be a more confusing and riskier UX
+
+## Compatibility with other public-key sharing standards
+
+### W3C DID
+TODO
+
+## Security considerations
+
From db4ec7a502f57ecf4ae072e3e0a2dd482c518c25 Mon Sep 17 00:00:00 2001
From: Joxes <91908708+Joxess@users.noreply.github.com>
Date: Tue, 11 Mar 2025 12:41:11 -0300
Subject: [PATCH 09/14] feat: folder restructuration (#29)
Includes:
- add new folders
- update READMEs
- update links
---
PROPERTIES.md | 2 +-
docs/README.md | 18 ++++++++++--------
.../csa-current-efforts.md} | 0
docs/{ => addresses}/csa-user-stories.md | 0
.../interoperable-address-explainer.md | 2 ++
docs/{ => assets}/asset-types.md | 0
docs/{ => intents}/atomic-swaps.md | 0
docs/{ => intents}/intent-types.md | 0
.../messaging-current-efforts.md} | 0
specs/README.md | 7 ++++---
...ross-chain-interoperable-addresses-spec.md} | 0
11 files changed, 17 insertions(+), 12 deletions(-)
rename docs/{addresses-current-efforts.md => addresses/csa-current-efforts.md} (100%)
rename docs/{ => addresses}/csa-user-stories.md (100%)
rename docs/{ => addresses}/interoperable-address-explainer.md (96%)
rename docs/{ => assets}/asset-types.md (100%)
rename docs/{ => intents}/atomic-swaps.md (100%)
rename docs/{ => intents}/intent-types.md (100%)
rename docs/{messaging-comparisons.md => message-passing/messaging-current-efforts.md} (100%)
rename specs/{address-types.md => addresses/cross-chain-interoperable-addresses-spec.md} (100%)
diff --git a/PROPERTIES.md b/PROPERTIES.md
index 59c2028..f80af44 100644
--- a/PROPERTIES.md
+++ b/PROPERTIES.md
@@ -18,7 +18,7 @@ From the integration perspective, we can separate cross-chain identification int
- **Cross-Chain Naming**: Human-readable names or identifiers that can be resolved to cross-chain addresses (e.g., alice@rollup.eth).
- **Cross-Chain Addressing**: Machine-readable addresses for uniquely identifying addresses across chains (e.g., eth:rollup:0x123...abc).
-_For a comparison of current efforts, see [here](./docs/addresses-current-efforts.md)._
+_For a comparison of current efforts, see [here](./docs/chain-specific-addresses/csa-current-efforts.md)._
The following properties outline the requirements for solutions in both spaces.
diff --git a/docs/README.md b/docs/README.md
index f1865e7..346cf3b 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,18 +1,20 @@
# Documentation Index
-## Addresses (& chains)
-- [Current efforts](addresses-current-efforts.md)
+## Addresses
+
+- [Current Efforts](addresses/csa-current-efforts.md)
+- [User Stories](addresses/csa-user-stories.md)
+- [Interoperable Address: Explainer](addresses/interoperable-address-explainer.md)
## Assets
-- [Comparisons](assets-comparisons.md)
-- [Asset Types](asset-types.md)
+- [Asset Types](assets/asset-types.md)
-## Messaging
-- [Comparisons](messaging-comparisons.md)
+## Message Passing
+- [Current Efforts](message-passing/messaging-current-efforts.md)
## Intents
-- [Intent Types](intent-types.md)
-- [Intents with Atomic Swaps](atomic-swaps.md)
+- [Intent Types](intents/intent-types.md)
+- [Intents with Atomic Swaps](intents/atomic-swaps.md)
## Miscellaneous
diff --git a/docs/addresses-current-efforts.md b/docs/addresses/csa-current-efforts.md
similarity index 100%
rename from docs/addresses-current-efforts.md
rename to docs/addresses/csa-current-efforts.md
diff --git a/docs/csa-user-stories.md b/docs/addresses/csa-user-stories.md
similarity index 100%
rename from docs/csa-user-stories.md
rename to docs/addresses/csa-user-stories.md
diff --git a/docs/interoperable-address-explainer.md b/docs/addresses/interoperable-address-explainer.md
similarity index 96%
rename from docs/interoperable-address-explainer.md
rename to docs/addresses/interoperable-address-explainer.md
index 333eb67..a44f196 100644
--- a/docs/interoperable-address-explainer.md
+++ b/docs/addresses/interoperable-address-explainer.md
@@ -1,6 +1,8 @@
Introducing: Interoperable Addresses
====
+*Specs in the formal format are written [here](/specs/addresses/cross-chain-interoperable-addresses-spec.md)*.
+
Interoperable Addresses is a standard defining address formats for a multi-chain world.
For a normal user, they look like this:
diff --git a/docs/asset-types.md b/docs/assets/asset-types.md
similarity index 100%
rename from docs/asset-types.md
rename to docs/assets/asset-types.md
diff --git a/docs/atomic-swaps.md b/docs/intents/atomic-swaps.md
similarity index 100%
rename from docs/atomic-swaps.md
rename to docs/intents/atomic-swaps.md
diff --git a/docs/intent-types.md b/docs/intents/intent-types.md
similarity index 100%
rename from docs/intent-types.md
rename to docs/intents/intent-types.md
diff --git a/docs/messaging-comparisons.md b/docs/message-passing/messaging-current-efforts.md
similarity index 100%
rename from docs/messaging-comparisons.md
rename to docs/message-passing/messaging-current-efforts.md
diff --git a/specs/README.md b/specs/README.md
index d142918..dca3c6e 100644
--- a/specs/README.md
+++ b/specs/README.md
@@ -1,12 +1,13 @@
# Specifications Index
-## Addresses (& chains)
-- [Address Types](address-types.md)
+## Addresses
+
+- [Cross-Chain Interoperable Addresses](addresses/cross-chain-interoperable-addresses-spec.md)
## Assets
- [Asset Types](asset-types.md)
-## Messaging
+## Message Passing
- [Message Types](message-types.md)
## Intents
diff --git a/specs/address-types.md b/specs/addresses/cross-chain-interoperable-addresses-spec.md
similarity index 100%
rename from specs/address-types.md
rename to specs/addresses/cross-chain-interoperable-addresses-spec.md
From 751aac8a0670a01e564871cd8086ce6de796ee2f Mon Sep 17 00:00:00 2001
From: Joxes <91908708+Joxess@users.noreply.github.com>
Date: Wed, 19 Mar 2025 10:57:19 -0300
Subject: [PATCH 10/14] fix: add binary representation requirement and remove
chain hierarchies (#31)
---
PROPERTIES.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/PROPERTIES.md b/PROPERTIES.md
index f80af44..f5df6fd 100644
--- a/PROPERTIES.md
+++ b/PROPERTIES.md
@@ -36,13 +36,13 @@ The following properties outline the requirements for solutions in both spaces.
3. **Implementation Requirements**
- Deterministic resolution from chain identifier + address
+- Guarantee there is a binary representation that can be passed, stored, and decoded unambiguously in smart contract environments
- Clear error handling for invalid identifiers
- Support for checksums and pre-validations
### Should-have
1. **Extensibility**
-- Support for chain hierarchies (L1/L2/L3)
- Support for future chain types and formats
- Flexibility in implementation details
From 4be67190f51699e14009c21ad3c0b65b98bd2cf5 Mon Sep 17 00:00:00 2001
From: 0xRaccoon <112493530+0xRaccoon@users.noreply.github.com>
Date: Wed, 19 Mar 2025 18:27:38 -0300
Subject: [PATCH 11/14] fix: general polish and fixes (#33)
* fix: general polish and fixes
Signed-off-by: 0xRaccoon
* fix: update PROPERTIES.md
Co-authored-by: Joxes <91908708+Joxess@users.noreply.github.com>
---------
Signed-off-by: 0xRaccoon
Co-authored-by: Joxes <91908708+Joxess@users.noreply.github.com>
---
NOMENCLATURE.md | 14 ++--
PROPERTIES.md | 66 +++++++++----------
docs/addresses/csa-current-efforts.md | 10 +--
docs/addresses/csa-user-stories.md | 47 +++++++------
.../interoperable-address-explainer.md | 40 +++++------
docs/assets/asset-types.md | 6 +-
docs/intents/atomic-swaps.md | 18 ++---
docs/intents/intent-types.md | 4 +-
.../messaging-current-efforts.md | 2 +-
docs/shared-bridges.md | 2 +-
10 files changed, 104 insertions(+), 105 deletions(-)
diff --git a/NOMENCLATURE.md b/NOMENCLATURE.md
index 19d0b64..2954389 100644
--- a/NOMENCLATURE.md
+++ b/NOMENCLATURE.md
@@ -39,14 +39,14 @@ This document defines the common terminology and conventions to be used across a
## Messaging
- **Message**: Information transmitted between chains.
- - **`send`**: The act of marking information on the origin chain to be transmitted to another chain(s). Functions in existing implementations are tipically named as `sendMessage` or others.
+ - **`send`**: The act of marking information on the origin chain to be transmitted to another chain(s). Functions in existing implementations are typically named as `sendMessage` or others.
- **Aggregation**: Combining multiple cross-chain messages (possibly from multiple origin chains) to finalize them on the destination chain in a single transaction or proof.
- **`receive`**: Used to denote the act of receiving a message. Depending on the context, receiving a message may have its own flow or involve multiple steps. Functions in existing implementations are tipically named as `receiveMessage`, `relayMessage`, `validateMessage`, `executeMessage` or others.
- **`Metadata`**: Information about the message (sender, receiver, nonce, etc.)
- - **`ChainId`**: Referes the chain identifier. Existing implementations might refer to it as "domain" instead of "chain," or simply as the destination.
-- **`Payload`**: The actual data orinstructions being transmitted.
+ - **`ChainId`**: Refers to the chain identifier. Existing implementations might refer to it as "domain" instead of "chain," or simply as the destination.
+- **`Payload`**: The data or instructions being transmitted.
- **Verification**: The process of validating cross-chain messages.
-- **Push-based**: A full cross-chain transmission lifecycle (including destination execution) can be arranged by a transaction on the origin chain, typically relying on in-protocol methods or third-party relayers.
+- **Push-based**: A full cross-chain transmission lifecycle (including destination execution) can be arranged by a transaction on the origin chain, it typically relies on in-protocol methods or third-party relayers.
- **Pull-based**: Requires a user (or application) to complete the lifecycle on the destination chain (so-called “self-relaying”).
@@ -58,9 +58,9 @@ This document defines the common terminology and conventions to be used across a
## Updates:
This document should be updated when:
-1. New standards introduce novel concepts
-2. Existing terminology requires clarification
-3. Community feedback suggests improvements
+1. New standards introduce novel concepts.
+2. The existing terminology requires clarification.
+3. Community feedback suggests improvements.
## Acknowledgments
diff --git a/PROPERTIES.md b/PROPERTIES.md
index f5df6fd..be18638 100644
--- a/PROPERTIES.md
+++ b/PROPERTIES.md
@@ -2,15 +2,15 @@
This document outlines the required properties for existing interoperability tracks. For each one, properties are categorized as:
-- **Must-have**: Core requirements that any solution MUST implement
-- **Should-have**: Important features that solutions SHOULD implement
-- **Nice to have**: Optional features that improves the solution
-- **Non-Goals**: Explicitly out of scope
+- **Must-have**: Core requirements that any solution MUST implement.
+- **Should-have**: Important features that solutions SHOULD implement.
+- **Nice to have**: Optional features that improves the solution.
+- **Non-Goals**: Explicitly out of scope.
# Chain-Specific Addresses
L2s and interconnected chains complicate how we identify accounts and targets for transactions. This becomes clear when looking at common scenarios:
-* Same address on different chains representing completely different entities (or some of them do not "exist").
+* The same address on different chains may represent completely different entities, or in some cases, may not _exist_ at all.
* Different addresses across chains representing the same logical entity.
From the integration perspective, we can separate cross-chain identification into two distinct concerns:
@@ -27,70 +27,70 @@ The following properties outline the requirements for solutions in both spaces.
### Must-have
1. **Address Uniqueness**
-- Unique (and thus, canonical) identification of addresses per chain
-- Prevention of cross-chain ambiguity
+- Unique and therefore canonical identification of addresses per chain.
+- Prevention of cross-chain ambiguity.
2. **Format Compatibility**
-- Support for arbitrary "blockchain" address formats (not constrained to EVM)
-- Consistent encoding/decoding of its format
+- Support for arbitrary "blockchain" address formats not constrained to EVM.
+- Consistent encoding and decoding of its format.
3. **Implementation Requirements**
-- Deterministic resolution from chain identifier + address
-- Guarantee there is a binary representation that can be passed, stored, and decoded unambiguously in smart contract environments
-- Clear error handling for invalid identifiers
-- Support for checksums and pre-validations
+- Deterministic resolution from chain identifier + address.
+- Guarantee there is a binary representation that can be passed, stored, and decoded unambiguously in smart contract environments.
+- Clear error handling for invalid identifiers.
+- Support for checksums and pre-validations.
### Should-have
1. **Extensibility**
-- Support for future chain types and formats
-- Flexibility in implementation details
+- Support for future chain types and formats.
+- Flexible implementation details.
2. **Integration Support**
-- Alignment with existing standards (DIDs, CAIP-10)
+- Alignment with existing standards like DIDs and CAIP-10.
### Nice to Have
-- Resolution path using on-chain config registries
+- Resolution path using on-chain config registries.
### Non-Goals
-- Human readability as primary concern
-- Enforcing specific name resolution services
-- Standardizing chain identifiers (covered by other standards)
+- Human readability as primary concern.
+- Enforcing specific name resolution services.
+- Standardizing chain identifiers (covered by other standards).
## Cross-Chain Naming
### Must-have
1. **Name Resolution**
-- Deterministic resolution to cross-chain addresses
-- Support for hierarchical naming patterns
-- Clear chain identification within names
+- Deterministic resolution to cross-chain addresses.
+- Support for hierarchical naming patterns.
+- Clear chain identification within names.
2. **User Interface**
-- _Human_-readable format
-- Reasonable length for manual validation
-- Clear syntax for separating name and chain components
+- _Human_-readable format.
+- Reasonable length for manual validation.
+- Clear syntax for separating name and chain components.
3. **Wallet Implementation Requirements**
-- Trusted verification method (e.g. on-chain registry)
-- Safe handling of malformed or invalid names
+- Trusted verification method (e.g. on-chain registry).
+- Safe handling of malformed or invalid names.
### Should-have
1. **Integration Support**
-- Compatibility with name service resolution (ENS, etc.)
-- Alignment with identity standards (DIDs)
+- Compatibility with name service resolution such as ENS.
+- Alignment with identity standards like DIDs.
2. **Error Prevention**
-- Support for checksums at the name level
+- Support for checksums at the name level.
### Nice to have
-- Reliance path in on-chain config registries
+- Reliance path in on-chain config registries.
### Non-Goals
-- Enforcing specific name resolution services
+- Enforcing specific name resolution services.
## Message Passing
diff --git a/docs/addresses/csa-current-efforts.md b/docs/addresses/csa-current-efforts.md
index 8505857..e8ae713 100644
--- a/docs/addresses/csa-current-efforts.md
+++ b/docs/addresses/csa-current-efforts.md
@@ -1,6 +1,6 @@
# Chain-specific addresses
-A core challenge in Ethereum's multichain landscape is disambiguating addresses across L2s, L3s, Ln, and other EVM ecosystems. In this context, an address by itself does not provide enough information to determine which chain it belongs to and may even differ in its code content (in the case of smart contracts). For this reason, the introduction of chain identifiers and human-readable labels aims to simplify the cross-chain UX.
+A core challenge in Ethereum's multichain landscape is disambiguating addresses across L2s, L3s, Ln, and other EVM ecosystems. In this context, an address by itself does not provide enough information to determine which chain it belongs to, and in the case of smart contracts, its code content may even differ. For this reason, the introduction of chain identifiers and human-readable labels aims to simplify the cross-chain UX.
# Existing efforts
@@ -10,7 +10,7 @@ A core challenge in Ethereum's multichain landscape is disambiguating addresses
## CAIP-10: Account ID Specification
-[CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) is a chain-agnostic standard that defines a way to identify an account on any blockchain that accomplies with [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md) (e.g. `eip155:1:0xAbC...123` for Ethereum mainnet). It is not neccessarily intended to be human-friendly, but rather serves as an universal reference for multi-chain tooling (e.g. Wallet Connect).
+[CAIP-10](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md) is a chain-agnostic standard that defines a way to identify an account on any blockchain that accomplies with [CAIP-2](https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-2.md), such as `eip155:1:0xAbC...123` for Ethereum mainnet. It is not neccessarily intended to be human-friendly, but rather serves as an universal reference for multi-chain tooling like Wallet Connect.
## ERC-7828: Chain-specific Addresses using ENS
@@ -18,7 +18,7 @@ A core challenge in Ethereum's multichain landscape is disambiguating addresses
## ENSIP-9: Multichain Address Resolution
-[ENSIP-9](https://github.com/ensdomains/ensips/blob/master/ensips/9.md) introduces a unified way for ENS resolvers to store and return addresses for different blockchains by overloading the `addr` function. Rather than proposing a textual format like `chain:address`, ENSIP-9 leverage from coin types (following [SLIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md)). This allows resolvers to identify each blockchain by its unique coin type and store the address in its native binary form (such as 20-byte hex for Ethereum, base58-decoded bytes for Bitcoin, etc).
+[ENSIP-9](https://github.com/ensdomains/ensips/blob/master/ensips/9.md) introduces a unified way for ENS resolvers to store and return addresses for different blockchains by overloading the `addr` function. Rather than proposing a textual format like `chain:address`, ENSIP-9 leverage from coin types following [SLIP-0044](https://github.com/satoshilabs/slips/blob/master/slip-0044.md). This allows resolvers to identify each blockchain by its unique coin type and store the address in its native binary form such as 20-byte hex for Ethereum, base58-decoded bytes for Bitcoin.
### ENSIP-11: EVM compatible Chain Address Resolution
@@ -26,11 +26,11 @@ A core challenge in Ethereum's multichain landscape is disambiguating addresses
## Comparison
-The existing approaches to chain-specific addresses represent an evolution in thinking about cross-chain identification rather than competing solutions. Some standards builds upon lessons learned from previous implementations while other targets other aspects or they could built on top of.
+The existing approaches to chain-specific addresses represent an evolution in thinking about cross-chain identification rather than competing solutions. Some standards build upon lessons learned from previous implementations, while other target other aspects or build on top of them.
| **Feature** | ERC-3770 | CAIP-10 | ERC-7828 | ENSIP-9/ENSIP-11 |
| --- | --- | --- | --- | --- |
-| **Scope** | Primarily a UI/UX layer standard for human-readable prefixes | A universal account identifier format (machine-readable) for all blockchains | On-chain naming integration with ENS (for chain names and addresses), EVM-focused | ENS resolver-level standards for storing/retrieving multi-chain addresses |
+| **Scope** | Primarily a UI/UX layer standard for human-readable prefixes | A universal account identifier format (machine-readable) for all blockchains | On-chain naming integration with ENS for chain names and addresses, EVM-focused | ENS resolver-level standards for storing/retrieving multi-chain addresses |
| **Status** | Draft (Fully defined) | Final (Fully defined) | Draft (Incomplete) | Final/Draft |
| **Format Example** | `chain:address` | `chain_namespace:chain_reference:address` | `address:chain.eth` or `address@chain.eth` | Still uses typical `.eth` format |
| **Human Readability (_best-case scenario_)** | Medium | Medium | High | High (from typical ENS format) |
diff --git a/docs/addresses/csa-user-stories.md b/docs/addresses/csa-user-stories.md
index 0c85171..81d9570 100644
--- a/docs/addresses/csa-user-stories.md
+++ b/docs/addresses/csa-user-stories.md
@@ -17,7 +17,7 @@ I want to send asset to any address, regardless of which chain it is on.
> 📌
> **Acceptance Criteria:**
> - Wallet detects and shows the destination chain when address is provided.
-> - Error prevention if sending to a non-existent account (e.g. non-registered address given a name).
+> - Error prevention when sending to a non-existent account, like an unregistered address assigned to a name.
> - The chain-specific address should be clearly visualized.
> - Clear separation between source and destination chain.
> - Optional: Transfer method and costs are shown afterwards (Intents/Bridges).
@@ -26,16 +26,16 @@ I want to send asset to any address, regardless of which chain it is on.
**As an end-user**:
-I want to send assets using a human-readable Name.
+I want to send assets using a human-readable name.
**Rationale**: I want to avoid dealing with raw addresses.
> 📌
> **Acceptance Criteria:**
-> - The Human-Readable name to chain-specific addresses conversion is unambiguous; the wallet must display the checksum for safety.
+> - The human-readable name to chain-specific addresses conversion is unambiguous; the wallet must display the checksum for safety.
> - Validates the existence of resolved addresses.
> - Chain information is shown.
-> - Optional: shows full-resolved machine address.
+> - Optional: shows the full-resolved machine address.
### US3: Send Asset Error Prevention
@@ -43,20 +43,20 @@ I want to send assets using a human-readable Name.
I want to be warned if I’m sending to potentially inexistent chain or address.
-**Rationale**: I can avoid losing funds.
+**Rationale**: I want to avoid losing funds.
> 📌
> **Acceptance Criteria:**
> - All US2 acceptance criteria apply here.
-> - If account is not found, warn about non-existent account.
-> - If chain is not found, warn about a non-existent destination chain.
-> - Optional: If chain identifier is intuitively distinguishable (e.g. ENS domains or CAIP-2 chain identifier mispellings), suggest correction and let the user decide whether to continue.
+> - If the account is not found, warn about non-existent account.
+> - If the chain is not found, warn about a non-existent destination chain.
+> - Optional: If the chain identifier is intuitively distinguishable (e.g., ENS domains or CAIP-2 chain identifier misspellings), suggest a correction and let the user decide whether to continue.
### US4: Sharing a Cross-Chain Address
**As an end-user:**
-I want to share a complete, unambiguous machine address so that the recipient knows exactly which chain and address they are sending funds to.
+I want to share a complete, unambiguous machine address so the recipient knows exactly which chain and address they are sending funds to.
**Rationale**: I can receive funds, preventing losses.
@@ -64,38 +64,38 @@ I want to share a complete, unambiguous machine address so that the recipient kn
> **Acceptance Criteria:**
> - Cross-chain address should be deterministically resolved into raw address + chain identifier.
> - No ambiguity is allowed.
-> - Optional: US6 (see below) is triggered if chain is unknown.
+> - Optional: US6 (see below) is triggered if the chain is unknown.
### US5: Sharing a Name
**As an end-user:**
-I want to share a human-readable name that can be resolved to one (or more) cross-chain addresses so that it’s more user-friendly and still prevents accidental misrouting.
+I want to share a human-readable name that can be resolved to one (or more) cross-chain addresses making it more user-friendly while still preventing accidental misrouting.
-**Rationale**: Sharing a name is more conveniente than a raw address.
+**Rationale**: Sharing a name is more convenient than a raw address.
> 📌
> **Acceptance Criteria:**
> - The human-readable name must be deterministically resolved into at least one cross-chain address.
> - If a name corresponds to multiple cross-chain addresses, default to one or show options.
-> - Checksum should guard against accidental collisions.
+> - The checksum should prevent accidental collisions.
### US6: Support for Unknown Chains
**As an end-user**:
-I want to send assets to addresses on chains that my wallet hasn't explicitly integrated with.
+I want to send assets to addresses on chains that my wallet hasn't explicitly integrated.
-**Rationale**: I shouldn't be limited to only sending assets to chains that my wallet already knows about.
+**Rationale**: I shouldn't be limited to only sending assets to chains that my wallet recognizes.
> 📌
> **Acceptance Criteria:**
> - Validates the existence of the chain through a trusted provider (e.g. bridging service in the short term, and through an on-chain list of chain configs in the long term).
-> - Fetch chain config and confirms compatibility.
+> - Fetches the chain config and confirms compatibility.
> - Validates the existence of resolved addresses.
> - Shows confirmation with chain information.
-> - Clearly indicates this is a new/unknown chain to the user.
-> - Optional: Allows user to save chain for future use.
+> - Clearly indicates if it is a new/unknown chain to the user.
+> - Optional: Allows the user to save the chain for future use.
## Developer Stories
@@ -104,13 +104,12 @@ I want to send assets to addresses on chains that my wallet hasn't explicitly in
**As an wallet/dApp developer**:
-I want a straightforward API to parse a chain-specific address (e.g., "chain:0x123...") and validate its correctness,
-so that I can accept user inputs and avoid sending transactions to invalid or ambiguous destinations.
+I want a simple API to parse a chain-specific address (e.g., 'chain:0x123...') and validate it, so I can accept user input while preventing transactions to invalid or ambiguous destinations.
-**Rationale**: I can reduce the risk of ambiguity and then error.
+**Rationale**: I want to reduce the risk of ambiguity and errors.
> 📌
> **Acceptance Criteria:**
-> - There is libraries that accepts a chain-specific string and outputs a result (e.g., {`chainIdentifier`, `rawAddress`}, which are based in ehtereum-lists/chains, ERC-7785 or others).
-> - Distinguishable for cases where the same address format is used (e.g. in the case of raw addresses in EVM)
-> - confirm chain identifiers against a known registry.
+> - Some libraries accept a chain-specific string and return a result like {`chainIdentifier`, `rawAddress`}, based on sources such as ethereum-lists/chains, ERC-7785, or others.
+> - Distinguishable in cases where the same address format is used, such as raw addresses in EVM.
+> - Verify chain identifiers against a known registry.
diff --git a/docs/addresses/interoperable-address-explainer.md b/docs/addresses/interoperable-address-explainer.md
index a44f196..5c89b85 100644
--- a/docs/addresses/interoperable-address-explainer.md
+++ b/docs/addresses/interoperable-address-explainer.md
@@ -1,9 +1,9 @@
Introducing: Interoperable Addresses
====
-*Specs in the formal format are written [here](/specs/addresses/cross-chain-interoperable-addresses-spec.md)*.
+*Formal format specifications are written [here](/specs/addresses/cross-chain-interoperable-addresses-spec.md)*.
-Interoperable Addresses is a standard defining address formats for a multi-chain world.
+Interoperable Addresses is a standard that defines address formats for a multi-chain world.
For a normal user, they look like this:
@@ -13,10 +13,10 @@ For a normal user, they look like this:
-- 3::
: the Interoperable Address Resolver version, which your wallet may very well omit.
-- vitalik.eth
: A human-readable name, specific to a chain. Supported by (anything looking like) ENS.
-- eth
: A human-readable chain name, defined by either https://github.com/ethereum-lists/chains if available (same registry for ERC-3770) or CAIP-2 in all other cases.
-- 5966be0f
: A checksum so you can at a glance validate what you see matches what you expect to be under the hood.
+- 3::
: the Interoperable Address Resolver version, which the wallet may omit.
+- vitalik.eth
: A human-readable name specific to a chain, supported by systems similar to ENS.
+- eth
: A human-readable chain name, defined by https://github.com/ethereum-lists/chains if available (same registry as ERC-3770), or by CAIP-2 in all other cases.
+- 5966be0f
: A checksum that allows quick validation that what is displayed matches what is expected.
---
@@ -29,26 +29,26 @@ For nerds and computers, however, they look like this:
- 3:
: Interoperable Address version.
-- eip155:1
: CAIP-2 id of chain where the naming registry is located
-- 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
: Address where to find the naming registry
-- eip155:1
: CAIP-2 id of chain we are referring to
-- 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
: Chain-specific address we are targeting in that chain
-- 5966be0f
: Checksum of all previous fields, to make sure nothing got lost in transit
+- eip155:1
: CAIP-2 ID of the chain where the naming registry is located.
+- 0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e
: Address of the naming registry.
+- eip155:1
: CAIP-2 ID of the chain.
+- 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045
: Chain-specific address target.
+- 5966be0f
: Checksum of all previous fields to prevent any loss in transit.
---
The Interoperable Address is a format for strings to:
- Fully specify an address on a particular chain (using CAIP-10), supporting any EVM-ecosystem chain and any chain on SLIP-044.
-- Also include the information to display it to a human in a readable way, as displayed above.
+- Include information for displaying it in a human-readable format, as shown above.
Some of its features are:
-- Uses mature technologies such as CAIP-10 and ENS.
-- Is extensible for future resolving mechanisms (eg: ERC-7785, when/if it reaches production).
-- Resolution of Interoperable Addresses to human readable names is fully deterministic.
-- Edge cases are securely abstractable to a library/SDK for wallets.
-- Does not enshrine a particular ENS contract, making it flexible for a future naming-only rollup, instances on other rollups or even an ENS fork.
+- It uses mature technologies such as CAIP-10 and ENS.
+- It is extensible for future resolving mechanisms (eg: ERC-7785, when/if it reaches production).
+- The resolution of Interoperable Addresses to human readable names is fully deterministic.
+- The edge cases can be securely abstracted into a library/SDK for wallets.
+- It does not enshrine a specific ENS contract, allowing flexibility for future naming-only rollups, deployments on other rollups, or even an ENS fork.
And, in all honesty, it has some drawbacks as well:
-- Exposes a version number to users (although that can be mitigated by wallet UX)
-- Supporting different name resolution contracts mean human-readable name -> machine address resolution can produce different results (which is mitigated by the checksum)
-- Wallets will have to maintain a set of name resolving contracts considered trustworthy, with a trust model similar to RPC urls (can be taken care of by a library/SDK, but user overrides should be supported).
+- It exposes a version number to users, though this can be mitigated through wallet UX.
+- Supporting different name resolution contracts means that resolving a human-readable name to a machine address may produce different results. However, this is mitigated by the checksum.
+- Wallets must maintain a set of trusted name-resolving contracts, using a trust model similar to RPC URLs. This can be handled by a library/SDK, but users should be able to override it.
diff --git a/docs/assets/asset-types.md b/docs/assets/asset-types.md
index a11d420..cb757e1 100644
--- a/docs/assets/asset-types.md
+++ b/docs/assets/asset-types.md
@@ -2,9 +2,9 @@
Ethereum has a long history of enabling the creation of interchangeable assets, most of which follow an ERC standard. Typically, asset creation converge into one of these three well-established standards:
-- [ERC-20](https://eips.ethereum.org/EIPS/eip-20): The most widely used standard for fungible tokens, defininf a set of functions that enable transfers, approvals and balance tracking.
+- [ERC-20](https://eips.ethereum.org/EIPS/eip-20): The most widely used standard for fungible tokens, defining a set of functions that enable transfers, approvals and balance tracking.
- [ERC-721](https://eips.ethereum.org/EIPS/eip-721): The standard for non-fungible tokens, ensuring uniqueness and ownership tracking.
-- [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155): A multi-token standard that supports both fungible and non-fungible tokens winthin a single contract, optimizing batch transgers and reducing gas costs.
+- [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155): A multi-token standard that supports both fungible and non-fungible tokens within a single contract, optimizing batch transfers and reducing gas costs.
These standards define how an asset is structured, including its fundamental properties and fungibility rules. However, they do not specify how assets should function in a multi-chain environment. To address this, various standards and frameworks have been proposed over time.
@@ -49,7 +49,7 @@ Layer 2s and sidechains commonly implement canonical bridges, which generally op
## Others
-Other teams have chosen to implement fully independent token frameworks and bridging mechanisms. The most notable example is the Bridged USDC Standard and native USDC with CCTP.
+Other teams have chosen to implement fully independent token frameworks and bridging mechanisms. The most notable examples are the Bridged USDC Standard and native USDC transferred via CCTP.
# ERC-721-Compatible Standards and Frameworks
[WIP].
diff --git a/docs/intents/atomic-swaps.md b/docs/intents/atomic-swaps.md
index a0988b7..25a2437 100644
--- a/docs/intents/atomic-swaps.md
+++ b/docs/intents/atomic-swaps.md
@@ -1,6 +1,6 @@
# Atomic Swaps with Local Verification
-This proposal introduces a mechanism for achieving asset interoperability between Ethereum L2s (and beyond) using Atomic Swaps. The approach does not require a cross-chain messaging protocol, does not introduce new trust assumptions, and remains open and permissionless for any network to participate. It leverages an enhanced version of HTLCs (PreHTLC) in conjunction with recent advancements in local verification techniques, such as running a light client in the browser (e.g., Helios), to achieve two primary objectives:
+This proposal introduces a mechanism for achieving asset interoperability between Ethereum L2s and beyond using Atomic Swaps. The approach does not require a cross-chain messaging protocol, does not introduce new trust assumptions, and remains open and permissionless for any network to participate. It leverages an enhanced version of HTLCs (PreHTLC) in conjunction with recent advancements in local verification techniques, such as running a light client in the browser (e.g., Helios), to achieve two primary objectives:
- Trustless – Users should be able to transfer assets between chains without ever losing control of their funds.
- Permissionless – Networks should be able to join the protocol without approvals or gatekeepers.
@@ -9,9 +9,9 @@ This proposal introduces a mechanism for achieving asset interoperability betwee
PreHTLC introduces three key improvements over [traditional HTLCs](https://en.bitcoin.it/wiki/Hash_Time_Locked_Contracts):
-- Delegated secret management – The Solver is responsible for managing secrets, reducing operational complexity for users.
-- Multiple Solver selection – Users can designate multiple Solvers to fulfill the transaction, mitigating Solver liveness risks.
-- Incentive alignment – A reward/slash mechanism ensures that Solvers are economically incentivized to execute transactions promptly.
+- Delegated secret management – The solver is responsible for managing secrets, reducing operational complexity for users.
+- Multiple solver selection – Users can designate multiple solvers to fulfill the transaction, mitigating the solver liveness risks.
+- Incentive alignment – A reward/slash mechanism ensures that solvers are economically incentivized to execute transactions promptly.
This document does not exhaustively cover all [edge cases](https://docs.train.tech/protocol-spec/edge-cases) and [implementation details](https://docs.train.tech) but instead provides a high-level overview of the core process.
@@ -32,9 +32,9 @@ sequenceDiagram
P1->>SC: addLock(hashlock)
SC-->>P2: TokenLockAdded
P2->>SC: redeem(secret)
- SC-->>P1: User Funds Recieved
+ SC-->>P1: User Funds Received
P2->>DC: redeem(secret)
- DC-->>P2: Solver Funds Recieved
+ DC-->>P2: Solver Funds Received
```
The following outlines the end-to-end execution when Alice transfers 1 ETH from Starknet to Optimism.
@@ -42,13 +42,13 @@ The following outlines the end-to-end execution when Alice transfers 1 ETH from
### 1. Transaction initiation
- Alice accesses the Bridge dApp, connects her wallet, and selects the Starknet → Optimism transfer route.
-- The dApp queries the Solver Discovery contract to retrieve a list of available Solvers supporting the route.
+- The dApp queries the solver discovery contract to retrieve a list of available Solvers supporting the route.
- Alice submits a commit transaction on Starknet, locking 1 ETH and specifying the set of Solvers.
At this point, the locked funds are subject to one of two conditions:
- A `Hashlock` is added once the auction winner is determined.
-- If no Solver successfully acts on this transaction before the `Timelock` expires, Alice can reclaim her funds.
+- If no solver successfully acts on this transaction before the `Timelock` expires, Alice can reclaim her funds.
### 2. Solver selection via Auction
@@ -69,7 +69,7 @@ The security of the exchange relies on this step, where the dApp retrieves the `
The worst-case scenario occurs when all of the following happen simultaneously:
-- There is no Light Client for the destination network.
+- There is no light client for the destination network.
- Only a single RPC provider is available for that network.
- This single RPC provider is also the solver matched with the user.
diff --git a/docs/intents/intent-types.md b/docs/intents/intent-types.md
index 6598352..1b7ba27 100644
--- a/docs/intents/intent-types.md
+++ b/docs/intents/intent-types.md
@@ -10,7 +10,7 @@ Intents are also considered a proper solution to minimize the consequences of li
[ERC-7683](https://github.com/ethereum/ERCs/blob/master/ERCS/erc-7683.md) proposes a standard API for cross-chain value-transfer systems. A participant called a filler fulfills intents in the destination initiated by users and is paid out through a settlement system. Users are protected since their funds are escrowed in the origin chain and are released when the action is verified, commonly through a message passed and validated.
-A CrossChainOrder is initiated (gasless or not gasless) and is resolved even when partitioned into several "legs." Note that the standard does not impose an opinion on the validation mechanism used to verify when an intent is completed.
+A CrossChainOrder is initiated (gasless or not gasless) and is resolved even when partitioned into several "legs". Note that the standard does not impose an opinion on the validation mechanism used to verify when an intent is completed.
For a gasless cross-chain Flow:
@@ -60,7 +60,7 @@ sequenceDiagram
DestinationSettler->>DestinationSettler: Validates & finalizes fill
```
-This standard intentionally does not prescribe the specifics of final settlement logic or how cancellations (e.g., revoking an unfilled order) should be handled. Implementations may choose to use any cross-chain messaging system.
+This standard intentionally does not prescribe the specifics of final settlement logic or how cancellations like revoking an unfilled order should be handled. Implementations may choose to use any cross-chain messaging system.
## Intents with Atomic Swaps
diff --git a/docs/message-passing/messaging-current-efforts.md b/docs/message-passing/messaging-current-efforts.md
index 330f327..6e9c699 100644
--- a/docs/message-passing/messaging-current-efforts.md
+++ b/docs/message-passing/messaging-current-efforts.md
@@ -32,7 +32,7 @@ sequenceDiagram
## ERC-7786: Cross-Chain Messaging Gateway
-[ERC-7786](https://github.com/ethereum/ERCs/pull/673) also proposes a minimal interface to send (`sendMessage`) and receive (`executeMessage`) arbitrary messages. It containts extensible attributes that can be adapted to multiple bridging protocol models, as it is intented to be proof-agnostic. It leverages CAIP-10 for sender/receiver addresses, and introduces an optional post-proccessing step for any custom logic, as well as a explicit definitions of roles for sending and executing messages.
+[ERC-7786](https://github.com/ethereum/ERCs/pull/673) also proposes a minimal interface to send (`sendMessage`) and receive (`executeMessage`) arbitrary messages. It contains extensible attributes that can be adapted to multiple bridging protocol models, as it is intented to be proof-agnostic. It leverages CAIP-10 for sender/receiver addresses, and introduces an optional post-proccessing step for any custom logic, as well as a explicit definitions of roles for sending and executing messages.
```mermaid
---
diff --git a/docs/shared-bridges.md b/docs/shared-bridges.md
index adfb4c7..c287e80 100644
--- a/docs/shared-bridges.md
+++ b/docs/shared-bridges.md
@@ -2,7 +2,7 @@
There have been ideas for sharing liquidity between multiple Layer 2s by utilizing common L1 escrow contracts, enabling assets to move freely across different chains. The primary objectives are:
1. Provide transfers for assets between rollup domains without requiring independent settlement transactions for each cross-chain transaction.
-2. Ensuring withdrawal guarantees across all participating chains.
+2. Ensure withdrawal guarantees across all participating chains.
3. Use of standardized bridge and asset contracts to maintain consistency (nice to have).
Shared bridges may anchor to the existing rollup contracts or operate a minimal infrastructure that rollups rely on. In any case, shared bridges may require trust in the state transitions of each chain or integrate the entire infrastructure into a common proof system.
From a62e02b6e389a8277f72758a7e8502ddf4263ea3 Mon Sep 17 00:00:00 2001
From: teddy
Date: Mon, 24 Mar 2025 14:44:25 -0300
Subject: [PATCH 12/14] feat: rewrite interoperable addresses as a binary
representation (#30)
* feat: rewrite as binary address POC
* fix: cant index compact format over words
* feat: go for shortest representation
* feat: Standard Long Format
* fix: small clarifications
* chore: fix links
* feat: 0xC000 address version
* fix: wording and definitions
* chore: ordering
* feat: changes proposed when preparing for show&tell
* feat: motivation section by joxes
* fix: suggestions by racu
* trivial examples for Appendix B
* feat: made up my mind on byte array encoding
---
...ross-chain-interoperable-addresses-spec.md | 542 +++++++++++++-----
1 file changed, 397 insertions(+), 145 deletions(-)
diff --git a/specs/addresses/cross-chain-interoperable-addresses-spec.md b/specs/addresses/cross-chain-interoperable-addresses-spec.md
index 3828beb..d44c65c 100644
--- a/specs/addresses/cross-chain-interoperable-addresses-spec.md
+++ b/specs/addresses/cross-chain-interoperable-addresses-spec.md
@@ -1,197 +1,449 @@
# Cross-chain interoperable addresses specification
This document, in its current state, aims to be the starting point for a future address format called 'Interoperable Address' whose aims & properties are fully described in [a separate document](../PROPERTIES.md)
-Requires: CAIP-10
+Requires: RFC-4648, ENSIP-11, CAIP-2
-## Abstract
-An extensible way to describe an address specific to one chain which includes the information to securely condense it into a human-readable name.
+# Abstract
+An extensible way to describe an address specific to one chain which also includes the information to securely condense it into a human-readable name.
-## Out of scope concerns
-Similarly to CAIP-10, this specification is not concerned with the mapping from a chain id to a network name, which might not be surjective (eg: the case where if there are multiple EIP-155 chains with chain id 8453, which one should we call Base?), regarding that resolution a social-layer problem until a future ERC decides to tackle it. Efforts in that front are tracked in [the chain registires document](../docs/chain-registries.md)
+# Motivation
+The Ethereum ecosystem is rapidly expanding into a multi-chain environment encompassing L1s, L2s, sidechains, and rollups—some EVM‐compatible, others not. A simple address alone no longer identifies which chain the address belongs to, creating ambiguity for wallets, dApps, and users. At the same time, human‐readable naming (e.g. ENS) is important for usability, but must be deterministically tied to the correct network.
-## Definitions
-Account id
-: A string which unambiguously corresponds to an address on a specific chain (EVM or not).
+Interoperable Addresses build on insights from previous iterations of ERC-7828 and related discussions, offering a unified format which combines:
+- Binding chain specificity (via explicit chain identifiers) to the raw address,
+- Support for human‐readable naming (through optional resolvers, e.g., ENS), and
+- Checksums for name collision mitigation.
+
+All without adding new trust assumptions beyond what wallets already apply. By bundling chain references, addresses, and optional resolver info into a canonical binary format, wallets can deterministically parse and display addresses, while users benefit from intuitive names.
+In short, this standard aims to:
+- Erase ambiguity by enshrining a deterministic link between chain and address.
+- Remain resolution‐agnostic, supporting various naming services and chain registries.
+- Permit multiple “version” specifications, ensuring future extensibility for different resolution schemes.
+- Provide a stable, machine‐readable binary representation digestible by smart contracts (e.g., via ABI).
+
+These goals make Interoperable Addresses future-proof and user-friendly, enabling trustless, cross-chain workflows in a multi-chain world. The format also seeks to align with existing standards (e.g., CAIP-2, CAIP-10) and embrace diversity of identifier formats.
+
+# Out of scope concerns
+Similarly to CAIP-10, this specification is not concerned with the mapping from a chain ID to a network name, which might not be surjective (eg: the case where if there are multiple EIP-155 chains with chain ID 8453, which one should we call Base?), regarding that resolution a social-layer problem until a future ERC decides to tackle it. Efforts in that front are tracked in [the chain registries document](../docs/chain-registries.md)
+
+# Definitions
+Interoperable Address
+: A binary payload which unambiguously identifies a target address and, optionally, a _resolver specification_ which, along with this (and potentially future) ERCs, allows conversion to a human-readable name without requiring further trust assumptions by wallet software.
Human-readable name
-: A shorter representation of an account id
+: A string representation of an interoperable address, meant to be used by humans.
-Interoperable address
-: A string which includes both an account id and a _resolver specification_ which, together with this (and potentially future) ERCs, allows conversion to a human-readable name in a way that requires no further trust assumptions than those the wallet software executing said conversion already operates under.
+Target address
+: The (address, chain ID) pair a particular Interoperable Address points to.
-## Machine address format definition
+Name-resolving contract
+: A contract responsible for converting addresses and/or chain IDs from a machine-readable format into parts of a human-readable name.
-### Syntax
+# Guarantees provided by the standard
+- Any Interoperable Address is trivially convertible to Interoperable Canonical Format, `0x8000`, making it a canonical representation for users who need to treat them opaquely.
+- Checksums are short enough to be compared by humans, and effectively identify a _target address_ independently of any extra data the address may contain.
+# Binary Format definition
+Word 0 Is the only word which will be common to all versions, and is defined as follows:
+```
+MSB LSB
+0xXXXXYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
+ ^^^^------------------------ 255-240 Interoperable Address version
+ ^^^^^^^^ --------------- 239-208 Checksum
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ \------------- 207-0 Reserved
+```
+
+No length restriction is placed on how many more words can an Interoperable Address span. Different versions of the standard can define uses for extra words and the 208 reserved bits.
+
+# Human-readable name format definition
+
+## Syntax
```bnf
- ::= ::#
- ::= :
- ::= [0-9]{1,4}
- ::= [-.%a-zA-Z0-9]* // same as CAIP-10 account address format
- ::= [0-9a-f]{8}
-```
-
-### Semantics
-- Similarly to CAIP-10, the resolver payload has `%` as a valid character to enable URL-escaping of arbitrary characters
- - The rules for wether to parse URL escaping in a resolver payload are specific to the resolver version
- - The rules for wether to parse URL escaping in a CAIP-10 account address are specific to its CAIP-2 chain namespace
-- To maintain the bijectivity of account ids and therefore interoperable addresses to on-chain addresses:
- - In CAIP-2 namespaces where there is a canonicalization scheme (such as EIP-55 in EIP-155 chains) it SHOULD be used.
- - In CAIP-2 namespaces where addresses have an *optional* checksum field, it MUST be omitted and the checksum defined in the standard be used without redundancy
- - In CAIP-2 namespaces where addresses are raw hexadecimal data without an EIP-55-equivalent capitalization scheme, the lowercase `a-f` characters MUST be used instead of uppercase ones.
- - In the case of EIP-155 chains, EIP-55 canonicalization MUST be used
-- The checksum MUST be the hexadecimal representation first four bytes of the keccak-256 hash of UTF-8 representation of the interoperable address from it's beginning up to and including the hash `#` character separating the checksum from the rest of the address.
-
-## Human-readable name format definition
-
-### Syntax
-```bnf
- ::= =
- ::= [0-9]{1,4}
- ::= [@-.%a-zA-Z0-9]*
+ ::= @#
+ ::= [-:_%a-zA-Z0-9]*
+ ::= [-:_a-zA-Z0-9]*
+ ::= [0-9A-F]{8}
```
## Rationale
-- In order to guarantee future resolvers don't share prefixes with existing resolvers in an ambiguous way, and therefore human-readable names are always mappable to a single machine address, this standard defines the human-readable names to start with the resolver version. (TODO: ideally we should be smarter about this and resolve it in a way that doesn't expose this implementation quirk to users)
-- Similarly to CAIP-10, arbitrary characters can be url-encoded.
+- Chain and account fields' syntax is deliberately chosen to be able to express CAIP-2 namespaces and CAIP-10 account IDs, with the caveat that no length restriction is placed, so chains with longer address formats or full 256-bit EVM chainids can be represented.
+- Similarly, the account field includes `%` as a valid character to allow for url-encoding of any other characters.
-## Resolver version definitions
+# Interoperable Address version definitions
-### `0` : No resolution
-This is used to indicate no resolution, with the human-readable name being equal to the machine address. The machine address MUST be shown in full.
+## `0x8000`: Interoperable Canonical Format: arbitrary length addresses, CAIP-10 compatible display format
-#### Examples:
-Machine address
-: `0:::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#6164da10`
+### Machine-address format
-Human-readable name
-: `0:::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#6164da10`
+#### First word
+No reserved bits are used. They MUST be set to zero, to ensure canonicity of addresses.
+```
+MSB LSB
+0x8000XXXXXXXX0000000000000000000000000000000000000000000000000000
+ ^^^^------------------------ 255-240 Interoperable Address version
+ ^^^^^^^^ --------------- 239-208 Checksum
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ \--------------- 207-0 Reserved
+```
-### `1` : No resolution, compact format
-This is used to indicate no resolution, but removing all redundant information that can be verified by the wallet. It is equivalent to the CAIP-10 account id, with the canonicalization caveat described above.
+#### Second field
+Serializes the chain ID as described in [Appendix A](#appendix-a-binary-encoding-of-caip-2-blockchain-id) and encodes it into a byte array as described in [Appendix C](#appendix-c-short-encoding-of-byte-arrays). It is a _field_ and not a _word_, since it may take up more than one word.
-#### Examples:
-Machine address
-: `1:::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#b50c58f9`
+#### Third field
+Serializes the address as described in [Appendix A](#appendix-a-binary-encoding-of-caip-2-blockchain-id) and encodes it into a byte array as described in [Appendix C](#appendix-c-short-encoding-of-byte-arrays). It is a _field_ and not a _word_, since it may take up more than one word, and may not start at the third word boundary if the second field takes up more than one word.
-Human-readable name
-: `1::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045`
+### Human-readable name resolution
+The CAIP-2 namespace is to be rendered alongside the CAIP-10 formatted address and the checksum:
-### `2` : ERC-3770 chain name resolution only
-The human-readable name in this approach is consistent with the address format defined in ERC-3770, and similarly depends on the EF's mapping of chain ids to names maintained in github at: https://github.com/ethereum-lists/chains
+```
+@#
+```
-#### Human-readable name format
+### Examples
-```bnf
- ::= 2:::
+Human-readable name:
+`0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#6164DA10@eip155:1#618ad0d1`:
+
+First word:
+```
+MSB LSB
+0x80006164DA100000000000000000000000000000000000000000000000000000
+ ^^^^------------------------ 255-240 Interoperable Address version
+ ^^^^^^^^ --------------- 239-208 Checksum
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ \--------------- 207-0 Not used
```
-Since wallet software can always validate the checksum, it MUST be removed.
-EIP-55 or applicable scheme is used for canonicalization only.
+Second word (second field):
+```
+MSB LSB
+0x0100000000000000000000000000000000000000000000000000000000000002
+ ^^----------------------------------------------------------------- 255-249 bytes array payload
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- 9-249 padding
+ ^^ -- 0-8 2*1 (payload length)
+```
-#### Examples:
+Third word (third field):
+```
+MSB LSB
+0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045000000000000000000000028
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------------- 255-97 bytes array payload
+ ^^^^^^^^^^^^^^^^^^^^^^ ---- 9-96 padding
+ ^^ -- 0-8 2*20 (payload length)
+```
-Machine address
-: `2:::eip155:1:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#bc797def`
+TODO: example with multi-word fields
-Human-readable name
-: `2::eth:0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045`
+## `0xC000`: Interoperable Canonical Format With Resolver Info: arbitrary length addresses, arbitrary length name-resolving contract specification
-### `3` : ENSIP-11 + ENSIP-19 for raw address resolution + ethereum-lists chain name resolution
-This resolver relies on the centralized [SLIP44](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) list for ENS standards compliance and on the one used by ERC-3770 to define the short chain names.
+### Machine-address format
-The machine address, in turn, specifies what will the source of truth be for the `raw address -> ens-like name` mapping, expecting it to conform to ENSIP-11.
+#### First word
+Uses reserved bits as a registry of interfaces the provided resolver conforms to.
+```
+MSB LSB
+0xC000XXXXXXXX0000000000000000000000000000000000000000000000000000
+ ^^^^------------------------ 255-240 Interoperable Address version
+ ^^^^^^^^ --------------- 239-208 Checksum
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ \--------------- 207-0 Resolver Interface Key
+```
+The Resolver Interface Key defines how wallets should interact with the smart contract responsible for assigning names to addresses.
+Said contract MAY also be responsible for naming the chain on which the target address resides as well as providing a human-readable name for the address, when ERC-7785 or similar standards reach production.
-The chain/contract on which the ENSIP-11 contract used to resolve the human-readable name resides is abstracted away from the user, but implementing wallets MUST maintain a list of those considered trustworthy and warn the user or choose to display the machine address in full when the contract it instructs to use is outside the set.
+#### Second field
+Serializes the chain ID of the target address as described in [Appendix A](#appendix-a-binary-encoding-of-caip-2-blockchain-id) and encodes it into a byte array as described in [Appendix C](#appendix-c-short-encoding-of-byte-arrays).
-Also, wallets MAY have a default registry they use for converting human-readable names into machine addresses. This means different wallets could potentially resolve the same human-readable name to different machine addresses which potentially also map to different raw addresses. This should be mitigated by wallets' choices of valid and default registries.
+#### Third field
+Serializes the address of the target address as described in [Appendix A](#appendix-a-binary-encoding-of-caip-2-blockchain-id) and encodes it into a byte array as described in [Appendix C](#appendix-c-short-encoding-of-byte-arrays).
-#### Human-readable name format
+#### Fourth field
+Serializes the chain ID where the name-resolving contract is located as described in [Appendix A](#appendix-a-binary-encoding-of-caip-2-blockchain-id) and encodes it into a byte array as described in [Appendix C](#appendix-c-short-encoding-of-byte-arrays).
-```bnf
- ::= 3::@#
- ::= |
+#### Fifth field
+Serializes the address of the name-resolving contract as described in [Appendix A](#appendix-a-binary-encoding-of-caip-2-blockchain-id) and encodes it into a byte array as described in [Appendix C](#appendix-c-short-encoding-of-byte-arrays).
+
+### Human-readable name resolution
+Specific to every Resolver Interface Key
+
+### Resolver Interface Keys
+
+#### `0x0000000000000000000000000000000000000000000000000000`
+Responsibility over discovering the interface of the naming smart contract is delegated to the contract itself, via mechanisms comparable to `ERC165`, out of scope for this definition.
+
+#### `0x0000000000000000000000000000000000000000000000000001`
+Naming contract is expected to conform to ENSIP-11, and used to display the address. ENSIP-11 does not name chains, so the CAIP-2 name should be used instead.
+
+### Examples
+
+Human-readable name:
+`vitalik.eth@eip155:1#618AD0D1`:
+
+First word: metadata
+```
+MSB LSB
+0xC0006164DA100000000000000000000000000000000000000000000000000001
+ ^^^^------------------------ 255-240 Interoperable Address version
+ ^^^^^^^^ --------------- 239-208 Checksum
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ \--------------- 207-0 Resolver Interface Key
```
-#### Machine-address format
+Second word (second field): target address' chain ID
+```
+MSB LSB
+0x000001000000000000000000000000000000000000000000000000000000000C
+ ^^^^^^------------------------------------------------------------- 255-208 bytes array payload
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- 9-207 padding
+ ^^ -- 0-8 2*6 (payload length)
+```
-```bnf
- ::= 3:::#
-```
-
-#### `machine address -> human-readable name` resolution
-1. Extract CAIP-2 `chainId` and raw address from ``.
- - Failure mode: wallet can't call the contract (eg: does not have access to an rpc of that chain)
- - Failure mode: `chainId` is not an EVM address
-2. Look up in wallet's 'trusted registry' set (which MAY be locally updated by the user) and see if the contract is contained in it. If it is not, issue a warning to the user.
-3. Extract `chainId` and raw address from ``.
-4. Convert `chainId` from step above into ENSIP-11 `coinType`
-5. Compute the namehash for the ENSIP-19 reverse resolution from the results of step 3 and 4
- - TODO: check if ambiguities or other edge cases are possible when converting from CAIP-10 into the raw form required by ENSIP-11
-6. Call `resolver(bytes32 node)`on the contract obtained in step 1, using the value from the step above for `node`.
-7. Call `name(bytes32 node)` on the contract returned by the step above. Save the response as the ``.
-8. Check direct resolution of name obtained in the step above, and fail the resolution if it does not match, as described in ENSIP-19
-9. For the ``, extract the CAIP-2 chain id from ``. If said chain has an entry in ethereum-lists, display its shortname. Otherwise, display the raw CAIP-2 chain id.
-10. Append the checksum from the machine address.
-
-#### `human-readable name -> machine address ` resolution
-1. Let the user input a destination chain name, and convert it to a CAIP-2 chainId.
-2. Convert the result from step 1 into an ENSIP-11 `coinType`.
-3. Let the user input a unicode string instead of the punycode-encoded name.
-4. Convert the string from step 3 into a punycode-encoded name.
-5. Compute the punycode-encoded name's namehash.
-6. Call `addr(namehash, coinType)` on the wallet's default resolver, with the values from steps 5 and 2 respectively.
- - If it returns the zero address, prompt the user to pick another trusted resolver where the name is defined.
- - Failure mode: name cant be resolved with trusted resolvers.
-7. Construct `` with the resolver used in the step above.
-8. Construct `` with the address returned in step 6 and the destination chain from step 1.
-9. The user should obviously not be prompted for the checksum, but it MUST be displayed somewhere in the wallet UI for the user to optionally validate with the receiver that they are using the same resolver.
-10. Wallets MAY choose to display the full machine address as well.
-
-#### Pre-validations
-- The CAIP-2 `chain_id` included within both CAIP-10 account ids can be mapped to a valid ENSIP-11 `coinType` which extends both ENSIP-9 and SLIP44
-
-#### Semantics
-- ENS uses [punycode](https://www.unicode.org/reports/tr46/) to encode non-ascii characters, which SHOULD be rendered by wallets. In cases where the wallet could infer the presence of non-ascii characters to be unlikely (eg: depending on locale), a warning MAY also be issued to the user.
-- `` is to be the fully qualified name, including the TLD.
-- For chains listed in `ethereum-lists/chains`, the short name MUST be used, taking precedence over the CAIP-2 chain id.
-
-#### Rationale
-This is proposed as a way to have functional human readable names with existing tooling and infrastructure, while being flexible in not enshrining a particular contract to allow for future changes on where & how names are resolved. Future developments in chain configs and name registries should improve upon it's decentralization characteristics and render it obsolete in the long-term.
-
-Since it's possible for users' wallets to use different name registries by default when computing a machine address from a human-readable name, the checksum for the machine address is provided as a layer of defense against losing funds either by mis-configuration or deliberate attacks taking advantage of the differences between the data contained in different naming registries.
-
-#### Examples:
+Third word (third field): target address
+```
+MSB LSB
+0xD8DA6BF26964AF9D7EED9E03E53415D37AA96045000000000000000000000028
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------------- 255-97 bytes array payload
+ ^^^^^^^^^^^^^^^^^^^^^^ ---- 9-96 padding
+ ^^ -- 0-8 2*20 (payload length)
+```
+
+Fourth word (fourth field): name resolving contract's chain ID
+```
+MSB LSB
+0x000001000000000000000000000000000000000000000000000000000000000C
+ ^^^^^^------------------------------------------------------------- 255-208 bytes array payload
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- 9-207 padding
+ ^^ -- 0-8 2*6 (payload length)
+```
+
+Fifth word (fifth field): name resolving contract's address
+```
+MSB LSB
+0x00000000000C2E074EC69A0DFB2997BA6C7D2E1E000000000000000000000028
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ------------------------- 255-97 bytes array payload
+ ^^^^^^^^^^^^^^^^^^^^^^ ---- 9-96 padding
+ ^^ -- 0-8 2*20 (payload length)
+```
+
+TODO: example with other ENSIP-11 contract
+
+### Security considerations
+- Wallets will have to maintain a list of Resolver Interface Keys they support, and which name-resolving contracts they consider trustworthy, and display addresses as described in `0x8000` when the provided name-resolving contract is not contained in the list. Said list MAY be updateable by the user.
+
+## `0x0000` : single-word 48-bit EVM chain IDs, no human-readable name resolution
+This encoding is meant to be the shortest possible way to encode most EVM addresses
+
+### Supported chains
+EVM chains with a chain ID shorter than 48 bits (which potentially rules out chain IDs chosen to comply with ERC-7785)
+
+### Machine-address format
+
+```
+MSB LSB
+0x0000000000000000000000000000000000000000000000000000000000000000
+ ^^^^------------------------ 255-240 Interoperable Address version
+ ^^^^^^^^ --------------- 239-208 Checksum
+ ^^^^^^^^^^^^
+ \------------- 207-160 Chain ID
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ \- 159-0 Address
+```
+
+`Interoperable Address version`
+: Always `0x0000`
+
+`Checksum`
+: Computed as described in [Appendix D](#appendix-d-checksum-computation)
+
+`ChainID`
+: `uint48` containing the chain ID for the target chain
+
+`Address`
+: Native EVM address
+
+### Human-readable name resolution
+The CAIP-2 namespace is to be rendered alongside the `0x`-prefixed EIP-55 address and the checksum
+```
+@#
+```
+
+### Examples:
Machine address
-: `3:eip155:1:0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e::eip155:10xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#5966be0f`
+:
+```
+MSB LSB
+0x0000618ad0d1000000000001D8DA6BF26964AF9D7EED9E03E53415D37AA96045
+ ^^^^------------------------ 255-240 Interoperable Address version
+ ^^^^^^^^ --------------- 239-208 Checksum
+ ^^^^^^^^^^^^
+ \------------- 207-160 chain ID
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ \- 159-0 Address
+```
Human-readable name
-: `3::vitalik.eth@eth`
+: `0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045#6164da10@eip155:1#618AD0D1`
-#### Security considerations
-- If the resolver lives in the destination/source chains, then securing a trustworthy RPC is already in scope of the wallet's responsibilities to operate safely
-- If the resolver lives in L1 or a name-specific rollup, then presumably it's feasible to run a light client of said network as part of the infrastructure trusted by the wallet
+## `0x0001` : Compact format, ENSIP-11+ERC-3770 name resolution
+The binary representation is identical to the format above, with the exception that the version number is different, indicating the intent for the chain to be displayed using the ERC-3770 shortname and the address to be displayed following mainnet's ENS deployment and ENSIP-11
-## Requirements for wallet software
-- When parsing the CAIP-10 `account_address` for a CAIP-2 chain namespace where URL-escaping or the `%` character is not part of valid addresses, finding URL-encoded data MUST be treated as an error.
-- Wallet software MUST perform all relevant pre-validations, including verifying the checksum, and report any errors to the user, for every defined resolver. Wallets MAY reject an interoperable address solely on the basis of these checks failing.
-- TODO: what to do when a machine address' resolver version is not supported by the wallet
- - option 1: show it as is -> easiest
- - option 2: convert it to resolver `1` -> guarantees not-that-bad-to-read address is shown to the user, might impose extra constraints on existing resolvers.
+### Supported chains
+Chain must be listed on ethereum-lists/chains on top of the restrictions of `0x0000`.
-## Recommendations for rollups
-TODO: probably coupled to ERC-7785, currently out of scope
+### Machine-address format
+Same as `0x0000`, with `0x0001` version
-## Rationale
-- URL-escaping of characters might be necessary for future resolvers
-- Checksum algorithm is independent of used resolution method to allow wallets to validate an interoperable address' checksum despite not being able to generate its human-readable name
-- Ideally we'd want the resolution method to be fully abstracted away from the user, but that might not be achievable in every case. The next best thing is to prefix every human-readable name with a string denoting which method to use, which prevents the user ever being prompted to choose different addresses based on the resolution method used for each, which would be a more confusing and riskier UX
+### Examples:
+Machine address
+:
+```
+MSB LSB
+0x0001618ad0d1000000000001D8DA6BF26964AF9D7EED9E03E53415D37AA96045
+ ^^^^------------------------ 255-240 Interoperable Address version
+ ^^^^^^^^ --------------- 239-208 Checksum
+ ^^^^^^^^^^^^
+ \------------- 207-160 chain ID
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ \- 159-0 Address
+```
+
+Human-readable name
+: `vitalik.eth@eth#618AD0D1`
+
+TODO: example on another chain
+
+# Restrictions for future versions
+- The Interoperable Address MUST include an address and specify the chain it belongs to, fully defining a target address. Any version that adds an indirection layer between payload data and these two fields would violate this restriction.
+- Interoperable Address versions MAY only be able to represent a subset of the CAIP-2 namespaces.
+- Interoperable Address versions MAY define extra fields containing information on how to display the addresses.
+- The most significant version bit is reserved to mean an address complies with the Interoperable Canonical Format, described in Interoperable Address version `0x8000`.
+- The second-most significant version bit is reserved to mean the payload includes information on how to display the address to users, but is not normative about how that information is to be encoded. An example of this is provided in Interoperable Address version `0xC000`.
+
+# Requirements for wallet software
+- Wallet software MUST perform all relevant pre-validations, including verifying the checksum, and report any errors to the user.
+- Wallets MAY reject an interoperable address solely on the basis of the checks above failing.
+
+# Encoding considerations
+- On-chain actors, such as smart contracts, MUST always receive and return the machine addresses as byte array.
+- On-chain actors, such as smart contracts, MAY only accept canonical `0x8000` address versions, with off-chain actors being responsible over converting them to said format.
+- Off-chain actors, such as wallets, MAY use the blockchain-native byte array representation, or, where practical MAY alternatively use base64 [^2] as defined in RFC-4648 to encode the former.
+- Users SHOULD NOT be shown the base64 or binary representations. Instead, they should be presented with the intended human-readable name or, in cases where that is not possible, wallet software MUST fall back to interpreting it as an Interoperable Address version `0x8000`.
+
+[^2]: Base64 was chosen since it is a more widely implemented standard than base58. Additionally, since machine addresses are not to be directly displayed to the user, the collision-avoidance reasons in favor of base58 do not apply
+
+# Appendix A: Binary encoding of CAIP-2 blockchain ID
+The first two bytes are the binary representation of CAIP-2 namespace (see table below), while the remaining bytes correspond to the CAIP-2 reference, whose encoding is namespace-specific and defined below.
+
+## CAIP-2 namespaces' binary representation table
+
+| Namespace | binary key |
+| --- | --- |
+| eip155 | `0x0000` |
+| bip122 | `0x0001` |
+
+### eip155
+The bare `chainid` encoded as a `uint` of the necessary amount of bytes will be used [^1]. This allows for most of existing EVM chain IDs to fit inside one EVM word.
+
+[^1]: This makes it possible to represent some chains using the full word as their chainid, which CAIP-2 does not support since the set of values representable with 32 `a-zA-Z0-9` characters has less than `type(uint256).max` elements. This is done in an effort to support chains whose ID is the output of `keccak256`, as proposed in ERC-7785.
-## Compatibility with other public-key sharing standards
+#### Examples
+Ethereum Mainnet: `0x000001` (1, encoded as uint8)
-### W3C DID
-TODO
+Optimism Mainnet: `0x00000A` (10, encoded as uint8)
-## Security considerations
+Ethereum Sepolia: `0x0000aa36a7` (11155111, encoded as uint24)
+### bip122
+The genesis/fork blockhash is to be stored raw, without encoding/decoding from/to base58btc, and without removing any leading zeroes:
+
+Note: CAIP-2 limits chain references to 32 characters, so converting to it will require truncating the reference, so converting _from_ CAIP-2 to this standard is potentially ambiguous (but converting from actual bip122 to this standard will never be).
+
+#### Examples
+Bitcoin Mainnet
+: `0x0001000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f`
+
+Litecoin
+: `0x000112a765e31ffd4059bada1e25190f6e98c99d9714d334efa41a195a7e7e04bfe2`
+
+# Appendix B: Binary encoding of addresses
+
+## eip155
+20 bytes of evm addresses trivially stored as the payload.
+
+### Examples
+`0xD8DA6BF26964AF9D7EED9E03E53415D37AA96045` -> `0xD8DA6BF26964AF9D7EED9E03E53415D37AA96045`
+
+## solana
+base-58 encoded public keys should be decoded and stored as a 32 byte payload
+
+### Examples
+
+`7S3P4HxJpyyigGzodYwHtCxZyUQe9JiBMHyRWXArAaKv` -> `0x5F90554BB3D8C2FC82B6EE59C49AAA143E77F7D49A83E956CE1DBEF17A43F805`
+
+`DYw8jCTfwHNRJhhmFcbXvVDTqWMEVFBX6ZKUmG5CNSKK` -> `0xBA7A74F374AB05B70D114A78112EF0D3F0695A819572C79710B5372000D81AE2`
+
+# Appendix C: Short-encoding of byte arrays
+This is a mix between [how bytes and strings are saved into storage](https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html#bytes-and-string) and how ABI encoding works
+
+This arises out of:
+- The need for the shortest possible representation of EVM addresses.
+- The absence of a canonical place to delimit the _start_ of the data (in the case of storage strings, this is the keccak256 hash of the storage slot index).
+
+If the data is at most 31 bytes long, the elements are stored in the higher-order bytes (left-aligned) and the lowest-order byte stores the value `length * 2`.
+
+If the data is 32 bytes or longer, the current word stores `length * 2 + 1`, and data follows in the next words, left-aligned and zero-padded.
+
+This means access to an arbitrary field in the structure requires a worst-case linear amount of reads. Future encodings using it should take it into consideration to put less-frequently-accessed members last.
+
+## Examples
+
+`0x1234`: `0x1234000000000000000000000000000000000000000000000000000000000005`
+
+`0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1234`: `0x01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF12343E`
+
+`0x00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF`:
+```
+0x
+0000000000000000000000000000000000000000000000000000000000000041
+00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF
+```
+
+`0x00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF0011`:
+```
+0x
+0000000000000000000000000000000000000000000000000000000000000045
+00112233445566778899AABBCCDDEEFF00112233445566778899AABBCCDDEEFF
+0011000000000000000000000000000000000000000000000000000000000000
+```
+
+## Rationale
+With this approach, packing the data right after the word saving its length instead of storing the offset to the data, we don't allow for extra information to be inserted in a way that is not visible to parsers (as is possible with ABI encoding), which allows for the canonicity of encoded addresses.
+
+# Appendix D: checksum computation
+With the intent of:
+- Maximizing the difficulty of mining checksum collisions
+- Maximize the safety a user gets from knowing the checksum matches
+- Allow maximum flexibility for human-readable names, leveraging the above to make human-readable name collisions permissible.
+
+And considering:
+- Binary payloads will often have their own error-correction mechanisms when in transit (eg: if encoded into a QR code, said QR code will have information redundancy & its own checksum ensuring only valid data can be decoded), so that can safely be deemed out of scope.
+TODO: Considering the above, does it make sense to store the checksum inside the address?
+
+We propose a way to serialize the 'abstract' components of an address, ignoring the information on how it should be displayed, to achieve the above:
+
+```solidity
+ function getChecksum(bytes2 caip2Namespace, bytes memory chainId, bytes memory address_)
+ internal
+ view
+ returns (bytes4 checksum)
+ {
+ bytes memory fullChainId = bytes.concat(caip2Namespace, chainId);
+ // Deliberately abi-encode instead of encode-packed to avoid preimage collisions
+ bytes memory serialized = abi.encode(fullChainId, address_);
+ bytes32 hashed = keccak256(serialized);
+ checksum = bytes4(hashed);
+ }
+```
+TODO: describe this in a way which is not potentially coupled to solidity (or even a specific version of it)
From 8956268d898f78789de2a2316f435bf291dc0059 Mon Sep 17 00:00:00 2001
From: elliedavidson <118024407+elliedavidson@users.noreply.github.com>
Date: Thu, 3 Apr 2025 21:30:58 -0400
Subject: [PATCH 13/14] finally update this PR with all that's happened
---
PROPERTIES.md | 37 +++++++++-
.../message-passing-working-group.md | 72 +++++++++++++++++++
2 files changed, 108 insertions(+), 1 deletion(-)
create mode 100644 docs/message-passing/message-passing-working-group.md
diff --git a/PROPERTIES.md b/PROPERTIES.md
index be18638..5a47b0d 100644
--- a/PROPERTIES.md
+++ b/PROPERTIES.md
@@ -94,7 +94,42 @@ The following properties outline the requirements for solutions in both spaces.
## Message Passing
-[To be added]
+### Must-have
+
+1. Safety - Assuming the mode of message verification is honest, a message is delivered at the destination iff it was sent at the source chain.
+
+2. Liveness - Assuming liveness and censorship-resistance of the source and destination chains, a sent message is eventually delivered at the destination chain.
+
+3. VM-Agnosticism - Assuming the VM allows arbitrary logic, the interface can be implemented on any VM. The interface works between many different VM implementations.
+* Balance this goal with goal 6; the interface shouldn't be overly complex in order to achieve VM-agnosticism.
+
+4. Proof-Agnosticism - The interface makes no assumption about how messages are proved to be valid. Many unique proof systems will be used in the underlying messaging protocols, and the interface works the same across all of them.
+
+5. Protocol-agnosticism - The interface makes no assumptions about how the underlying messaging protocol works.
+
+6. Optimized for most use cases - The interface optimizes to provide the best developer experience for bridging and cross-chain function calls across L2s, L3s, and Ethereum.
+* Supporting all use cases results in a more complex interface. This may lead developers to use wrapper contracts to simplify the interface or to not adopt the interface at all, defeating the purpose of the interface.
+* Edge cases can be handled by the messaging protocol itself. Some edge use cases may depend on the specific messaging protocol used.
+
+### Should-have
+
+1. Timely Delivery - Assuming liveness and censorship resistance of the source and destination chains, messages should arrive within a known, bounded time delay.
+
+2. Allows arbitrary data transfer - Interface allows applications to send arbitrary data between chains, vs. forcing cross chain messages to represent tokens exclusively.
+
+### Nice to Have
+
+1. L1 <-> L1 messaging - The interface should work to interoperate across L1s in the same way it interoperates within the Ethereum ecosystem. (This property is implied by the other properties).
+
+2. Gas abstraction - The interface should support the ability for users to pay gas on the destination chain from the source chain, since this is required in most use cases.
+
+### Non-Goals
+
+1. Message broadcasting - While the underlying protocols may implement a message broadcast mechanism, the interface does not need to optimize for this use case.
+
+2. Ordering - The interface does not enforce the order in which messages arrive.
+
+
## Cross-Chain Intents
diff --git a/docs/message-passing/message-passing-working-group.md b/docs/message-passing/message-passing-working-group.md
new file mode 100644
index 0000000..0df4454
--- /dev/null
+++ b/docs/message-passing/message-passing-working-group.md
@@ -0,0 +1,72 @@
+# Message Passing Working Group
+
+## Introduction
+
+Interoperability among chains requires data from the source chain to be made available to the destination chain. This is often described as passing messages between chains. Cross-chain communication protocols that handle passing these messages are **message-passing protocols**. A message-passing protocol defines how a messages is transmitted, routed, verified, etc. These protocols are the foundation for token bridging, cross-chain function calls, and more.
+
+There exist many message-passing protocols today. These protocols are deployed on different chains and each one has its own tradeoffs. Each protocol defines its own messaging interface for applications, and these interfaces are not compatible with each other, which restricts the interoperability they can provide.
+
+This group's focus is to evaluate a standard messaging interface so applications interact with each message-passing protocol in the same way.
+
+## Discussion Summaries
+
+### What is the value of creating a new standard vs. adopting an existing one?
+
+If our goal is maximum interoperability between chains in the most pragmatic way, then it could make sense to canonicalize an existing message-passing protocol's interface. Applications already using this protocol would automatically adopt the standard, and such an interface benefits from having time in production.
+
+The interface standard must be credibly neutral, meaning:
+* The interface can function without the support of any core developement team.
+* The interface does not favor any specific project.
+* The interface does not favor any particular ecosystem or L2.
+* Projects are naturally incentivized to adopt the interface.
+
+ Canonicalizing an existing message-passing protocol interface will not move us towards towards the goal of seemless interoperabilty between chains because existing messaging protocols realistically will not adopt the protocol of another project. And thus we will continue to have many different interfaces that fragment cross-chain applications. A new standard allows us to create a credibly neutral interface that doesn't favor any particular party.
+
+Secondly, while current interfaces are powerful, they are not necessarily the *right* interface for applications long term.
+
+### What is the value of a message passing interface standard?
+
+Unified, simple developer experience - A standard allows all applications to interact with messaging protocols in the same way. Many different messaging protocols will continue to exist, and applications may need to make use of multiple protocols to serve certain cross-chain routes. A standard interface allows applications to use whichever message protocol they need to without restructuring their contracts.
+
+No vendor lock-in - Since applications interact with all messaging protocols through the same interface, applications can easily switch which messaging protocols they use without major contract changes.
+
+### Why will applications adopt this standard?
+
+Adoption is always difficult with efforts like this. \ However, we still feel it is the best way forward to achieve long term interoperability. Furthermore, the group has prioritized creating adapter contracts for major message passing protocols to ease adoption.
+
+Adoption will take time.
+
+### Is a message passing interface standard the most impactful work this group can do?
+
+Interoperability solutions are needed now, and this standard doesn't have much benefit in the short term since it only gains benefit once a critical mass of applications adopt it.
+
+This is why the L2 Interop group overall is primarily focused on intents and cross-chain addresses, since those can provide end users benefit in the very near term. We recognize that this interface standard is not the highest priority of the group.
+
+### Is message passing the right abstraction for developers?
+
+There are several ways to model cross-chain communication: message passing, reading from another chain's state, etc. Ultimately all these abstractions represent the exact same idea, and message passing is the most common and intuitive abstraction for developers.
+
+### Why not standardize the entire message-passing protocol instead?
+
+There was discussion of standardizing an entire protocol, or at least standardizing the message verification mechanisms. This may be something to tackle in the future, but it is a contentious topic. We can provide more benefit right now by standardizing the interface first.
+
+### Group Tasks
+
+- [ ] Agree on the properties a messaging interface should have.
+- [x] Discuss the value of a new interface versus an existing one.
+- [x] Discuss whether an interface is the most beneficial work for the group to do.
+- [ ] Agree on a final standard.
+- [ ] Implement adapters for major messaging protocols.
+- [ ] Update ERC-7786 based on group discussions, if needed.
+
+## Open Discussions
+
+1. Should we allow a tx hash as unique id of a message? Current protocols today use this hash as an id, but it adds complexity to the interface since the tx hash is not known at runtime.
+
+## Resources
+
+* [Comparison with current efforts](docs/message-passing/messaging-current-efforts.md)
+
+## Help Wanted
+
+* Adding more detail to the [Comparison with current efforts](docs/message-passing/messaging-current-efforts.md) file.
From 49eb2e9da10ad3183e3a2c1bc978c9a311233999 Mon Sep 17 00:00:00 2001
From: elliedavidson <118024407+elliedavidson@users.noreply.github.com>
Date: Thu, 3 Apr 2025 21:37:23 -0400
Subject: [PATCH 14/14] Remove old file
---
docs/messaging-working-group.md | 156 --------------------------------
1 file changed, 156 deletions(-)
delete mode 100644 docs/messaging-working-group.md
diff --git a/docs/messaging-working-group.md b/docs/messaging-working-group.md
deleted file mode 100644
index 25631ac..0000000
--- a/docs/messaging-working-group.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# Message Passing Working Group
-
-## L2 Interop Overall Goal:
-A user can bridge assets between any two Lns within 3 slots or less of the slower chain.
-
-Things required to achieve this goal:
-* Message passing protocols to physically relay information from one chain to another. Different protocols have different tradeoffs and security properties, and different L2s may use different protocols.
-* Common, abstracted interface for devs to interact with messaging protocols. Devs should not have to worry about the underlying protocol to bridge between chains. Cross-chain applications should be able to be built on top of any messaging protocol that supports the interface. See [ERC-7841's](https://github.com/elliedavidson/ERCs/blob/d7c16c21f0a012ef391783322ae9b6f0eb0b56bc/ERCS/erc-7841.md) *Motivation* section for details about this goal.
-
-This working group focuses on the second point.
-
-## Current Working Group Status
-We are currently working on 3 tasks:
-
-1. Agreeing that such an interface is useful.
-2. Agreeing whether goal 1 listed below is in scope for this working group. We will iterate through each goal below until we reach rough consensus among core contributors.
-3. Identifying core contributors to move this consensus forward quickly. We will ask for feedback from the broader group periodically.
-4. Establishing commitments and timelines from core projects to implement the interface once it is finalized.
-
-### Timeline:
-* 2/17/2025: Core contibutors identified.
-* 2/24/2025: Agreement on goals has been reached among core contributors, broader group feedback welcome.
-* 3/2/2025: Agreement on properties of interface has been reached among core contributors, broader group feedback welcome.
-* 3/9/2025: Agreement on interface has been reached among all core contributors, broader group feedback welcome.
-* 3/16/2025: Publish updated or new ERC, reach out to devs explicitly to get feedback.
-* 3/30/2025: All changes to interface are finalized. Implementation begins
-
-
-## Goals:
-### 1. Interface supports only the most common use cases: bridging and cross-chain function calls. --> We'll start with 90% of uses cases, aiming to make those APIs simple, and then we can add more complex use cases from there.
-
-Reasoning:
-* Supporting all use cases results in a more complex interface. This may lead developers to use wrapper contracts to simplify the interface or to not adopt the interface at all, defeating the purpose of the interface.
-* Edge cases can be handled by the messaging protocol itself. Some edge use cases may depend on the specific messaging protocol used.
-
-#### 1a. Developers should not need to use wrapper contracts to interact with the interface.
-
-### 2. Interface should be VM-agnostic. --> Agree
-
-Reasoning:
-* Our goal is to connect the entire ecosystem of Lns, including the many Lns using different VMs.
-* We will need to balance this goal with goal 1; we shouldn't make the interface overly complex to achieve this goal.
-
-### 3. Interface should be proof-agnostic. --> Agree
-
-Reasoning:
-* Many proof systems will be used in the underlying messaging protocols. This interface should be compatible with any of those protocols. Otherwise, the interface does not achieve its primary goal abstracting the underlying messaging protocol from developers.
-
-### 4. Interface should be protocol-agnostic. --> Agree
-
-Reasoning:
-* Many messaging protocols will be used. This interface should be compatible with any of those protocols.
-
-### 5. Interface is compatible with any Ln↔Ln messaging. --> Agree
-
-Reasoning:
-* Both L2 <> L2 messaging and L1 <> L2 messaging are core use cases. If we want to create a unified developer experience, the interface needs to support both using the same abstractions.
-* L3 <> L2 messaging is a less common use case, but should be supported.
-* Key Question: Should it be an explicit goal of this interface to support L1 <> L1 messaging?
-
-### 6. Making it happen soon
-
-Glacis --> TODO investigate
-OZ adapts - 2-4 weeks / adapter --> 3 months for at least 3 adapters
- Axelar
- Wormhole
- Hyperlane
- LZ
- Chainlink
-
- Parallel track - public support from major protocols to advertise this
-
-### 7. Support m / n messsage aggregation
-
-### 8. Data transfer
-
-### 9. Only narrow casting vs broadcasting to begin with
-3 ways: push, pull, read
-
-push -
-pull -
-
-Push vs Pull
-A push protocol allows for the entire cross-chain transmission lifecycle, up to and including delivery to a receiver, to be arranged on the source chain without a user transaction on the destination chain. The protocol may rely on third party relayers to complete the lifecycle.
-
-A pull protocol requires a user (or application) to complete the lifecycle with a transaction on the destination chain. The protocol can be said to require self-relaying.
-
-push + local pull
-push + execute
-don't need to worry about broadcast (for now
-
-### 10. Gas is out of scope (for now)
-
-### 11. Interface does not enforce ordering
-
-### 12. Liveness
-The protocol MUST guarantee Safety: A message is delivered at the destination if and only if it was sent at the source. The delivery process must ensure a message is only delivered once the sending transaction is finalized, and not delivered more than once. Note that there can be multiple messages with identical parameters that must be delivered separately.
-The protocol MUST guarantee Liveness: A sent message is delivered at the destination eventually, assuming Liveness and censorship-resistance of the source and destination chains.
-
-
-
-
-### Message Format
-
-Message {
- payload: bytes
- source address: bytes
- source chain id: bytes
- destination adress: bytes
- destination chain: bytes
- nonce: uint32
-}
-
-packet_id - unique id, bytes
-
-// destination addr
-fn send (payload, (destination address?), destination chain) -> packet id
-
-
-// Won't support for now
-fn recv (packet id) -> Message
-
-
- function executeMessage(
- string calldata sourceChain, // [CAIP-2] chain identifier
- string calldata sender, // [CAIP-10] account address
- bytes calldata payload,
- bytes[] calldata attributes
- ) external payable returns (bytes4);
-
-
-
- Gas
-
- source chain:
- pay_gas(packet id) payable
-
- estimate_gas(gas_limit, destination id, ) -> cost on origin gas token
-
- // Didn't add enough gas in the beginning
- add_gas (
-
-
-
-
-Questions:
-* Should we allow tx hash as unique id?
-
-## Miscellaneous Questions (to be addressed later)
-* Should the interface include gas quoting?
-* Should the interface be pull or push-based?
-* Should the interface use Ethereum specific addresses?
-* Should the interface defined specific message formats for specific use cases?
-* Should the interface use 7786-style attributes
-* Why don't existing messaging designs cover our use cases?
-* How should cross-chain addresses be represented?