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

# Understanding wallets and addresses

> Understand how wallets map to on-chain addresses and what a single address can hold.

export const WalletPlanner = () => {
  const SANS = "Inter, ui-sans-serif, system-ui, sans-serif";
  const MONO = "'Roboto Mono', ui-monospace, SFMono-Regular, monospace";
  const WAM_WIDS = ["8f3a21", "c075d9", "41be8c", "9d2b64", "7c5e19"];
  const WAM_BTC_WID = "2d97bf";
  const wamWid = s => "wallet ID=" + s;
  const WAM_NETS = {
    ethereum: {
      label: "Ethereum",
      family: "EVM",
      model: "account",
      assets: "ETH, ERC-20s",
      chain: ["Ethereum", "Arbitrum", "Base", "Optimism", "Polygon"],
      addr: ["0xA1b2…9F3c", "0x7Dc4…21Ea", "0xF03b…8B7d", "0x5E9a…C412", "0x2b81…7f6D"]
    },
    solana: {
      label: "Solana",
      family: "SVM",
      model: "account",
      assets: "SOL, SPL tokens",
      chain: ["Solana", "Fogo"],
      addr: ["7xKX…gAsU", "9pQm…Lt3V"]
    },
    bitcoin: {
      label: "Bitcoin",
      family: "UTXO",
      model: "utxo",
      assets: "BTC",
      chain: ["Bitcoin"],
      addr: ["bc1q…4k2p", "bc1q…m7ry", "bc1q…s8ez", "bc1q…j0xd"]
    }
  };
  const isDark = () => typeof document !== "undefined" && (document.documentElement.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark");
  const [dark, setDark] = useState(isDark);
  useEffect(() => {
    if (typeof document === "undefined") return;
    const read = () => setDark(isDark());
    read();
    const obs = new MutationObserver(read);
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class", "data-theme"]
    });
    return () => obs.disconnect();
  }, []);
  const C = dark ? {
    card: "#161718",
    cardBorder: "#222325",
    panel: "#1F1F1F",
    soft: "#1B1C1D",
    strong: "#FFFFFF",
    body: "#CACBCE",
    muted: "#AAACB1",
    line: "#222325",
    edge: "#4E5055",
    anchorage: "#90ACF9",
    anchorageSoft: "#131C34",
    chain: "#5FD6E8",
    chainSoft: "#0B2126",
    auto: "#E4B45C",
    autoSoft: "#271C02",
    termBg: "#0F0F10",
    termInk: "#F4F5F5",
    termMuted: "#8B8F94"
  } : {
    card: "#FFFFFF",
    cardBorder: "#E4E5E7",
    panel: "#FFFFFF",
    soft: "#F4F5F5",
    strong: "#000000",
    body: "#4E5055",
    muted: "#6B6E73",
    line: "#E4E5E7",
    edge: "#AAACB1",
    anchorage: "#2E52C8",
    anchorageSoft: "#F5F8FF",
    chain: "#0E7C8D",
    chainSoft: "#F0FAFB",
    auto: "#886107",
    autoSoft: "#FDF8EC",
    termBg: "#141415",
    termInk: "#F4F5F5",
    termMuted: "#9A9DA2"
  };
  const label = {
    fontFamily: MONO,
    fontSize: "11px",
    letterSpacing: "0.04em",
    color: C.muted,
    fontWeight: 600,
    marginBottom: "10px",
    textTransform: "uppercase"
  };
  const legend = {
    marginTop: "10px",
    fontSize: "11.5px",
    lineHeight: 1.6,
    color: C.muted
  };
  const scroller = {
    overflowX: "auto"
  };
  const svgStyle = {
    width: "100%",
    minWidth: "640px",
    height: "auto",
    display: "block"
  };
  const WamArrow = ({id, color}) => <defs>
      <marker id={id} viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
        <path d="M 0 1 L 9 5 L 0 9 z" fill={color} />
      </marker>
    </defs>;
  const WamSwatch = ({color}) => <span style={{
    display: "inline-block",
    width: "8px",
    height: "8px",
    borderRadius: "2px",
    background: color,
    marginRight: "4px"
  }} />;
  const [network, setNetwork] = useState("ethereum");
  const [reach, setReach] = useState("all");
  const [strategy, setStrategy] = useState("shared");
  const [utxoCount, setUtxoCount] = useState("2");
  const net = WAM_NETS[network];
  const isUtxo = net.model === "utxo";
  const plan = (() => {
    if (isUtxo) {
      const count = parseInt(utxoCount, 10);
      return {
        kind: "utxo",
        wallets: [{
          net: "Bitcoin",
          wid: WAM_BTC_WID,
          assets: net.assets
        }],
        addresses: net.addr.slice(0, count).map((v, i) => ({
          v,
          auto: i > 0
        })),
        map: () => true
      };
    }
    const k = reach === "only" ? 1 : net.chain.length;
    const nets = net.chain.slice(0, k);
    const shared = strategy === "shared" || k === 1;
    return {
      kind: shared ? "shared" : "unique",
      wallets: nets.map((n, i) => ({
        net: n,
        wid: WAM_WIDS[i % WAM_WIDS.length],
        assets: n === "Polygon" ? "POL, ERC-20s" : net.assets
      })),
      addresses: shared ? [{
        v: net.addr[0],
        auto: false
      }] : nets.map((_, i) => ({
        v: net.addr[i % net.addr.length],
        auto: false
      })),
      map: (wi, ai) => shared ? ai === 0 : wi === ai
    };
  })();
  const caseName = plan.kind === "utxo" ? "UTXO" : plan.wallets.length === 1 ? "one network" : plan.kind === "shared" ? "compatible networks, shared address" : "compatible networks, address per network";
  const lane = (count, y, h, maxW) => {
    const span = 880, x0 = 60, gap = 14;
    const w = Math.min(maxW, (span - (count - 1) * gap) / count);
    const total = count * w + (count - 1) * gap;
    const start = x0 + (span - total) / 2;
    const out = [];
    for (let i = 0; i < count; i++) {
      const x = start + i * (w + gap);
      out.push({
        x,
        y,
        w,
        h,
        cx: x + w / 2
      });
    }
    return out;
  };
  const W = lane(plan.wallets.length, 58, 66, 200);
  const A = lane(plan.addresses.length, 262, 62, 200);
  const edges = [];
  W.forEach((w, wi) => {
    A.forEach((a, ai) => {
      if (!plan.map(wi, ai)) return;
      const y1 = w.y + w.h, y2 = a.y - 6, mid = 200;
      edges.push(Math.abs(w.cx - a.cx) < 0.5 ? "M " + w.cx + " " + y1 + " L " + w.cx + " " + y2 : "M " + w.cx + " " + y1 + " L " + w.cx + " " + mid + " L " + a.cx + " " + mid + " L " + a.cx + " " + y2);
    });
  });
  const cardinality = plan.wallets.length + (plan.wallets.length === 1 ? " wallet ID : " : " wallet IDs : ") + plan.addresses.length + (plan.addresses.length === 1 ? " address" : " addresses");
  const planFoot = plan.kind === "utxo" ? "Every address receives, and all of them pool into one balance under one wallet ID." : plan.kind === "shared" ? plan.wallets.length > 1 ? "Edges converge: several wallet IDs behind one on-chain address." : "One wallet, one address." : "Parallel edges: each network has its own on-chain address.";
  const segBtn = (on, off) => ({
    flex: "1 1 0",
    minWidth: 0,
    border: "none",
    borderRadius: "8px",
    padding: "7px 6px",
    fontFamily: SANS,
    fontSize: "12.5px",
    fontWeight: 600,
    cursor: off ? "not-allowed" : "pointer",
    opacity: off ? 0.4 : 1,
    background: on ? C.panel : "transparent",
    color: on ? C.strong : C.body,
    boxShadow: on ? "0 1px 2px rgba(0,0,0,0.08)" : "none"
  });
  const Seg = ({title, note, options, value, onPick, disabled}) => <div style={{
    minWidth: "200px",
    flex: "1 1 200px"
  }}>
      <div style={{
    fontSize: "11px",
    letterSpacing: "0.06em",
    color: C.muted,
    marginBottom: "6px",
    fontWeight: 600,
    textTransform: "uppercase"
  }}>{title}</div>
      <div style={{
    display: "flex",
    background: C.soft,
    border: "1px solid " + C.line,
    borderRadius: "10px",
    padding: "3px",
    gap: "3px"
  }}>
        {options.map(o => <button key={o.v} type="button" style={segBtn(value === o.v, disabled)} aria-pressed={value === o.v} disabled={disabled} onClick={() => {
    if (!disabled) onPick(o.v);
  }}>{o.t}</button>)}
      </div>
      <div style={{
    fontSize: "11px",
    color: C.muted,
    marginTop: "5px",
    lineHeight: 1.45
  }}>{note}</div>
    </div>;
  const summaryLines = (() => {
    const out = [["Wallets to create", plan.wallets.map(w => w.net).join(", ")]];
    if (plan.kind === "utxo") {
      out.push(["Addresses", "one to start, then as many as you generate, all pooled"]);
      out.push(["Assets", "BTC only, because a UTXO network has no token layer to share the address with"]);
    } else if (plan.wallets.length === 1) {
      out.push(["Addresses", "exactly one, so a second address means a second wallet"]);
      out.push(["Assets", net.assets + ", sharing this wallet ID"]);
    } else {
      out.push(["Addresses", plan.kind === "shared" ? "one, shared by every wallet above" : "one per network, none shared"]);
      out.push(["Balances", "tracked per wallet ID, and a withdrawal names a wallet ID"]);
    }
    return out;
  })();
  const holdRows = (() => {
    const out = [["Withdrawing", "A withdrawal names a wallet ID. The first wallet created for a network in a vault is that vault's default wallet, and the source of funds for external withdrawals."]];
    if (plan.kind === "utxo") {
      out.push(["Choosing a source", "You never designate an address. Funds are pulled from multiple addresses automatically."]);
      out.push(["Change addresses", "A transfer returns its unspent remainder to a new address inside this wallet, managed for you and counted in the balance."]);
      out.push(["Allowlisting", "Trusted destinations are per network, so one Bitcoin entry covers withdrawals from this wallet."]);
    } else if (plan.wallets.length === 1) {
      out.push(["Another address", "On an account-based network, a second deposit address means a second wallet with its own wallet ID."]);
      out.push(["Token deposits", "Every token on this network uses this same deposit address, while balances stay separate per asset."]);
      out.push(["Allowlisting", "Trusted destinations are per network, so add this network's entry before withdrawing."]);
    } else {
      out.push(["Moving between networks", "Balances never cross networks on their own. Getting funds from " + plan.wallets[0].net + " to " + plan.wallets[1].net + " means bridging."]);
      out.push(["Allowlisting", plan.kind === "shared" ? "Per network, always: the same address on " + plan.wallets[0].net + " and " + plan.wallets[1].net + " are two separate trusted destinations." : "Per network, always, and here each network has its own address to allowlist."]);
      out.push([plan.kind === "shared" ? "On-chain visibility" : "Privacy", plan.kind === "shared" ? "One address carries activity for all " + plan.wallets.length + " networks, so anyone watching it sees the whole set." : "Separate addresses keep these networks unlinked on chain. To get a fresh address in a family, create more wallets than you already hold in it."]);
      out.push(["Unexpected deposits", "A deposit on a compatible network where you have no wallet is still detected on the shared address. We run spam attribution and create the wallet if it clears."]);
    }
    return out;
  })();
  const card = {
    background: C.panel,
    border: "1px solid " + C.line,
    borderRadius: "14px",
    padding: "16px"
  };
  return <div style={{
    background: dark ? C.soft : "#F4F5F5",
    border: "1px solid " + C.cardBorder,
    borderRadius: "14px",
    padding: "16px",
    margin: "1.5rem 0",
    fontFamily: SANS
  }}>
      <div style={{
    ...card,
    display: "flex",
    gap: "18px",
    flexWrap: "wrap",
    marginBottom: "14px"
  }}>
        <Seg title="1 · Network" note={isUtxo ? "UTXO. One asset, many addresses." : "Account-based. " + net.family + " family, " + net.chain.length + " compatible networks."} options={[{
    v: "ethereum",
    t: "Ethereum"
  }, {
    v: "solana",
    t: "Solana"
  }, {
    v: "bitcoin",
    t: "Bitcoin"
  }]} value={network} onPick={v => {
    setNetwork(v);
    if (WAM_NETS[v].model === "utxo") setReach("only");
  }} />

        <Seg title="2 · Networks to cover" note={isUtxo ? "UTXO networks share no addresses across networks." : reach === "only" ? "One network, one wallet ID." : "Covers " + net.chain.join(", ") + "."} options={[{
    v: "only",
    t: "This one"
  }, {
    v: "all",
    t: "All"
  }]} value={reach} onPick={setReach} disabled={isUtxo} />

        <Seg title="3 · Address strategy" note={isUtxo ? "Not applicable." : reach === "only" ? "Applies once more than one network is covered." : strategy === "shared" ? "Option B above." : "Option A above."} options={[{
    v: "shared",
    t: "Shared"
  }, {
    v: "unique",
    t: "Unique"
  }]} value={strategy} onPick={setStrategy} disabled={isUtxo || reach === "only"} />

        <Seg title="4 · Addresses generated" note={isUtxo ? "Generate more at any time, all pooled to this wallet." : "Applies to UTXO networks only."} options={[{
    v: "1",
    t: "1"
  }, {
    v: "2",
    t: "2"
  }, {
    v: "4",
    t: "4"
  }]} value={utxoCount} onPick={setUtxoCount} disabled={!isUtxo} />
      </div>

      <div style={card}>
        <div style={label}>Resulting structure: {caseName}</div>
        <div style={scroller}>
          <svg viewBox="0 0 1000 380" style={svgStyle} fontFamily={SANS} role="img" aria-label={"Generated diagram. " + cardinality + ". " + planFoot}>
            <WamArrow id="wam-plan" color={C.edge} />
            <text x="0" y="14" fontFamily={MONO} fontSize="9.5" letterSpacing="0.9" fill={C.muted}>ANCHORAGE DIGITAL · wallet ID</text>
            <text x="0" y="248" fontFamily={MONO} fontSize="9.5" letterSpacing="0.9" fill={C.muted}>ON CHAIN · address</text>
            <text x="1000" y="14" textAnchor="end" fontFamily={MONO} fontSize="11.5" fontWeight="700" fill={C.anchorage}>{cardinality}</text>

            {edges.map((d, i) => <path key={i} d={d} stroke={C.edge} strokeWidth="1.4" fill="none" markerEnd="url(#wam-plan)" />)}

            {W.map((w, i) => <g key={"w" + i}>
                <rect x={w.x} y={w.y} width={w.w} height={w.h} rx="9" fill={C.anchorageSoft} stroke={C.anchorage} strokeWidth="1.5" />
                <text x={w.cx} y={w.y + 22} textAnchor="middle" fontSize="11" fontWeight="600" fill={C.strong}>{plan.wallets[i].net}</text>
                <text x={w.cx} y={w.y + 40} textAnchor="middle" fontFamily={MONO} fontSize="9.5" fill={C.anchorage}>{wamWid(plan.wallets[i].wid)}</text>
                <text x={w.cx} y={w.y + 56} textAnchor="middle" fontSize="9.5" fill={C.muted}>{plan.wallets[i].assets}</text>
              </g>)}

            {A.map((a, i) => <g key={"a" + i}>
                <rect x={a.x} y={a.y} width={a.w} height={a.h} rx="9" fill={plan.addresses[i].auto ? C.autoSoft : C.chainSoft} stroke={plan.addresses[i].auto ? C.auto : C.chain} strokeWidth="1.2" strokeDasharray="5 4" />
                <text x={a.cx} y={a.y + 26} textAnchor="middle" fontFamily={MONO} fontSize="10.5" fill={plan.addresses[i].auto ? C.auto : C.chain}>{plan.addresses[i].v}</text>
                <text x={a.cx} y={a.y + 44} textAnchor="middle" fontSize="9.5" fill={plan.addresses[i].auto ? C.auto : C.muted}>
                  {plan.addresses[i].auto ? "generated, pooled" : plan.kind === "utxo" ? "deposit" : "deposit address"}
                </text>
              </g>)}

            <text x="500" y="358" textAnchor="middle" fontSize="10.5" fill={C.muted}>{planFoot}</text>
          </svg>
        </div>
        <div style={legend}>
          <WamSwatch color={C.anchorage} />Wallets on top  
          <WamSwatch color={C.chain} />addresses below  
          <WamSwatch color={C.auto} />generated for you.   Edges that converge on one address are the n : 1 case.
        </div>
      </div>

      <div style={{
    display: "flex",
    gap: "14px",
    marginTop: "14px",
    flexWrap: "wrap"
  }}>
        <div style={{
    ...card,
    flex: "1 1 340px",
    borderLeft: "4px solid " + C.chain,
    padding: "14px 16px"
  }}>
          <div style={label}>What you end up with</div>
          <div style={{
    display: "flex",
    gap: "10px",
    flexWrap: "wrap",
    marginBottom: "10px"
  }}>
            {[[plan.wallets.length, "Wallets", C.anchorage], [plan.addresses.length, "On-chain addresses", C.chain], [new Set(plan.wallets.map(w => w.net)).size, "Networks", C.anchorage]].map(k => <div key={k[1]} style={{
    flex: "1 1 90px"
  }}>
                <div style={{
    fontFamily: MONO,
    fontSize: "20px",
    color: k[2],
    fontVariantNumeric: "tabular-nums"
  }}>{k[0]}</div>
                <div style={{
    fontSize: "10.5px",
    color: C.muted,
    textTransform: "uppercase",
    letterSpacing: "0.04em"
  }}>{k[1]}</div>
              </div>)}
          </div>
          {summaryLines.map(l => <div key={l[0]} style={{
    fontSize: "12.5px",
    lineHeight: 1.55,
    color: C.body,
    marginBottom: "6px"
  }}>
              <strong style={{
    color: C.strong
  }}>{l[0]}:</strong> {l[1]}.
            </div>)}
        </div>

        <div style={{
    ...card,
    flex: "1 1 340px",
    padding: "14px 16px"
  }}>
          <div style={label}>As the API would list it</div>
          <div style={{
    fontFamily: MONO,
    fontSize: "12px",
    background: C.termBg,
    color: C.termInk,
    borderRadius: "12px",
    padding: "12px 14px",
    maxHeight: "240px",
    overflow: "auto",
    lineHeight: 1.6
  }}>
            <div style={{
    color: C.termMuted
  }}>GET /v2/wallets</div>
            {plan.kind === "utxo" ? <div style={{
    display: "flex",
    gap: "12px",
    whiteSpace: "nowrap"
  }}>
                <span style={{
    width: "152px",
    flexShrink: 0
  }}>{wamWid(plan.wallets[0].wid)}</span>
                <span style={{
    width: "92px",
    flexShrink: 0,
    color: C.termMuted
  }}>BITCOIN</span>
                <span style={{
    flex: 1
  }}>{plan.addresses.map(a => a.v).join(", ")}</span>
              </div> : plan.wallets.map((w, i) => <div key={w.wid} style={{
    display: "flex",
    gap: "12px",
    whiteSpace: "nowrap"
  }}>
                <span style={{
    width: "152px",
    flexShrink: 0
  }}>{wamWid(w.wid)}</span>
                <span style={{
    width: "92px",
    flexShrink: 0,
    color: C.termMuted
  }}>{w.net.toUpperCase()}</span>
                <span style={{
    flex: 1
  }}>{plan.addresses[plan.kind === "shared" ? 0 : i].v}</span>
              </div>)}
            <div style={{
    color: C.termMuted,
    marginTop: "8px",
    whiteSpace: "normal"
  }}>
              {plan.kind === "utxo" ? "One wallet, " + plan.addresses.length + " address" + (plan.addresses.length === 1 ? "" : "es") + ". Deposit-address listings return every one of them." : plan.wallets.length === 1 ? "One wallet, one address." : plan.kind === "shared" ? "Separate wallet IDs, identical address. Filtering by address returns all " + plan.wallets.length + " wallets." : "Separate wallet IDs, separate addresses. Nothing correlates these on chain."}
            </div>
          </div>
        </div>
      </div>

      <div style={{
    ...card,
    marginTop: "14px"
  }}>
        <div style={label}>What this means for this configuration</div>
        <div style={{
    display: "grid",
    gridTemplateColumns: "repeat(auto-fit, minmax(230px, 1fr))",
    gap: "0 20px"
  }}>
          {holdRows.map(r => <div key={r[0]} style={{
    padding: "8px 0",
    borderTop: "1px solid " + C.line
  }}>
              <div style={{
    fontSize: "11.5px",
    fontWeight: 700,
    color: C.anchorage,
    marginBottom: "2px"
  }}>{r[0]}</div>
              <div style={{
    fontSize: "12.5px",
    lineHeight: 1.5,
    color: C.body
  }}>{r[1]}</div>
            </div>)}
        </div>
      </div>
    </div>;
};

