> ## Documentation Index
> Fetch the complete documentation index at: https://docs.notareum.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cross chain identity

# Cross-Chain Identity

A single entity usually operates on multiple chains. A DAO has a treasury on Ethereum, ops accounts on Arbitrum, grants on Base, a Solana program, and a Bitcoin cold vault. Today, linking these addresses to one identity depends on convention: a Twitter bio, a governance forum post, a page on the website. None of those are cryptographic. Notareum binds an issuer identity to addresses across every chain through signed `.nota` files that share an issuer DID, producing a verifiable cross-chain identity graph.

## The model

```mermaid theme={"system"}
flowchart TB
    Issuer[Issuer DID: did:web:acmedao.xyz] --> E[.nota: ETH 0x...]
    Issuer --> P[.nota: Polygon 0x...]
    Issuer --> A[.nota: Arbitrum 0x...]
    Issuer --> B[.nota: Base 0x...]
    Issuer --> S[.nota: Solana Pub...]
    Issuer --> BTC[.nota: Bitcoin bc1...]
    Issuer --> C[.nota: Cosmos cosmos1...]
    E --> Registry[NotaRegistry]
    P --> Registry
    A --> Registry
    B --> Registry
    S --> Registry
    BTC --> Registry
    C --> Registry
```

Every `.nota` file references the same issuer DID and is signed by a key listed in that DID document. Consumers resolve the DID, enumerate the authorized keys, and verify each address `.nota` against the appropriate key for that chain.

## DIDs as identity anchors

Notareum uses W3C Decentralized Identifiers (DIDs) as the canonical issuer anchor. The two most common methods are:

* `did:web:acmedao.xyz` resolves to `https://acmedao.xyz/.well-known/did.json`.
* `did:pkh:eip155:1:0x...` derives directly from an Ethereum address.

A DID document lists the set of public keys authorized to sign on behalf of the issuer, each key's `publicKeyMultibase`, and the chains it is valid for. Example:

```json theme={"system"}
{
  "id": "did:web:acmedao.xyz",
  "verificationMethod": [
    {
      "id": "did:web:acmedao.xyz#eth-admin",
      "type": "EcdsaSecp256k1RecoveryMethod2020",
      "controller": "did:web:acmedao.xyz",
      "blockchainAccountId": "eip155:1:0xabc...",
      "purposes": ["evm-signing"]
    },
    {
      "id": "did:web:acmedao.xyz#sol-admin",
      "type": "Ed25519VerificationKey2020",
      "publicKeyMultibase": "z6Mk...",
      "purposes": ["solana-signing"]
    },
    {
      "id": "did:web:acmedao.xyz#btc-admin",
      "type": "SchnorrSecp256k1VerificationKey2024",
      "publicKeyMultibase": "zQ3...",
      "purposes": ["bitcoin-signing"]
    }
  ]
}
```

The issuer controls the DID document; the document controls which keys sign which chains; each chain's `.nota` carries a signature from the correct key. Revoking a key is a DID document update, which cascades to every `.nota` that key signed.

## Binding chains per issuer

```typescript theme={"system"}
import { Notareum } from "@notareum/sdk";

const ntm = Notareum({ provider, signer, contracts });

async function bindAddress(params: {
  chainId: number;
  chainName: string;
  identifier: string;
  role: "treasury" | "ops" | "grants" | "cold";
  signer: any;
  signerKeyId: string; // e.g. "did:web:acmedao.xyz#eth-admin"
}) {
  return ntm.nota
    .create({
      type: "address",
      chainId: params.chainId,
      chainName: params.chainName,
      identifier: params.identifier,
      name: `Acme DAO ${params.role}`,
      description: `${params.chainName} ${params.role} wallet`,
      resourceMetadata: {
        role: params.role,
        signerKeyId: params.signerKeyId,
        issuerGraph: "did:web:acmedao.xyz",
      },
      issuerName: "Acme DAO",
      issuerEntityType: "organization",
      issuerDid: "did:web:acmedao.xyz",
    })
    .validate()
    .sign(params.signer);
}

const eth = await bindAddress({ chainId: 1, chainName: "ethereum", identifier: ethAddr,
  role: "treasury", signer: ethSigner, signerKeyId: "did:web:acmedao.xyz#eth-admin" });
const sol = await bindAddress({ chainId: 101, chainName: "solana", identifier: solAddr,
  role: "treasury", signer: solSigner, signerKeyId: "did:web:acmedao.xyz#sol-admin" });
const btc = await bindAddress({ chainId: 0, chainName: "bitcoin", identifier: btcAddr,
  role: "cold", signer: btcSigner, signerKeyId: "did:web:acmedao.xyz#btc-admin" });
```

