> ## Documentation Index
> Fetch the complete documentation index at: https://seilabs-docs-evm-cookbook.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Sei Improvement Proposals

> Browse every Sei Improvement Proposal (SIP) with status, type, authorship, and section outlines pulled live from the sei-protocol/sips repository.

export const SipIndex = () => {
  const REPO = 'sei-protocol/sips';
  const BRANCH = 'main';
  const LIST_URL = `https://api.github.com/repos/${REPO}/contents/sips?ref=${BRANCH}`;
  const CACHE_KEY = 'sei-sip-index-v1';
  const CACHE_TTL = 3600000;
  const MAX_PROBE = 40;
  const rawUrl = file => `https://raw.githubusercontent.com/${REPO}/${BRANCH}/sips/${file}`;
  const blobUrl = file => `https://github.com/${REPO}/blob/${BRANCH}/sips/${file}`;
  const normKey = key => key.toLowerCase().replace(/[^a-z0-9]/g, '');
  const pick = (meta, ...keys) => {
    for (const key of keys) {
      const value = meta[normKey(key)];
      if (value) return value;
    }
    return '';
  };
  const toPlainText = value => value.replace(/<br\s*\/?>/gi, ', ').replace(/\[([^\]]+)\]\([^)]*\)/g, '$1').replace(/\\([[\]])/g, '$1').replace(/\[[^\]]*@[^\]]*\]/g, '').replace(/`/g, '').replace(/\s+/g, ' ').replace(/\s+,/g, ',').replace(/[,\s]+$/, '').trim();
  const firstUrl = value => {
    const match = value.match(/https?:\/\/[^\s)|]+/);
    return match ? match[0] : '';
  };
  const slugify = text => text.toLowerCase().replace(/[^\p{L}\p{N}_\s-]/gu, '').trim().replace(/\s/g, '-');
  const headingText = markdown => markdown.replace(/\[([^\]]+)\]\([^)]*\)/g, '$1').replace(/\*\*/g, '').replace(/\*/g, '').replace(/`/g, '').trim();
  const parseSip = (file, raw) => {
    const number = Number((file.match(/sip-(\d+)\.md$/i) || [])[1]);
    const meta = Object.create(null);
    const header = raw.split(/^##\s/m)[0];
    for (const line of header.split('\n')) {
      const trimmed = line.trim();
      if (!trimmed.startsWith('|')) continue;
      const cells = trimmed.slice(1).split('|');
      if (cells.length && cells[cells.length - 1].trim() === '') cells.pop();
      if (cells.length < 2) continue;
      const key = cells[0].trim();
      const value = cells.slice(1).join('|').trim();
      if ((/^:?-{2,}:?$/).test(key)) continue;
      if (!key || meta[normKey(key)]) continue;
      meta[normKey(key)] = value;
    }
    const headline = (header.match(/^\s*\*\*SIP[-\s]?\d+:\s*(.+?)\*\*/m) || [])[1];
    const title = toPlainText(headline || pick(meta, 'Title') || file);
    const seen = Object.create(null);
    const sections = [];
    const prose = raw.replace(/^```[\s\S]*?^```/gm, '');
    const headingPattern = /^(#{2,4})\s+(.+?)\s*$/gm;
    let match;
    while ((match = headingPattern.exec(prose)) !== null) {
      const text = headingText(match[2]);
      if (!text) continue;
      let anchor = slugify(text);
      if (seen[anchor] !== undefined) {
        seen[anchor] += 1;
        anchor = `${anchor}-${seen[anchor]}`;
      } else {
        seen[anchor] = 0;
      }
      sections.push({
        level: match[1].length,
        text,
        anchor
      });
    }
    const type = toPlainText(pick(meta, 'Type'));
    const category = toPlainText(pick(meta, 'Category'));
    return {
      number,
      file,
      title,
      description: toPlainText(pick(meta, 'Description')),
      type: type && category && !type.includes(category) ? `${type} (${category})` : type || category,
      status: toPlainText(pick(meta, 'Status')) || 'Unknown',
      author: toPlainText(pick(meta, 'Author', 'Authors')),
      reviewer: toPlainText(pick(meta, 'Reviewer', 'Editor')),
      created: toPlainText(pick(meta, 'Created')),
      discussion: firstUrl(pick(meta, 'Comments', 'Comments-URI', 'CommentsURI')),
      sections
    };
  };
  const [sips, setSips] = useState([]);
  const [state, setState] = useState('loading');
  useEffect(() => {
    let cancelled = false;
    const readCache = () => {
      try {
        const cached = JSON.parse(localStorage.getItem(CACHE_KEY) || 'null');
        if (cached && Date.now() - cached.time < CACHE_TTL && Array.isArray(cached.sips)) {
          return cached.sips;
        }
      } catch {}
      return null;
    };
    const readSip = async file => {
      try {
        const res = await fetch(rawUrl(file));
        if (!res.ok) return null;
        return parseSip(file, await res.text());
      } catch {
        return null;
      }
    };
    const loadFromApi = async () => {
      const res = await fetch(LIST_URL, {
        headers: {
          Accept: 'application/vnd.github+json'
        }
      });
      if (!res.ok) throw new Error(`GitHub API ${res.status}`);
      const files = (await res.json()).filter(entry => entry.type === 'file' && (/^sip-\d+\.md$/i).test(entry.name)).map(entry => entry.name);
      if (!files.length) throw new Error('No SIP files listed');
      const fetched = await Promise.all(files.map(readSip));
      const parsed = fetched.filter(Boolean);
      if (!parsed.length) throw new Error('No SIP files could be read');
      return parsed;
    };
    const loadByProbing = async () => {
      const numbers = Array.from({
        length: MAX_PROBE
      }, (_, i) => i + 1);
      const fetched = await Promise.all(numbers.map(n => readSip(`sip-${n}.md`)));
      const found = fetched.filter(Boolean);
      if (!found.length) throw new Error('No SIPs reachable');
      return found;
    };
    const cached = readCache();
    if (cached) {
      setSips(cached);
      setState('ready');
      return;
    }
    loadFromApi().catch(loadByProbing).then(parsed => {
      if (cancelled) return;
      const ordered = parsed.sort((a, b) => a.number - b.number);
      setSips(ordered);
      setState('ready');
      try {
        localStorage.setItem(CACHE_KEY, JSON.stringify({
          time: Date.now(),
          sips: ordered
        }));
      } catch {}
    }).catch(() => {
      if (cancelled) return;
      setState('error');
    });
    return () => {
      cancelled = true;
    };
  }, []);
  const [isDark, setIsDark] = useState(true);
  useLayoutEffect(() => {
    const root = document.documentElement;
    const sync = () => setIsDark(root.classList.contains('dark'));
    sync();
    const observer = new MutationObserver(sync);
    observer.observe(root, {
      attributes: true,
      attributeFilter: ['class']
    });
    return () => observer.disconnect();
  }, []);
  const byMode = (light, dark) => isDark ? dark : light;
  const theme = {
    cardBg: byMode('var(--sei-card-bg-light)', 'var(--sei-card-bg-dark)'),
    border: byMode('var(--sei-card-border-light)', 'var(--sei-card-border-dark)'),
    strong: byMode('var(--sei-grey-600)', 'var(--sei-white)'),
    body: byMode('var(--sei-grey-300)', 'var(--sei-grey-50)'),
    muted: byMode('var(--sei-grey-200)', 'var(--sei-grey-75)'),
    label: byMode('var(--sei-gold-100)', 'var(--sei-gold-25)'),
    accent: byMode('var(--sei-maroon-100)', 'var(--sei-maroon-25)'),
    hoverBg: byMode('rgba(96, 0, 20, 0.02)', 'rgba(96, 0, 20, 0.08)'),
    hoverBorder: byMode('rgba(96, 0, 20, 0.35)', 'rgba(185, 155, 161, 0.25)')
  };
  const TONES = {
    live: byMode('#1a7a00', '#38df00'),
    error: byMode('#c20a00', '#fa0c00'),
    gold: byMode('#966f22', '#d6c9ac'),
    maroon: byMode('#600014', '#b99ba1'),
    grey: byMode('#666666', '#999999')
  };
  const STATUS_TONES = {
    idea: 'grey',
    draft: 'gold',
    review: 'gold',
    'fast track': 'gold',
    'last call': 'gold',
    final: 'live',
    implemented: 'live',
    activated: 'live',
    living: 'maroon',
    stagnant: 'grey',
    withdrawn: 'error'
  };
  const channels = hex => {
    const n = parseInt(hex.slice(1), 16);
    return `${n >> 16 & 255}, ${n >> 8 & 255}, ${n & 255}`;
  };
  const eyebrow = {
    fontFamily: 'var(--sei-font-mono)',
    fontSize: '10px',
    letterSpacing: '0.04em',
    textTransform: 'uppercase'
  };
  const statusStyle = status => {
    const hex = TONES[STATUS_TONES[status.toLowerCase()] || 'grey'];
    const rgb = channels(hex);
    return {
      ...eyebrow,
      color: hex,
      backgroundColor: `rgba(${rgb}, ${byMode(0.09, 0.14)})`,
      border: `1px solid rgba(${rgb}, ${byMode(0.28, 0.32)})`,
      borderRadius: 'var(--sei-radius-sm)',
      padding: '3px 6px',
      whiteSpace: 'nowrap'
    };
  };
  const cardStyle = {
    background: theme.cardBg,
    border: `1px solid ${theme.border}`,
    borderRadius: 'var(--sei-radius-sm)',
    padding: '20px'
  };
  const buttonStyle = {
    display: 'inline-flex',
    alignItems: 'center',
    gap: '6px',
    padding: '6px 12px',
    fontFamily: 'var(--sei-font-mono)',
    fontSize: '12px',
    letterSpacing: '0.02em',
    color: theme.strong,
    background: 'transparent',
    border: `1px solid ${theme.border}`,
    borderRadius: 'var(--sei-radius-sm)',
    textDecoration: 'none',
    transition: 'background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease'
  };
  const hoverSwap = hovering => event => {
    event.currentTarget.style.backgroundColor = hovering ? theme.hoverBg : 'transparent';
    event.currentTarget.style.borderColor = hovering ? theme.hoverBorder : theme.border;
    event.currentTarget.style.color = hovering ? theme.accent : theme.strong;
  };
  const tintSwap = hovering => event => {
    event.currentTarget.style.color = hovering ? theme.accent : theme.body;
  };
  const ExternalLinkIcon = () => <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
			<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
			<path d="M15 3h6v6" />
			<path d="M10 14 21 3" />
		</svg>;
  const Field = ({label, value}) => value ? <div>
				<div style={{
    ...eyebrow,
    color: theme.label,
    marginBottom: '3px'
  }}>{label}</div>
				<div style={{
    fontSize: '14px',
    color: theme.body
  }}>{value}</div>
			</div> : null;
  const statusMessage = {
    ...cardStyle,
    fontSize: '14px',
    color: theme.body
  };
  if (state === 'loading') {
    return <div className="not-prose" style={statusMessage}>
				Loading proposals from <code style={{
      fontFamily: 'var(--sei-font-mono)'
    }}>{REPO}</code>…
			</div>;
  }
  if (state === 'error') {
    return <div className="not-prose" style={statusMessage}>
				This page could not reach the SIPs repository. Browse the proposals directly at{' '}
				<a href={`https://github.com/${REPO}/tree/${BRANCH}/sips`} target="_blank" rel="noopener noreferrer" style={{
      color: theme.accent
    }}>
					github.com/{REPO}
				</a>
				.
			</div>;
  }
  return <div className="not-prose" style={{
    display: 'flex',
    flexDirection: 'column',
    gap: '16px'
  }}>
			{sips.map(sip => <div key={sip.number} style={cardStyle}>
					<div style={{
    display: 'flex',
    flexWrap: 'wrap',
    alignItems: 'center',
    gap: '8px'
  }}>
						<span style={{
    ...eyebrow,
    fontSize: '11px',
    color: 'var(--sei-white)',
    backgroundColor: 'var(--sei-maroon-100)',
    borderRadius: 'var(--sei-radius-sm)',
    padding: '3px 7px'
  }}>
							SIP-{sip.number}
						</span>
						<span style={statusStyle(sip.status)}>{sip.status}</span>
						{sip.type ? <span style={{
    fontSize: '12px',
    color: theme.muted
  }}>{sip.type}</span> : null}
					</div>

					<h3 style={{
    fontFamily: 'var(--sei-font-display)',
    fontSize: '18px',
    fontWeight: 600,
    letterSpacing: '-0.01em',
    color: theme.strong,
    margin: '14px 0 0'
  }}>
						{sip.title}
					</h3>

					{sip.description ? <p style={{
    fontSize: '14px',
    lineHeight: 1.6,
    color: theme.body,
    margin: '6px 0 0'
  }}>{sip.description}</p> : null}

					<div style={{
    display: 'grid',
    gridTemplateColumns: 'repeat(auto-fit, minmax(150px, 1fr))',
    gap: '12px',
    marginTop: '16px'
  }}>
						<Field label="Author" value={sip.author} />
						<Field label="Reviewer" value={sip.reviewer} />
						<Field label="Created" value={sip.created} />
					</div>

					{}
					{sip.sections.length ? <details style={{
    marginTop: '16px'
  }}>
							<summary style={{
    fontSize: '13px',
    color: theme.body
  }}>
								Contents ({sip.sections.length} sections)
							</summary>
							<ul style={{
    listStyle: 'none',
    margin: 0,
    padding: '0 16px 12px'
  }}>
								{sip.sections.map(section => <li key={section.anchor} style={{
    paddingLeft: `${(section.level - 2) * 16}px`,
    margin: '4px 0'
  }}>
										<a href={`${blobUrl(sip.file)}#${section.anchor}`} target="_blank" rel="noopener noreferrer" style={{
    fontSize: '13px',
    color: theme.body,
    textDecoration: 'none',
    transition: 'color 0.15s ease'
  }} onMouseEnter={tintSwap(true)} onMouseLeave={tintSwap(false)}>
											{section.text}
										</a>
									</li>)}
							</ul>
						</details> : null}

					<div style={{
    display: 'flex',
    flexWrap: 'wrap',
    gap: '8px',
    marginTop: '16px'
  }}>
						<a href={blobUrl(sip.file)} target="_blank" rel="noopener noreferrer" style={buttonStyle} onMouseEnter={hoverSwap(true)} onMouseLeave={hoverSwap(false)}>
							Read SIP-{sip.number} <ExternalLinkIcon />
						</a>
						{sip.discussion ? <a href={sip.discussion} target="_blank" rel="noopener noreferrer" style={buttonStyle} onMouseEnter={hoverSwap(true)} onMouseLeave={hoverSwap(false)}>
								Discussion <ExternalLinkIcon />
							</a> : null}
					</div>
				</div>)}

			<p style={{
    fontSize: '12px',
    color: theme.muted,
    margin: 0
  }}>
				This list reads live data from{' '}
				<a href={`https://github.com/${REPO}/tree/${BRANCH}/sips`} target="_blank" rel="noopener noreferrer" style={{
    color: theme.accent
  }}>
					{REPO}
				</a>
				. Statuses and metadata reflect the {BRANCH} branch.
			</p>
		</div>;
};

A Sei Improvement Proposal (SIP) is a design document for a change to Sei. It might cover a new protocol feature, a change to how the project runs, or a convention for the wider ecosystem. Writing one is how you put an idea in front of the community, and how the reasoning behind a decision is recorded.

Every SIP lives in the [sei-protocol/sips](https://github.com/sei-protocol/sips) repository, and the list below reads from it directly. Titles, statuses, authors, and section outlines come from the source files, not from a copy that can become outdated.

<Info>
  A SIP is not the same as an on-chain governance proposal. The SIP holds the design and the reasoning. The on-chain proposal is the vote that enacts it. One SIP can take several governance proposals to carry out, as SIP-3 did. For the on-chain process, see [Governance](/learn/general-governance) and [Proposals](/learn/proposals).
</Info>

## All proposals

<SipIndex />

## Proposal types

Every SIP declares a type, and the type decides how much community consensus it needs. [SIP-1](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#sip-type) defines all three.

| Type | Scope | Needs consensus |
| - | - | - |
| [Standard](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#standard) | Changes that affect most implementations of Sei, such as consensus, networking, RPC, EVM and CosmWasm behavior, and contract standards. It must also declare a category. | Yes |
| [Process](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#process) | Changes around Sei rather than inside it, such as developer tooling, node and validator procedures, and the SIP process itself. | Yes |
| [Informational](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#informational) | Guidelines or information for the community, with no change to the protocol or development environment. | No |

### Categories

A Standard SIP must also declare one of five [categories](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#sip-category).

| Category | Covers |
| - | - |
| Core | Consensus, execution, storage, and account signatures |
| Networking | Mempool and network protocols |
| Interface | RPC specifications and lower-level naming conventions |
| Framework | EVM and CosmWasm contracts and primitives included in the Sei codebase |
| Application | New EVM or CosmWasm standards and primitives that sit outside the Sei codebase |

## Status lifecycle

A successful SIP usually moves through Draft, Review, Last Call, Final, Implemented, and Activated. Each card above shows the status recorded in that proposal's own source file.

| Status | What it means |
| - | - |
| [Idea](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#idea) | Written, but not yet admitted to the process and not yet numbered. |
| [Draft](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#draft) | An editor has accepted the formatting and assigned a number. The author now gathers community feedback. |
| [Review](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#review) | The author has worked through early feedback. At least three assigned reviewers now give a formal review. |
| [Fast Track](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#fast-track) | For proposals that already reached consensus outside the SIP process. It runs the same way as Review. |
| [Last Call](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#last-call) | A final window for objections, usually at least one week. |
| [Final](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#final) | Accepted, and the specification is now frozen. |
| [Implemented](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#implemented) | Development is complete, but the feature is not yet live on Sei Mainnet. |
| [Activated](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#activated) | Live on Sei Mainnet. |
| [Stagnant](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#stagnant) | Inactive for four weeks while in Draft, Review, or Last Call. |
| [Withdrawn](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#withdrawn) | The author has withdrawn the proposal. |
| [Living](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#living) | A continuously updated proposal that never reaches Final, such as SIP-1 itself. |

<Note>
  After a SIP reaches Final, nobody can withdraw or edit it. To change an accepted specification, submit a new SIP that extends or replaces the original.
</Note>

## Guides for specific proposals

SIP-3 and SIP-4 both affect how you use and build on Sei. These pages cover what they mean in practice.

<CardGroup cols={2}>
  <Card title="SIP-3 migration guide" icon="arrow-right-arrow-left" href="/learn/sip-03-migration">
    What SIP-3 changes for asset holders, and how to move off Cosmos-native addresses.
  </Card>

  <Card title="SIP-3 for exchanges" icon="building-columns" href="/learn/sip-03-exchange-migration">
    Integration changes for exchanges and custodians that support Sei deposits and withdrawals.
  </Card>

  <Card title="Gas and transaction fees" icon="gas-pump" href="/learn/dev-gas">
    How Sei's EIP-1559 implementation works, including the parameters SIP-4 revises.
  </Card>

  <Card title="Cosmos-SDK deprecation" icon="triangle-exclamation" href="/cosmos-sdk">
    Legacy Cosmos SDK and CosmWasm documentation, deprecated under SIP-3.
  </Card>
</CardGroup>

## Submit a proposal

Anyone can author a SIP. Before you write one, discuss the idea with the community to find out whether the proposal is needed at all.

<Steps>
  <Step title="Read SIP-1">
    [SIP-1](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md) defines the process, the header fields your file needs, and what authors and editors are each responsible for.
  </Step>

  <Step title="Raise the idea with the community">
    Open a thread in [GitHub Discussions](https://github.com/sei-protocol/sips/discussions) to collect early feedback, especially from the people who would implement the change.
  </Step>

  <Step title="Fork the repository and add your file">
    Fork [sei-protocol/sips](https://github.com/sei-protocol/sips). In your fork, create your proposal at `sips/sip-temporary_title.md`. Put any images in `assets/sip-temporary_title/`.
  </Step>

  <Step title="Match the required format">
    Start the file with the two-column header table. Follow the section structure described in [SIP format](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#sip-format). Keep the title under 64 characters. Do not end the title with a period.
  </Step>

  <Step title="Open a pull request">
    Submit the pull request from your fork. A [SIP editor](https://github.com/sei-protocol/sips/blob/main/sips/sip-1.md#sip-editor) reviews the formatting, assigns a number, moves the status to Draft, and opens the official comments thread.
  </Step>
</Steps>

<Tip>
  From Draft onward, you are responsible for keeping the proposal moving. An editor helps you find the right people to talk to, but does not push the process forward for you.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.