export const CompatibleNetworkOptions = () => {
  const SANS = "Inter, ui-sans-serif, system-ui, sans-serif";
  const MONO = "'Roboto Mono', ui-monospace, SFMono-Regular, monospace";
  const wamWid = s => "wallet ID=" + s;
  const isDark = () => typeof document !== "undefined" && (document.documentElement.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark");
  const [dark, setDark] = useState(isDark);
  useEffect(() => {
    if (typeof document === "undefined") return;
    const read = () => setDark(isDark());
    read();
    const obs = new MutationObserver(read);
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class", "data-theme"]
    });
    return () => obs.disconnect();
  }, []);
  const C = dark ? {
    card: "#161718",
    cardBorder: "#222325",
    panel: "#1F1F1F",
    soft: "#1B1C1D",
    strong: "#FFFFFF",
    body: "#CACBCE",
    muted: "#AAACB1",
    line: "#222325",
    edge: "#4E5055",
    anchorage: "#90ACF9",
    anchorageSoft: "#131C34",
    chain: "#5FD6E8",
    chainSoft: "#0B2126",
    auto: "#E4B45C",
    autoSoft: "#271C02",
    termBg: "#0F0F10",
    termInk: "#F4F5F5",
    termMuted: "#8B8F94"
  } : {
    card: "#FFFFFF",
    cardBorder: "#E4E5E7",
    panel: "#FFFFFF",
    soft: "#F4F5F5",
    strong: "#000000",
    body: "#4E5055",
    muted: "#6B6E73",
    line: "#E4E5E7",
    edge: "#AAACB1",
    anchorage: "#2E52C8",
    anchorageSoft: "#F5F8FF",
    chain: "#0E7C8D",
    chainSoft: "#F0FAFB",
    auto: "#886107",
    autoSoft: "#FDF8EC",
    termBg: "#141415",
    termInk: "#F4F5F5",
    termMuted: "#9A9DA2"
  };
  const panel = {
    background: C.panel,
    border: "1px solid " + C.cardBorder,
    borderRadius: "14px",
    padding: "16px",
    margin: "1.5rem 0",
    fontFamily: SANS
  };
  const label = {
    fontFamily: MONO,
    fontSize: "11px",
    letterSpacing: "0.04em",
    color: C.muted,
    fontWeight: 600,
    marginBottom: "10px",
    textTransform: "uppercase"
  };
  const legend = {
    marginTop: "10px",
    fontSize: "11.5px",
    lineHeight: 1.6,
    color: C.muted
  };
  const scroller = {
    overflowX: "auto"
  };
  const svgStyle = {
    width: "100%",
    minWidth: "640px",
    height: "auto",
    display: "block"
  };
  const WamArrow = ({id, color}) => <defs>
      <marker id={id} viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
        <path d="M 0 1 L 9 5 L 0 9 z" fill={color} />
      </marker>
    </defs>;
  const rows = [{
    y: 40,
    name: "Ethereum",
    w: "8f3a21",
    a: "0xA1b2…9F3c"
  }, {
    y: 92,
    name: "Arbitrum",
    w: "c075d9",
    a: "0x7Dc4…21Ea"
  }, {
    y: 144,
    name: "Base",
    w: "41be8c",
    a: "0xF03b…8B7d"
  }];
  return <div style={panel}>
      <div style={label}>Separate addresses vs one shared address</div>
      <div style={scroller}>
        <svg viewBox="0 0 1000 300" style={svgStyle} fontFamily={SANS} role="img" aria-label="Option A: three wallets on Ethereum, Arbitrum, and Base, each with its own wallet ID and its own separate on-chain address. Option B: the same three wallets with their own wallet IDs all sharing a single on-chain address.">
          <WamArrow id="wam-a3" color={C.edge} />

          <text x="0" y="14" fontFamily={MONO} fontSize="9.5" letterSpacing="0.9" fill={C.muted}>OPTION A · AN ADDRESS PER NETWORK</text>
          {rows.map(r => <g key={r.name}>
              <rect x="0" y={r.y} width="226" height="40" rx="8" fill={C.anchorageSoft} stroke={C.anchorage} strokeWidth="1.5" />
              <text x="14" y={r.y + 25} fontSize="10.5" fontWeight="600" fill={C.strong}>{r.name}</text>
              <text x="212" y={r.y + 25} textAnchor="end" fontFamily={MONO} fontSize="9.5" fill={C.anchorage}>{wamWid(r.w)}</text>
              <line x1="226" y1={r.y + 20} x2="252" y2={r.y + 20} stroke={C.edge} strokeWidth="1.3" markerEnd="url(#wam-a3)" />
              <rect x="258" y={r.y} width="212" height="40" rx="8" fill={C.chainSoft} stroke={C.chain} strokeWidth="1.2" strokeDasharray="5 4" />
              <text x="364" y={r.y + 25} textAnchor="middle" fontFamily={MONO} fontSize="10" fill={C.chain}>{r.a}</text>
            </g>)}
          <text x="235" y="230" textAnchor="middle" fontFamily={MONO} fontSize="12" fontWeight="700" fill={C.anchorage}>3 wallet IDs : 3 addresses</text>
          <text x="235" y="256" textAnchor="middle" fontSize="10.5" fill={C.muted}>Nothing links these networks on chain.</text>
          <text x="235" y="272" textAnchor="middle" fontSize="10.5" fill={C.muted}>Three addresses to distribute and allowlist.</text>

          <line x1="500" y1="30" x2="500" y2="284" stroke={C.line} strokeWidth="1" />

          <text x="530" y="14" fontFamily={MONO} fontSize="9.5" letterSpacing="0.9" fill={C.muted}>OPTION B · ONE ADDRESS FOR THE FAMILY</text>
          {rows.map(r => <g key={"b" + r.name}>
              <rect x="530" y={r.y} width="226" height="40" rx="8" fill={C.anchorageSoft} stroke={C.anchorage} strokeWidth="1.5" />
              <text x="544" y={r.y + 25} fontSize="10.5" fontWeight="600" fill={C.strong}>{r.name}</text>
              <text x="742" y={r.y + 25} textAnchor="end" fontFamily={MONO} fontSize="9.5" fill={C.anchorage}>{wamWid(r.w)}</text>
            </g>)}
          <path d="M 756 60 L 772 60 L 772 164 L 756 164" stroke={C.edge} strokeWidth="1.3" fill="none" />
          <line x1="756" y1="112" x2="772" y2="112" stroke={C.edge} strokeWidth="1.3" />
          <line x1="772" y1="112" x2="800" y2="112" stroke={C.edge} strokeWidth="1.3" markerEnd="url(#wam-a3)" />

          <rect x="806" y="86" width="194" height="52" rx="9" fill={C.chainSoft} stroke={C.chain} strokeWidth="1.2" strokeDasharray="5 4" />
          <text x="903" y="108" textAnchor="middle" fontFamily={MONO} fontSize="10.5" fill={C.chain}>0xA1b2…9F3c</text>
          <text x="903" y="125" textAnchor="middle" fontSize="9.5" fill={C.muted}>one address, shared</text>

          <text x="765" y="230" textAnchor="middle" fontFamily={MONO} fontSize="12" fontWeight="700" fill={C.anchorage}>3 wallet IDs : 1 address</text>
          <text x="765" y="256" textAnchor="middle" fontSize="10.5" fill={C.muted}>One address for counterparties to use.</text>
          <text x="765" y="272" textAnchor="middle" fontSize="10.5" fill={C.muted}>Anyone watching it sees all three networks.</text>
        </svg>
      </div>
      <div style={legend}>
        You don’t have to create the wallet first. If you deposit a token on a compatible network where you have no wallet for it yet, we generate one: we detect the balance on the shared address, run spam attribution, and create the wallet on that network if the deposit clears. Spam deposits never generate wallets.
      </div>
    </div>;
};