The same fluent API handles EVM, Solana, Bitcoin, and Cosmos. Each SDK dispatches signing to a chain-appropriate signer; the resulting `.nota` is canonically serialized so signature semantics are unambiguous.

## Chain identifier conventions

`chainId` and `chainName` are the two identity coordinates. The protocol follows these conventions:

| Chain family        | `chainId` source                           | `chainName`                                                |
| ------------------- | ------------------------------------------ | ---------------------------------------------------------- |
| EVM (Ethereum, L2s) | EIP-155 integer                            | lowercase slug (`ethereum`, `polygon`, `arbitrum`, `base`) |
| Solana              | `101` mainnet, `102` testnet, `103` devnet | `solana`                                                   |
| Bitcoin             | `0` mainnet, `1` testnet                   | `bitcoin`                                                  |
| Cosmos SDK chains   | ChainID string hashed to uint256           | canonical chain-id (`cosmoshub-4`, `osmosis-1`)            |
| Aptos / Sui         | Move chain-id                              | `aptos`, `sui`                                             |

The SDK exposes a `chainIdToName` helper and a reverse `chainNameToId` for consistent binding.

## Consumer resolution

A consumer verifying a payment claim like "send to Acme DAO's Arbitrum treasury" follows this path:

```typescript theme={"system"}
import { Notareum } from "@notareum/sdk";

const ntm = Notareum({ provider, contracts });

async function resolveIssuerAddress(
  issuerDid: string,
  chainId: number,
  role?: string
) {
  const issuer = await ntm.registry.getIssuerByDid(issuerDid);
  if (!issuer.exists || issuer.isRevoked) {
    throw new Error("Issuer not recognized");
  }

  const candidates = await ntm.registry.listByIssuer(issuer.id, {
    type: "address",
    chainId,
  });

  const match = role ? candidates.find((c) => c.resourceMetadata.role === role) : candidates[0];
  if (!match) throw new Error("No address for chain/role combination");
  return match;
}

const acmeArb = await resolveIssuerAddress("did:web:acmedao.xyz", 42161, "treasury");
```

## Proving cross-chain control

Claiming an address on another chain is cheap. Proving control requires the signing key for that chain to sign a payload bound to the issuer identity. Notareum provides a standard `control proof`:

```typescript theme={"system"}
const proof = await ntm.nota
  .create({
    type: "attestation",
    chainId: 101,
    chainName: "solana",
    identifier: solAddr,
    name: "Control proof",
    resourceMetadata: {
      attestationType: "control_proof",
      issuerDid: "did:web:acmedao.xyz",
      nonce: "0x1234...",
      timestamp: Date.now(),
    },
  })
  .sign(solSigner);
```

A consumer checks that `proof.signature.signer` matches the address and that the address is bound to the stated DID. This is the `.nota` analogue of signing a message in MetaMask to prove account control.

## Cross-chain revocation

Revocation is key-scoped, not chain-scoped. Three revocation paths:

1. **Revoke a specific `.nota`** via `NotaRegistry.revokeResource`. Only that chain/address pair is affected.
2. **Revoke a key in the DID document**. Every `.nota` signed by that key is implicitly untrusted going forward. Consumers checking DID state reject new verifications but can still honor receipts issued before revocation (if timestamps are within the key's validity window).
3. **Revoke the issuer entirely**. The issuer DID is marked retired; all resources under that DID are untrusted.

## Integration patterns

* **Wallets** render "Acme DAO (7 chains verified)" with a single issuer query, then route sends to the right chain/address pair.
* **Block explorers** cluster addresses by issuer DID across chains.
* **Cross-chain bridges** require sender and recipient to be addresses bound to the same issuer DID as an anti-phishing guard.
* **Compliance tooling** builds entity-level reports spanning every chain without manual mapping.

## Related pages

* [.nota File Format](../protocol/nota-file-format.md)
* [Institutional Treasuries](institutional-treasuries.md)
* [Wallet Address Sharing](wallet-address-sharing.md)
* [Resource Registry](../protocol/resource-registry.md)