export const AddressAssetTypes = () => {
  const SANS = "Inter, ui-sans-serif, system-ui, sans-serif";
  const MONO = "'Roboto Mono', ui-monospace, SFMono-Regular, monospace";
  const wamWid = s => "wallet ID=" + s;
  const isDark = () => typeof document !== "undefined" && (document.documentElement.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark");
  const [dark, setDark] = useState(isDark);
  useEffect(() => {
    if (typeof document === "undefined") return;
    const read = () => setDark(isDark());
    read();
    const obs = new MutationObserver(read);
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class", "data-theme"]
    });
    return () => obs.disconnect();
  }, []);
  const C = dark ? {
    card: "#161718",
    cardBorder: "#222325",
    panel: "#1F1F1F",
    soft: "#1B1C1D",
    strong: "#FFFFFF",
    body: "#CACBCE",
    muted: "#AAACB1",
    line: "#222325",
    edge: "#4E5055",
    anchorage: "#90ACF9",
    anchorageSoft: "#131C34",
    chain: "#5FD6E8",
    chainSoft: "#0B2126",
    auto: "#E4B45C",
    autoSoft: "#271C02",
    termBg: "#0F0F10",
    termInk: "#F4F5F5",
    termMuted: "#8B8F94"
  } : {
    card: "#FFFFFF",
    cardBorder: "#E4E5E7",
    panel: "#FFFFFF",
    soft: "#F4F5F5",
    strong: "#000000",
    body: "#4E5055",
    muted: "#6B6E73",
    line: "#E4E5E7",
    edge: "#AAACB1",
    anchorage: "#2E52C8",
    anchorageSoft: "#F5F8FF",
    chain: "#0E7C8D",
    chainSoft: "#F0FAFB",
    auto: "#886107",
    autoSoft: "#FDF8EC",
    termBg: "#141415",
    termInk: "#F4F5F5",
    termMuted: "#9A9DA2"
  };
  const panel = {
    background: C.panel,
    border: "1px solid " + C.cardBorder,
    borderRadius: "14px",
    padding: "16px",
    margin: "1.5rem 0",
    fontFamily: SANS
  };
  const label = {
    fontFamily: MONO,
    fontSize: "11px",
    letterSpacing: "0.04em",
    color: C.muted,
    fontWeight: 600,
    marginBottom: "10px",
    textTransform: "uppercase"
  };
  const legend = {
    marginTop: "10px",
    fontSize: "11.5px",
    lineHeight: 1.6,
    color: C.muted
  };
  const scroller = {
    overflowX: "auto"
  };
  const svgStyle = {
    width: "100%",
    minWidth: "640px",
    height: "auto",
    display: "block"
  };
  const WamArrow = ({id, color}) => <defs>
      <marker id={id} viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
        <path d="M 0 1 L 9 5 L 0 9 z" fill={color} />
      </marker>
    </defs>;
  const chips = [{
    x: 314,
    w: 78,
    t: "ETH",
    dash: false
  }, {
    x: 400,
    w: 84,
    t: "USDC",
    dash: false
  }, {
    x: 492,
    w: 84,
    t: "USDT",
    dash: false
  }, {
    x: 584,
    w: 84,
    t: "WBTC",
    dash: false
  }, {
    x: 676,
    w: 118,
    t: "any ERC-20",
    dash: true
  }];
  return <div style={panel}>
      <div style={label}>One address, many asset types</div>
      <div style={scroller}>
        <svg viewBox="0 0 1000 232" style={svgStyle} fontFamily={SANS} role="img" aria-label="One Ethereum on-chain address feeds a single wallet under one wallet ID, holding ETH, USDC, USDT, WBTC, and any other ERC-20 token, each with its own balance.">
          <WamArrow id="wam-a2" color={C.edge} />

          <text x="0" y="14" fontFamily={MONO} fontSize="9.5" letterSpacing="0.9" fill={C.muted}>ACCOUNT-BASED · ETHEREUM</text>

          <rect x="0" y="76" width="236" height="72" rx="9" fill={C.chainSoft} stroke={C.chain} strokeWidth="1.2" strokeDasharray="5 4" />
          <text x="118" y="106" textAnchor="middle" fontFamily={MONO} fontSize="11.5" fill={C.chain}>0xA1b2…9F3c</text>
          <text x="118" y="124" textAnchor="middle" fontSize="10" fill={C.muted}>one on-chain address</text>

          <line x1="236" y1="112" x2="286" y2="112" stroke={C.edge} strokeWidth="1.4" markerEnd="url(#wam-a2)" />

          <rect x="292" y="44" width="708" height="136" rx="9" fill={C.anchorageSoft} stroke={C.anchorage} strokeWidth="1.5" />
          <text x="314" y="70" fontSize="11.5" fontWeight="600" fill={C.strong}>Anchorage Digital wallet, Ethereum</text>
          <text x="978" y="70" textAnchor="end" fontFamily={MONO} fontSize="10.5" fill={C.anchorage}>{wamWid("8f3a21")}</text>

          {chips.map(c => <g key={c.t}>
              <rect x={c.x} y="86" width={c.w} height="28" rx="6" fill={C.card} stroke={C.edge} strokeDasharray={c.dash ? "4 3" : null} />
              <text x={c.x + c.w / 2} y="105" textAnchor="middle" fontFamily={MONO} fontSize="10.5" fill={c.dash ? C.muted : C.strong}>{c.t}</text>
            </g>)}

          <text x="314" y="140" fontSize="10.5" fill={C.body}>ETH is the network’s native asset. The rest are tokens issued on Ethereum.</text>
          <text x="314" y="158" fontSize="10.5" fill={C.body}>They share this address and this wallet ID, and each keeps its own balance.</text>

          <text x="500" y="214" textAnchor="middle" fontFamily={MONO} fontSize="12" fontWeight="700" fill={C.anchorage}>1 address · 1 wallet ID · many asset types</text>
        </svg>
      </div>
      <div style={legend}>
        Ethereum here, but this holds on any account-based network, such as Solana with its SPL tokens. To get a second deposit address you create a second wallet, which comes with its own wallet ID.
      </div>
    </div>;
};

export const WalletAddressMap = () => {
  const SANS = "Inter, ui-sans-serif, system-ui, sans-serif";
  const MONO = "'Roboto Mono', ui-monospace, SFMono-Regular, monospace";
  const WAM_BTC_WID = "2d97bf";
  const wamWid = s => "wallet ID=" + s;
  const isDark = () => typeof document !== "undefined" && (document.documentElement.classList.contains("dark") || document.documentElement.getAttribute("data-theme") === "dark");
  const [dark, setDark] = useState(isDark);
  useEffect(() => {
    if (typeof document === "undefined") return;
    const read = () => setDark(isDark());
    read();
    const obs = new MutationObserver(read);
    obs.observe(document.documentElement, {
      attributes: true,
      attributeFilter: ["class", "data-theme"]
    });
    return () => obs.disconnect();
  }, []);
  const C = dark ? {
    card: "#161718",
    cardBorder: "#222325",
    panel: "#1F1F1F",
    soft: "#1B1C1D",
    strong: "#FFFFFF",
    body: "#CACBCE",
    muted: "#AAACB1",
    line: "#222325",
    edge: "#4E5055",
    anchorage: "#90ACF9",
    anchorageSoft: "#131C34",
    chain: "#5FD6E8",
    chainSoft: "#0B2126",
    auto: "#E4B45C",
    autoSoft: "#271C02",
    termBg: "#0F0F10",
    termInk: "#F4F5F5",
    termMuted: "#8B8F94"
  } : {
    card: "#FFFFFF",
    cardBorder: "#E4E5E7",
    panel: "#FFFFFF",
    soft: "#F4F5F5",
    strong: "#000000",
    body: "#4E5055",
    muted: "#6B6E73",
    line: "#E4E5E7",
    edge: "#AAACB1",
    anchorage: "#2E52C8",
    anchorageSoft: "#F5F8FF",
    chain: "#0E7C8D",
    chainSoft: "#F0FAFB",
    auto: "#886107",
    autoSoft: "#FDF8EC",
    termBg: "#141415",
    termInk: "#F4F5F5",
    termMuted: "#9A9DA2"
  };
  const panel = {
    background: C.panel,
    border: "1px solid " + C.cardBorder,
    borderRadius: "14px",
    padding: "16px",
    margin: "1.5rem 0",
    fontFamily: SANS
  };
  const label = {
    fontFamily: MONO,
    fontSize: "11px",
    letterSpacing: "0.04em",
    color: C.muted,
    fontWeight: 600,
    marginBottom: "10px",
    textTransform: "uppercase"
  };
  const legend = {
    marginTop: "10px",
    fontSize: "11.5px",
    lineHeight: 1.6,
    color: C.muted
  };
  const scroller = {
    overflowX: "auto"
  };
  const svgStyle = {
    width: "100%",
    minWidth: "640px",
    height: "auto",
    display: "block"
  };
  const WamArrow = ({id, color}) => <defs>
      <marker id={id} viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
        <path d="M 0 1 L 9 5 L 0 9 z" fill={color} />
      </marker>
    </defs>;
  const WamSwatch = ({color}) => <span style={{
    display: "inline-block",
    width: "8px",
    height: "8px",
    borderRadius: "2px",
    background: color,
    marginRight: "4px"
  }} />;
  const wallet = (x, y, w, h) => <rect x={x} y={y} width={w} height={h} rx="9" fill={C.anchorageSoft} stroke={C.anchorage} strokeWidth="1.5" />;
  const addr = (x, y, w, h, auto) => <rect x={x} y={y} width={w} height={h} rx="9" fill={auto ? C.autoSoft : C.chainSoft} stroke={auto ? C.auto : C.chain} strokeWidth="1.2" strokeDasharray="5 4" />;
  return <div style={panel}>
      <div style={label}>Account-based vs UTXO</div>
      <div style={scroller}>
        <svg viewBox="0 0 1000 300" style={svgStyle} fontFamily={SANS} role="img" aria-label="Left: one Ethereum wallet with one wallet ID maps to exactly one on-chain address. Right: one Bitcoin wallet with one wallet ID maps to three on-chain addresses, one of them generated automatically as change.">
          <WamArrow id="wam-a1" color={C.edge} />

          <text x="0" y="14" fontFamily={MONO} fontSize="9.5" letterSpacing="0.9" fill={C.muted}>ACCOUNT-BASED · ETHEREUM</text>
          {wallet(95, 40, 280, 58)}
          <text x="235" y="65" textAnchor="middle" fontSize="11.5" fontWeight="600" fill={C.strong}>Anchorage Digital wallet</text>
          <text x="235" y="85" textAnchor="middle" fontFamily={MONO} fontSize="11" fill={C.anchorage}>{wamWid("8f3a21")}</text>

          <line x1="235" y1="98" x2="235" y2="150" stroke={C.edge} strokeWidth="1.4" markerEnd="url(#wam-a1)" />
          <text x="245" y="128" fontFamily={MONO} fontSize="9.5" fill={C.muted}>maps to</text>

          {addr(95, 156, 280, 58)}
          <text x="235" y="181" textAnchor="middle" fontFamily={MONO} fontSize="11.5" fill={C.chain}>0xA1b2…9F3c</text>
          <text x="235" y="199" textAnchor="middle" fontSize="10" fill={C.muted}>the only on-chain address</text>

          <text x="235" y="250" textAnchor="middle" fontFamily={MONO} fontSize="12" fontWeight="700" fill={C.anchorage}>1 wallet ID : 1 address</text>
          <text x="235" y="274" textAnchor="middle" fontSize="10.5" fill={C.muted}>A second address means a second wallet, with a second wallet ID.</text>

          <line x1="500" y1="34" x2="500" y2="282" stroke={C.line} strokeWidth="1" />

          <text x="560" y="14" fontFamily={MONO} fontSize="9.5" letterSpacing="0.9" fill={C.muted}>UTXO · BITCOIN</text>
          {wallet(630, 40, 280, 58)}
          <text x="770" y="65" textAnchor="middle" fontSize="11.5" fontWeight="600" fill={C.strong}>Anchorage Digital wallet</text>
          <text x="770" y="85" textAnchor="middle" fontFamily={MONO} fontSize="11" fill={C.anchorage}>{wamWid(WAM_BTC_WID)}</text>

          <path d="M 770 98 L 770 126" stroke={C.edge} strokeWidth="1.4" fill="none" />
          <line x1="640" y1="126" x2="900" y2="126" stroke={C.edge} strokeWidth="1.4" />
          <g stroke={C.edge} strokeWidth="1.4" markerEnd="url(#wam-a1)">
            <line x1="640" y1="126" x2="640" y2="150" />
            <line x1="770" y1="126" x2="770" y2="150" />
            <line x1="900" y1="126" x2="900" y2="150" />
          </g>
          <text x="782" y="118" fontFamily={MONO} fontSize="9.5" fill={C.muted}>maps to</text>

          {addr(578, 156, 124, 58)}
          <text x="640" y="181" textAnchor="middle" fontFamily={MONO} fontSize="10.5" fill={C.chain}>bc1q…4k2p</text>
          <text x="640" y="199" textAnchor="middle" fontSize="10" fill={C.muted}>deposit</text>

          {addr(708, 156, 124, 58)}
          <text x="770" y="181" textAnchor="middle" fontFamily={MONO} fontSize="10.5" fill={C.chain}>bc1q…m7ry</text>
          <text x="770" y="199" textAnchor="middle" fontSize="10" fill={C.muted}>deposit</text>

          {addr(838, 156, 124, 58, true)}
          <text x="900" y="181" textAnchor="middle" fontFamily={MONO} fontSize="10.5" fill={C.auto}>bc1q…s8ez</text>
          <text x="900" y="199" textAnchor="middle" fontSize="10" fill={C.auto}>change, automatic</text>

          <text x="770" y="250" textAnchor="middle" fontFamily={MONO} fontSize="12" fontWeight="700" fill={C.anchorage}>1 wallet ID : n addresses</text>
          <text x="770" y="274" textAnchor="middle" fontSize="10.5" fill={C.muted}>All of them receive, and all of them pool into one balance.</text>
        </svg>
      </div>
      <div style={legend}>
        <WamSwatch color={C.anchorage} />Wallets and wallet IDs.  
        <WamSwatch color={C.chain} />On-chain addresses.  
        <WamSwatch color={C.auto} />Generated for you: a UTXO transfer returns its unspent remainder to a new change address inside the same wallet.
      </div>
    </div>;
};

A wallet at Anchorage Digital isn't necessarily an on-chain address. Sometimes the two line up one to one, sometimes one wallet pools many addresses, and sometimes several wallets sit behind a single address. Knowing which case you're in tells you how many addresses you'll be handing out and how your balances are organized.

It helps to keep two ideas apart. An **on-chain wallet** is a keypair and the address derived from it, and it works on every network that shares its key derivation. An **Anchorage Digital wallet** is where your balances for one network live inside a vault, with its own wallet ID, name, and archive state. For how vaults and wallets fit together, see [Vaults and wallets overview](/knowledge-base/platform/users/vaults-wallets).

## How a wallet maps to addresses

Every wallet has one wallet ID, and that's what the platform works with. Withdrawals and balances always name a wallet. The number of on-chain addresses underneath it depends on the network.

<WalletAddressMap />

On networks like Ethereum, your wallet has a single address and the two are easy to think of as the same thing. On Bitcoin they aren't: you can generate as many addresses as you like, every one of them receives, and they all pool into one balance. Anchorage Digital also adds change addresses for you when you transfer, and those count toward the same balance.

## What one address can hold

A single address holds more than one type of asset. On Ethereum, ETH and every token issued on Ethereum arrive at the same address and sit in the same wallet, each with its own balance.

<AddressAssetTypes />

This is why you can't add a second deposit address to an existing Ethereum wallet. If you want a separate address, create another wallet in the vault and it gets its own. See [Creating and managing wallets](/knowledge-base/platform/users/wallet-creation).

## Two ways to set up compatible networks

Some networks are close enough relatives that one keypair works across all of them. Anchorage Digital supports this on EVM, SPL, and Tendermint networks, and calls them compatible networks. When you create wallets on more than one network in the same family, you have a choice to make.

<CompatibleNetworkOptions />

You make this choice when you create the wallet, and you can extend an existing wallet's address onto more compatible networks later. [Creating and managing wallets](/knowledge-base/platform/users/wallet-creation) walks through both flows.

<Note>
  Sharing an address doesn't share a balance. To move assets from one compatible network to another, they have to be bridged.
</Note>

## Try a configuration

Pick a network, decide how many networks you want to cover, and choose an address strategy. The diagram updates to show the wallets you'd create and the addresses underneath them.

<WalletPlanner />

## Good to know

* The first wallet you create for a network in a vault becomes that vault's default wallet, which is the source of funds for external withdrawals.
* Addresses can't be deleted once generated, because they stay live on the blockchain and can keep receiving deposits.
* Trusted destinations are per network, so the same address on two networks needs two separate entries. See [Trusted destinations](/knowledge-base/platform/users/trusted-destinations).
* On some networks, creating one wallet also creates the wallets for every compatible network and archives them to keep your dashboard tidy. Archived wallets still receive deposits, but unarchive them before staking or withdrawing.
* If a deposit lands on a compatible network where you don't have a wallet yet, we'll create one for you once the deposit clears spam attribution.
* For what each balance label means, see [Reading balances](/knowledge-base/platform/users/reading-balances).


## Related topics

- [Vaults, wallets & addresses](/knowledge-base/porto/vaults-wallets/overview.md)
- [Provision a deposit address for a wallet](/knowledge-base/api-reference/v2/addresses/provision-a-deposit-address-for-a-wallet.md)
- [Mapping wallets to on-chain addresses](/knowledge-base/platform/developers/wallet-address-model.md)
- [Bitcoin address types](/knowledge-base/platform/developers/bitcoin-address-types.md)
