Files
2025-12-17 01:26:12 +00:00

151 lines
248 KiB
HTML
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper docs-doc-page docs-version-current plugin-docs plugin-id-codex docs-doc-id-raw/codex-block-exchange">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v2.4.1">
<title data-rh="true">CODEX-BLOCK-EXCHANGE | Vac Research</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://vac.dev/codex/raw/codex-block-exchange"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="image" content="https://vac.dev/_og/82c156aed9e368919af1ca7bea00240f41c664f8.png"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-codex-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-codex-current"><meta data-rh="true" property="og:title" content="CODEX-BLOCK-EXCHANGE | Vac Research"><meta data-rh="true" name="description" content="- Status: raw"><meta data-rh="true" property="og:description" content="- Status: raw"><link data-rh="true" rel="icon" href="/theme/image/favicon.ico"><link data-rh="true" rel="canonical" href="https://vac.dev/codex/raw/codex-block-exchange"><link data-rh="true" rel="alternate" href="https://vac.dev/codex/raw/codex-block-exchange" hreflang="en"><link data-rh="true" rel="alternate" href="https://vac.dev/codex/raw/codex-block-exchange" hreflang="x-default"><link rel="alternate icon" type="image/png" href="/theme/image/favicon.png">
<link rel="icon" type="image/svg+xml" href="/theme/image/favicon.svg">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css" integrity="sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM" crossorigin="anonymous"><link rel="stylesheet" href="/assets/css/styles.7f69a75a.css">
<link rel="preload" href="/assets/js/runtime~main.db01e95f.js" as="script">
<link rel="preload" href="/assets/js/main.7bd63d25.js" as="script">
<meta property="og:image" content="https://vac.dev/_og/82c156aed9e368919af1ca7bea00240f41c664f8.png"><meta name="twitter:image" content="https://vac.dev/_og/82c156aed9e368919af1ca7bea00240f41c664f8.png"></head>
<body class="navigation-with-keyboard">
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}return t}()||function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"dark")}()</script><div id="__docusaurus">
<style data-emotion="css-global 3rtehh">.lsd-button{width:auto;cursor:pointer;padding:6px 24px;}.lsd-button--disabled{cursor:default;opacity:0.34;}.lsd-button--large{padding:10px 40px;}.lsd-button--medium{padding:6px 24px;}.lsd-button--small{padding:6px 12px;}.lsd-button:hover:not(.lsd-button--disabled) .lsd-button__text{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-button--with-icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-button__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:100%;}.lsd-button--large.lsd-button--with-icon{padding:10px 0px 10px 18px;}.lsd-button--large.lsd-button--with-icon .lsd-button__icon{width:42px;}.lsd-button--medium.lsd-button--with-icon{padding:6px 0px 6px 14px;}.lsd-button--medium.lsd-button--with-icon .lsd-button__icon{width:38px;}.lsd-button--small.lsd-button--with-icon{padding:6px 0px 6px 12px;}.lsd-button--small.lsd-button--with-icon .lsd-button__icon{width:34px;}.lsd-button--outlined{background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-button--outlined .lsd-button__text{color:rgb(var(--lsd-text-primary));}.lsd-button--filled{background:rgb(var(--lsd-surface-secondary));border:1px solid rgb(var(--lsd-border-primary));}.lsd-button--filled .lsd-button__text{color:rgb(var(--lsd-text-secondary));}</style><style data-emotion="css-global 10bahxd">.lsd-icon-button{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;cursor:pointer;background:none;padding:0;border:1px solid rgb(var(--lsd-border-primary));}.lsd-icon-button--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-icon-button--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-icon-button--disabled{opacity:0.34;cursor:default;}.lsd-icon-button--large{width:40px;height:40px;}.lsd-icon-button--medium{width:32px;height:32px;}.lsd-icon-button--small{width:28px;height:28px;}</style><style data-emotion="css-global icqph9">.lsd-icon-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-icon-button-group--outlined .lsd-icon-button:not(:last-child){border-right:none;}</style><style data-emotion="css-global 1f43ub2">body *{font-family:var(--lsd-typography-generic-font-family);}.lsd-typography{color:rgb(var(--lsd-text-primary));}.lsd-typography--sans-serif,.lsd-typography--sans-serif *{font-family:sans-serif;}.lsd-typography--serif,.lsd-typography--serif *{font-family:serif;}.lsd-typography--monospace,.lsd-typography--monospace *{font-family:monospace;}.lsd-typography--display1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-display1-fontWeight);font-size:var(--lsd-display1-fontSize);line-height:var(--lsd-display1-lineHeight);}.lsd-typography--display2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-display2-fontWeight);font-size:var(--lsd-display2-fontSize);line-height:var(--lsd-display2-lineHeight);}.lsd-typography--display3{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-display3-fontWeight);font-size:var(--lsd-display3-fontSize);line-height:var(--lsd-display3-lineHeight);}.lsd-typography--display4{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-display4-fontWeight);font-size:var(--lsd-display4-fontSize);line-height:var(--lsd-display4-lineHeight);}h1,.lsd-typography--h1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h1-fontWeight);font-size:var(--lsd-h1-fontSize);line-height:var(--lsd-h1-lineHeight);}h2,.lsd-typography--h2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h2-fontWeight);font-size:var(--lsd-h2-fontSize);line-height:var(--lsd-h2-lineHeight);}h3,.lsd-typography--h3{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h3-fontWeight);font-size:var(--lsd-h3-fontSize);line-height:var(--lsd-h3-lineHeight);}h4,.lsd-typography--h4{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h4-fontWeight);font-size:var(--lsd-h4-fontSize);line-height:var(--lsd-h4-lineHeight);}h5,.lsd-typography--h5{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h5-fontWeight);font-size:var(--lsd-h5-fontSize);line-height:var(--lsd-h5-lineHeight);}h6,.lsd-typography--h6{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-h6-fontWeight);font-size:var(--lsd-h6-fontSize);line-height:var(--lsd-h6-lineHeight);}.lsd-typography--subtitle1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-subtitle1-fontWeight);font-size:var(--lsd-subtitle1-fontSize);line-height:var(--lsd-subtitle1-lineHeight);}.lsd-typography--subtitle2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-subtitle2-fontWeight);font-size:var(--lsd-subtitle2-fontSize);line-height:var(--lsd-subtitle2-lineHeight);}.lsd-typography--subtitle3{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-subtitle3-fontWeight);font-size:var(--lsd-subtitle3-fontSize);line-height:var(--lsd-subtitle3-lineHeight);}.lsd-typography--subtitle4{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-subtitle4-fontWeight);font-size:var(--lsd-subtitle4-fontSize);line-height:var(--lsd-subtitle4-lineHeight);}body,.lsd-typography--body1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-body1-fontWeight);font-size:var(--lsd-body1-fontSize);line-height:var(--lsd-body1-lineHeight);}.lsd-typography--body2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-body2-fontWeight);font-size:var(--lsd-body2-fontSize);line-height:var(--lsd-body2-lineHeight);}.lsd-typography--body3{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-body3-fontWeight);font-size:var(--lsd-body3-fontSize);line-height:var(--lsd-body3-lineHeight);}label,.lsd-typography--label1{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-label1-fontWeight);font-size:var(--lsd-label1-fontSize);line-height:var(--lsd-label1-lineHeight);}.lsd-typography--label2{color:rgb(var(--lsd-text-primary));font-weight:var(--lsd-label2-fontWeight);font-size:var(--lsd-label2-fontSize);line-height:var(--lsd-label2-lineHeight);}.lsd-typography--primary{color:rgb(var(--lsd-text-primary));}.lsd-typography--secondary{color:rgb(var(--lsd-text-secondary));}input{color:rgb(var(--lsd-text-primary));font-size:var(--lsd-body1-fontSize);font-weight:var(--lsd-body1-fontWeight);}h1,h2,h3,h4,h5,h6,p,span{margin:0;}</style><style data-emotion="css-global 1yxb6i5">.lsd-icon--primary.lsd-icon--filled,.lsd-icon--primary.lsd-icon--filled *{fill:rgb(var(--lsd-icon-primary));}.lsd-icon--primary $.lsd-icon--stroked,.lsd-icon--primary $.lsd-icon--stroked *{fill:rgb(var(--lsd-icon-primary));}.lsd-icon--secondary.lsd-icon--filled,.lsd-icon--secondary.lsd-icon--filled *{fill:rgb(var(--lsd-icon-secondary));}.lsd-icon--secondary $.lsd-icon--stroked,.lsd-icon--secondary $.lsd-icon--stroked *{fill:rgb(var(--lsd-icon-secondary));}</style><style data-emotion="css-global 1hozxbf">.lsd-tab-item{background:rgb(var(--lsd-surface-primary));border:1px solid transparent;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;}.lsd-tab-item:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-tab-item:not(lsd-tab-item--selected){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-tab-item--text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-tab-item--icon{margin-left:14px;}.lsd-tab-item--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-tab-item--selected:hover{-webkit-text-decoration:none;text-decoration:none;}.lsd-tab-item--with-icon{-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-tab-item--disabled{cursor:default;opacity:0.34;}.lsd-tab-item--disabled:hover{-webkit-text-decoration:none;text-decoration:none;}.lsd-tab-item--small{padding:6px 12px;}.lsd-tab-item--small .lsd-tab-item--icon{margin-left:10px;}.lsd-tab-item--medium{padding:6px 14px;}.lsd-tab-item--medium .lsd-tab-item--icon{margin-left:12px;}.lsd-tab-item--large{padding:10px 18px;}.lsd-tab-item--large .lsd-tab-item--icon{margin-left:14px;}</style><style data-emotion="css-global 1a24j7d">.lsd-tabs{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;overflow:auto;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;max-width:100%;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-tabs>*{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-tabs .lsd-tab-item{border-bottom:none;}.lsd-tabs--full-width{width:100%;-webkit-box-pack:stretch;-ms-flex-pack:stretch;-webkit-justify-content:stretch;justify-content:stretch;}.lsd-tabs--full-width>*{width:100%;-webkit-flex:1 0;-ms-flex:1 0;flex:1 0;}.lsd-tabs{-ms-overflow-style:none;scrollbar-width:none;}.lsd-tabs::-webkit-scrollbar{display:none;}.lsd-tabs__left-scroll-control{left:0;}.lsd-tabs__right-scroll-control{right:0;}.lsd-tabs__right-scroll-control,.lsd-tabs__left-scroll-control{top:0;-webkit-flex:0 1;-ms-flex:0 1;flex:0 1;position:-webkit-sticky;position:sticky;}</style><style data-emotion="css-global 1v7gjjb">.lsd-dropdown-menu{position:absolute;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));overflow:auto;border:1px solid rgb(var(--lsd-border-primary));border-top:0;}.lsd-dropdown-menu>div{border:0;}.lsd-dropdown-menu>div:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-menu--open{opacity:1;visibility:visible;}.lsd-dropdown-menu--large{max-height:220px;}.lsd-dropdown-menu--medium{max-height:176px;}.lsd-dropdown-menu--small{max-height:154px;}</style><style data-emotion="css-global hyd3xb">.lsd-dropdown:not(.lsd-dropdown--disabled):not(
.lsd-dropdown--error
) .lsd-dropdown__trigger:hover .lsd-dropdown__option-label,.lsd-dropdown:not(.lsd-dropdown--disabled):not(
.lsd-dropdown--error
) .lsd-dropdown__trigger:focus .lsd-dropdown__option-label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown__label{display:block;}.lsd-dropdown__button-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-dropdown__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;border:none;cursor:pointer;background:none;}.lsd-dropdown__trigger:focus{outline:none;}.lsd-dropdown__option-label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.lsd-dropdown__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;gap:8px;}.lsd-dropdown__icon{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-dropdown__supporting-text{margin:6px 14px;}.lsd-dropdown--error .lsd-dropdown__option-label{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-dropdown--disabled{opacity:0.34;cursor:initial;}.lsd-dropdown--large{width:208px;}.lsd-dropdown--large.lsd-dropdown--error{width:230px;}.lsd-dropdown--large .lsd-dropdown__label{margin:0 0 6px 18px;}.lsd-dropdown--large .lsd-dropdown__button-container{height:40px;}.lsd-dropdown--large .lsd-dropdown__trigger{padding:10px 0px 10px 18px;}.lsd-dropdown--large .lsd-dropdown__icons{padding:0px 14px;}.lsd-dropdown--medium{width:188px;}.lsd-dropdown--medium.lsd-dropdown--error{width:210px;}.lsd-dropdown--medium .lsd-dropdown__label{margin:0 0 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__button-container{height:32px;}.lsd-dropdown--medium .lsd-dropdown__trigger{padding:6px 0px 6px 14px;}.lsd-dropdown--medium .lsd-dropdown__icons{padding:0px 12px;}.lsd-dropdown--small{width:164px;}.lsd-dropdown--small.lsd-dropdown--error{width:186px;}.lsd-dropdown--small .lsd-dropdown__label{margin:0 0 6px 12px;}.lsd-dropdown--small .lsd-dropdown__button-container{height:28px;}.lsd-dropdown--small .lsd-dropdown__trigger{padding:6px 0px 6px 12px;}.lsd-dropdown--small .lsd-dropdown__icons{padding:0px 10px;}.lsd-dropdown--outlined .lsd-dropdown__button-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown--underlined .lsd-dropdown__button-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global w2g5fy">.lsd-dropdown-item{width:100%;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled){cursor:pointer;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus{outline:none;}.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):hover .lsd-dropdown-item__label,.lsd-dropdown-item:not(.lsd-dropdown-item--disabled):focus .lsd-dropdown-item__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-dropdown-item__label{display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;}.lsd-dropdown-item--disabled{opacity:0.34;}.lsd-dropdown-item__icon{margin-right:18px;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-dropdown-item--small{padding:5px 9px;height:28px;}.lsd-dropdown-item--medium{padding:5px 11px;height:32px;}.lsd-dropdown-item--large{padding:5px 13px;height:40px;}</style><style data-emotion="css-global ww9kgc">.lsd-breadcrumb__list{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;list-style-type:none;margin:0;padding:0;}.lsd-breadcrumb--disabled .lsd-breadcrumb__list{opacity:0.34;cursor:initial;pointer-events:none;}.lsd-breadcrumb__dropdown-menu{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;overflow:auto;border:1px solid rgb(var(--lsd-border-primary));margin-top:10px;position:absolute;width:auto!important;}.lsd-breadcrumb__dropdown-menu>li{cursor:pointer;}.lsd-breadcrumb__dropdown-menu>li:not(:last-child){border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu>li:hover,.lsd-breadcrumb__dropdown-menu>li:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-breadcrumb__dropdown-menu li>a{width:164px;padding:5px 11px;}</style><style data-emotion="css-global 4gvini">.lsd-breadcrumb-item{list-style-type:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-breadcrumb__list>li:not(:last-child)::after{display:inline-block;margin-inline:12px;content:'/';}.lsd-breadcrumb-item__link{-webkit-text-decoration:none;text-decoration:none;cursor:pointer;}.lsd-breadcrumb-item--outlined{padding:3px 11px;border:1px solid rgb(var(--lsd-border-primary));}.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:hover,.lsd-breadcrumb:not(.lsd-breadcrumb--disabled) .lsd-breadcrumb-item__link:focus{-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1cwg3oc">.lsd-card{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-card>.lsd-card-header{margin-bottom:-1px;}</style><style data-emotion="css-global v7d76i">.lsd-card-header{box-sizing:border-box;padding:10px 18px;text-align:center;border:1px solid rgb(var(--lsd-border-primary));}.lsd-card-header__title{overflow:hidden;word-break:break-all;}.lsd-card-header--large{padding:10px 18px;}.lsd-card-header--medium{padding:6px 14px;}.lsd-card-header--small{padding:6px 12px;}</style><style data-emotion="css-global 1txgafh">.lsd-card-body{box-sizing:border-box;padding:14px 22px;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global kzy52c">.lsd-tag{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;border:1px solid rgb(var(--lsd-icon-primary));}.lsd-tag:hover,.lsd-tag:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-tag--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-tag--filled .lsd-tag__label{color:rgb(var(--lsd-text-secondary));}.lsd-tag--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-tag--outlined{color:rgb(var(--lsd-text-primary));}.lsd-tag--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global 4wy0ub">.lsd-text-field{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-text-field__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-text-field--disabled{opacity:0.34;}.lsd-text-field__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-text-field__input:hover{outline:none;}.lsd-text-field__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-text-field--error .lsd-text-field__input{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-text-field__supporting-text{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-text-field--large{width:208px;}.lsd-text-field--large>*{padding:10px 14px 10px 18px;}.lsd-text-field--medium{width:188px;}.lsd-text-field--medium>*{padding:6px 12px 6px 14px;}.lsd-text-field--small{width:164px;}.lsd-text-field--small>*{padding:6px 10px 6px 12px;}.lsd-text-field__label{padding-top:0;padding-bottom:6px;}.lsd-text-field__supporting-text{padding-bottom:0;padding-top:6px;}.lsd-text-field--outlined .lsd-text-field__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field--underlined .lsd-text-field__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-text-field__clear-button{padding:0;width:auto;height:auto;margin:0;border:0;}</style><style data-emotion="css-global uhig7c">.lsd-checkbox{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-checkbox__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-checkbox:not(.lsd-checkbox--disabled):hover,.lsd-checkbox:not(.lsd-checkbox--disabled).lsd-checkbox--focused{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-checkbox:not(.lsd-checkbox--disabled) .lsd-checkbox__input{cursor:pointer;}.lsd-checkbox--disabled{opacity:0.34;}.lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--large .lsd-checkbox__label{margin-left:18px;}.lsd-checkbox--medium .lsd-checkbox__label{margin-left:14px;}.lsd-checkbox--small .lsd-checkbox__label{margin-left:12px;}</style><style data-emotion="css-global txommo">.lsd-autocomplete{box-sizing:border-box;}.lsd-autocomplete__label{display:block;}.lsd-autocomplete__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-autocomplete--disabled{opacity:0.34;}.lsd-autocomplete__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;}.lsd-autocomplete__input:hover{outline:none;}.lsd-autocomplete__input::-webkit-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::-moz-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input:-ms-input-placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__input::placeholder{color:rgb(var(--lsd-text-primary));opacity:0.3;}.lsd-autocomplete__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-autocomplete--error{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-autocomplete--large{width:208px;}.lsd-autocomplete--large .lsd-autocomplete__label{margin:0 0 6px 18px;}.lsd-autocomplete--large .lsd-autocomplete__input-container{height:40px;}.lsd-autocomplete--large .lsd-autocomplete__input{padding:9px 17px;}.lsd-autocomplete--large .lsd-autocomplete__icon{padding:12px 13px;}.lsd-autocomplete--medium{width:188px;}.lsd-autocomplete--medium .lsd-autocomplete__label{margin:0 0 6px 14px;}.lsd-autocomplete--medium .lsd-autocomplete__input-container{height:32px;}.lsd-autocomplete--medium .lsd-autocomplete__input{padding:5px 13px;}.lsd-autocomplete--medium .lsd-autocomplete__icon{padding:8px 11px;}.lsd-autocomplete--small{width:164px;}.lsd-autocomplete--small .lsd-autocomplete__label{margin:0 0 6px 12px;}.lsd-autocomplete--small .lsd-autocomplete__input-container{height:28px;}.lsd-autocomplete--small .lsd-autocomplete__input{padding:5px 11px;}.lsd-autocomplete--small .lsd-autocomplete__icon{padding:6px 9px;}.lsd-autocomplete--outlined .lsd-autocomplete__input-container{border:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete--underlined .lsd-autocomplete__input-container{border:1px solid transparent;border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-autocomplete__dropdown-item-placeholder{opacity:0.5;white-space:pre;}</style><style data-emotion="css-global quxxm6">.lsd-quote{color:rgb(var(--lsd-text-primary));white-space:pre-wrap;}.lsd-quote--indented-inline{border-left:1px solid rgb(var(--lsd-border-primary));padding:4px 8px 4px 28px;}.lsd-quote--parentheses{padding:0px;text-align:center;}.lsd-quote--parentheses::before{content:'***';}.lsd-quote--parentheses::after{content:'***';}</style><style data-emotion="css-global a49t4h">.lsd-collapse{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-collapse--open .lsd-collapse__content{border-top:1px solid transparent;}.lsd-collapse__content{border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 12ppw0q">.lsd-collapse-header{box-sizing:border-box;}.lsd-collapse-header:not(.lsd-collapse-header--disabled) .lsd-collapse-header__trigger:hover .lsd-collapse-header__label{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-collapse-header__trigger{width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;cursor:pointer;background:none;border:1px solid rgb(var(--lsd-border-primary));}.lsd-collapse-header__trigger:focus{outline:none;}.lsd-collapse-header__label{cursor:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin:auto;}.lsd-collapse-header__icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;}.lsd-collapse-header__icon{margin-right:8px;}.lsd-collapse-header--disabled .lsd-collapse-header__trigger{opacity:0.34;cursor:initial;}.lsd-collapse-header--large .lsd-collapse-header__trigger{width:299px;height:40px;padding:9px 17px;}.lsd-collapse-header--medium .lsd-collapse-header__trigger{width:270px;height:32px;padding:5px 13px;}.lsd-collapse-header--small .lsd-collapse-header__trigger{width:235px;height:28px;padding:5px 11px;}</style><style data-emotion="css-global dixc0i">.lsd-checkbox-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-checkbox-group__label{margin-bottom:6px;}</style><style data-emotion="css-global q2n2hz">.lsd-badge{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;border:1px solid rgb(var(--lsd-icon-primary));border-radius:20px;}.lsd-badge:hover,.lsd-badge:focus{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.lsd-badge--large{padding:3px 11px;gap:12px;height:28px;}.lsd-badge--small{padding:3px 7px;gap:8px;height:24px;}.lsd-badge--filled{background-color:rgb(var(--lsd-icon-primary));}.lsd-badge--filled .lsd-badge__label{color:rgb(var(--lsd-text-secondary));}.lsd-badge--filled svg{--lsd-icon-primary:var(--lsd-icon-secondary);}.lsd-badge--outlined{color:rgb(var(--lsd-text-primary));}.lsd-badge--disabled{opacity:0.3;cursor:initial;pointer-events:none;}</style><style data-emotion="css-global rlst54">.lsd-radio-button{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-radio-button__input{opacity:0;position:absolute;left:0;top:0;padding:0;margin:0;width:100%;height:100%;}.lsd-radio-button:not(.lsd-radio-button--disabled):hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-radio-button:not(.lsd-radio-button--disabled) .lsd-radio-button__input{cursor:pointer;}.lsd-radio-button--disabled{opacity:0.34;}.lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--large .lsd-radio-button__label{margin-left:18px;}.lsd-radio-button--medium .lsd-radio-button__label{margin-left:14px;}.lsd-radio-button--small .lsd-radio-button__label{margin-left:12px;}</style><style data-emotion="css-global mo7h6o">.lsd-radio-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:6px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-radio-button-group__label{margin-bottom:6px;}</style><style data-emotion="css-global amncrr">.lsd-table{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-table>.lsd-table-header{margin-bottom:-1px;}</style><style data-emotion="css-global 1fkbozr">.lsd-table-header{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 1fb1r54">.lsd-table-body table{border-collapse:collapse;text-align:center;table-layout:fixed;width:100%;height:auto;}.lsd-table-body table tr:first-of-type td label:has(input[type='radio']){display:none;}.lsd-table-body__toolbar{box-sizing:border-box;padding:10px;border:1px solid rgb(var(--lsd-border-primary));border-bottom:none;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}</style><style data-emotion="css-global 607rj8">.lsd-table-item{border:1px solid rgb(var(--lsd-border-primary));}.lsd-table-item:has(> label){width:40px;}.lsd-table-item:has(> label) input{position:relative;width:14px;height:14px;margin:auto;}.lsd-table-item:has(> label) span{margin-left:14px!important;}.lsd-table-item--large{padding:10px;}.lsd-table-item--medium{padding:6px 8px;}.lsd-table-item--small{padding:6px;}</style><style data-emotion="css-global 1vlh57l">.lsd-table-row{-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}</style><style data-emotion="css-global 1fw5y3v">.lsd-number-input{width:auto;box-sizing:border-box;}.lsd-number-input__main-container:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-number-input--error .lsd-number-input__main-container{-webkit-text-decoration:line-through;text-decoration:line-through;}.lsd-number-input__label{display:block;}.lsd-number-input__plus-minus-icons{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-number-input__input-container{box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));border-left:0px;border-right:0px;}.lsd-number-input__error-icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:10px 8px;}.lsd-number-input__input-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-number-input--disabled{opacity:0.34;}.lsd-number-input__main-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-number-input__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;text-align:center;padding:0 4px;}.lsd-number-input__input::-webkit-inner-spin-button{display:none;-webkit-appearance:none;}.lsd-number-input__input:hover{outline:none;}.lsd-number-input__supporting-text{position:absolute;}.lsd-number-input--large .lsd-number-input__label{margin:0 0 6px 18px;}.lsd-number-input--large .lsd-number-input__input-container{height:40px;}.lsd-number-input--large .lsd-number-input__input{width:62px;}.lsd-number-input--large .lsd-number-input__plus-minus-icons{height:40px;width:40px;}.lsd-number-input--large .lsd-number-input__supporting-text{margin:6px 18px 0 18px;}.lsd-number-input--medium .lsd-number-input__label{margin:0 0 6px 14px;}.lsd-number-input--medium .lsd-number-input__input-container{height:32px;}.lsd-number-input--medium .lsd-number-input__input{width:58px;}.lsd-number-input--medium .lsd-number-input__plus-minus-icons{height:32px;width:32px;}.lsd-number-input--medium .lsd-number-input__supporting-text{margin:6px 14px 0 14px;}.lsd-number-input--small .lsd-number-input__label{margin:0 0 6px 12px;}.lsd-number-input--small .lsd-number-input__input-container{height:28px;}.lsd-number-input--small .lsd-number-input__input{width:50px;}.lsd-number-input--small .lsd-number-input__plus-minus-icons{height:28px;width:28px;}.lsd-number-input--small .lsd-number-input__supporting-text{margin:6px 12px 0 12px;}</style><style data-emotion="css-global 12rmo7o">.lsd-modal{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0, 0, 0, 0.5);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;z-index:9999;}.lsd-modal__container{position:relative;background:rgb(var(--lsd-surface-primary));padding:20px;max-width:90%;box-sizing:border-box;border:1px solid rgb(var(--lsd-border-primary));}.lsd-modal__header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-modal__close-icon{position:absolute;top:8px;right:8px;cursor:pointer;}.lsd-modal__title-and-subtitle-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}.lsd-modal--large .lsd-modal__container{min-width:960px;}.lsd-modal--medium .lsd-modal__container{min-width:768px;}.lsd-modal--small .lsd-modal__container{min-width:614px;}.lsd-modal--extra-small .lsd-modal__container{min-width:490px;}</style><style data-emotion="css-global 1k7gzc">.lsd-modal-footer{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}</style><style data-emotion="css-global 1b9t8so">.lsd-modal-body{margin:18px 0;}</style><style data-emotion="css-global dyud2a">.lsd-date-picker{width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker--large .lsd-date-field--large{width:318px;}.lsd-date-picker--medium .lsd-date-field--medium{width:290px;}.lsd-date-picker--small .lsd-date-field--small{width:262px;}</style><style data-emotion="css-global olq3nk">.lsd-date-field{width:auto;box-sizing:border-box;}.lsd-date-field__label{display:block;}.lsd-date-field__input-container__icon{position:absolute;right:0;cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background-color:rgb(var(--lsd-surface-primary));}.lsd-date-field__input-container__icon:focus{background:blue;background-color:pink;border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container__no-icon{position:absolute;right:0;background-color:rgb(var(--lsd-surface-primary));padding:12px;}.lsd-date-field--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field--underlined{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-field__input-container{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-date-field--disabled{opacity:0.34;}.lsd-date-field__input-container__input{border:none;outline:none;font-size:14px;color:rgb(var(--lsd-text-primary));background:none;width:100%;opacity:0.4;-webkit-transition:opacity 0.2s ease-in-out;transition:opacity 0.2s ease-in-out;}.lsd-date-field__input-container__input::-webkit-inner-spin-button,.lsd-date-field__input-container__input::-webkit-calendar-picker-indicator{display:none;-webkit-appearance:none;}.lsd-date-field__input-container__input:hover{outline:none;}.lsd-date-field__supporting-text{position:absolute;}.lsd-date-field--large{width:208px;}.lsd-date-field--large .lsd-date-field__label{margin:0 0 6px 18px;}.lsd-date-field--large .lsd-date-field__input-container{height:40px;}.lsd-date-field--large .lsd-date-field__input-container__input{padding:9px 0px 9px 17px;}.lsd-date-field--large .lsd-date-field__input-container__icon{padding:12px 13px;}.lsd-date-field--large .lsd-date-field__supporting-text{margin:6px 18px 0 18px;}.lsd-date-field--medium{width:188px;}.lsd-date-field--medium .lsd-date-field__label{margin:0 0 6px 14px;}.lsd-date-field--medium .lsd-date-field__input-container{height:32px;}.lsd-date-field--medium .lsd-date-field__input-container__input{padding:5px 11px 5px 13px;}.lsd-date-field--medium .lsd-date-field__input-container__icon{padding:8px 11px;}.lsd-date-field--medium .lsd-date-field__supporting-text{margin:6px 14px 0 14px;}.lsd-date-field--small{width:164px;}.lsd-date-field--small .lsd-date-field__label{margin:0 0 6px 12px;}.lsd-date-field--small .lsd-date-field__input-container{height:28px;}.lsd-date-field--small .lsd-date-field__input-container__input{padding:5px 9px 5px 11px;font-size:12px;}.lsd-date-field--small .lsd-date-field__input-container__icon{padding:6px 9px;}.lsd-date-field--small .lsd-date-field__supporting-text{margin:6px 12px 0 12px;}.lsd-date-field__input-container__input:invalid,.lsd-date-field__input-container__input--filled{color:rgb(var(--lsd-border-primary));opacity:1;}.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-year-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-month-field,.lsd-date-field--error .lsd-date-field__input-container__input::-webkit-datetime-edit-day-field{-webkit-text-decoration:line-through;text-decoration:line-through;}@supports not selector(::-webkit-datetime-edit-day-field){.lsd-date-field--error .lsd-date-field__input-container__input{-webkit-text-decoration:line-through;text-decoration:line-through;}}</style><style data-emotion="css-global 1gjtao4">.lsd-calendar{border:1px solid rgb(var(--lsd-border-primary));visibility:hidden;position:absolute!important;top:0;left:0;opacity:0;visibility:hidden;margin:0;padding:0;box-sizing:border-box;background:rgb(var(--lsd-surface-primary));-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.lsd-calendar-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;padding:8px;}.lsd-calendar--open{opacity:1;visibility:visible;}.lsd-calendar-header{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;height:32px;margin-bottom:8px;}.lsd-calendar__week_day{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;aspect-ratio:1/1;margin-bottom:4px;}.lsd-calendar__change-year{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:2px 0xp 2px 8px;gap:6px;border:1px solid transparent;}.lsd-calendar__change-year--active .lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__change-year-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border:none;}.lsd-calendar-month{margin-right:8px;}.lsd-calendar__month-and-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}.lsd-calendar-day__container{cursor:pointer;background:transparent;position:relative;box-sizing:border-box;border:1px solid transparent;}.lsd-calendar-day{aspect-ratio:1/1;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}.lsd-calendar-day:hover{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline;text-decoration-color:rgb(var(--lsd-border-primary));}.lsd-calendar-day label:hover{cursor:pointer;}.lsd-calendar-day--selected{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar-day--disabled{opacity:0.3;cursor:default;}.lsd-calendar-day__today_indicator{position:absolute;left:50%;-webkit-transform:translateX(-50%);-moz-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);bottom:2px;}.lsd-calendar--disabled{pointer-events:none;border:1px solid rgba(var(--lsd-border-primary), 0.3);}.lsd-calendar--disabled label{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar__button{opacity:0.3;}.lsd-calendar--disabled .lsd-calendar-day--selected{opacity:0.3;}.lsd-calendar__button{border:1px solid rgb(var(--lsd-border-primary));cursor:pointer;background:transparent;width:32px;height:32px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;position:absolute;}.lsd-calendar__next-month-button{top:8px;right:8px;}.lsd-calendar__previous-month-button{top:8px;left:8px;}.lsd-calendar-day--border-left{border-left:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-right{border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-left-and-right{border-left:1px double rgb(var(--lsd-border-primary));border-right:1px double rgb(var(--lsd-border-primary));}.lsd-calendar-day--border-top-and-bottom{border-top:1px double rgb(var(--lsd-border-primary));border-bottom:1px double rgb(var(--lsd-border-primary));}.lsd-calendar__month-table{border-collapse:collapse;}.lsd-calendar__year-dropdown{box-sizing:border-box;position:absolute;top:100%;left:0;max-height:200px;overflow-y:auto;width:100%;border:1px solid rgb(var(--lsd-border-primary));border-top:none;z-index:1;}.lsd-calendar__year-dropdown .lsd-calendar-year{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar__year-dropdown--hidden{visibility:hidden;}.lsd-calendar-year{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;cursor:pointer;-webkit-transition:background-color 0.2s;transition:background-color 0.2s;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));}.lsd-calendar-year:hover{-webkit-text-decoration:underline;text-decoration:underline;}.lsd-calendar__year-and-icon{border:1px solid rgb(var(--lsd-border-primary));}.lsd-calendar--large .lsd-calendar-year{padding:6px 0px 6px 14px;}.lsd-calendar--large .lsd-calendar__change-year-icon-container{width:32px;}.lsd-calendar--medium .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--medium .lsd-calendar__change-year-icon-container{width:28px;}.lsd-calendar--small .lsd-calendar-year{padding:6px 0px 6px 12px;}.lsd-calendar--small .lsd-calendar__change-year-icon-container{width:28px;}</style><style data-emotion="css-global dlrd7d">.lsd-toast{box-sizing:border-box;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;background:rgb(var(--lsd-surface-primary));border:1px solid rgb(var(--lsd-border-primary));padding:8px;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;}.lsd-toast__inline-button-container{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;}.lsd-toast__column-button-container{margin-top:18px;margin-bottom:6px;}.lsd-toast__inline-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}.lsd-toast__column-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:justify;-webkit-justify-content:space-between;justify-content:space-between;}.lsd-toast__text-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;color:rgb(var(--lsd-text-secondary));padding-left:12px;}.lsd-toast__title{position:relative;}.lsd-toast__information{margin-top:4px;}.lsd-toast__button-container{min-height:28px;min-width:60px;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;padding:0px 12px;}.lsd-toast__close-button{margin-bottom:auto;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;height:28px;width:28px;margin-left:auto;}.lsd-toast__column-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;margin-bottom:auto;position:relative;top:4px;padding-left:4px;}.lsd-toast__inline-icon-container{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;padding-left:4px;}.lsd-toast__icon{position:relative;}.lsd-toast--large{width:364px;}.lsd-toast--medium{width:336px;}.lsd-toast--small{width:296px;}.lsd-toast--small .lsd-toast__icon{top:0px;}</style><style data-emotion="css-global 5wlfwk">.lsd-toast-provider__toast-container{position:fixed;-webkit-transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);transition:all 230ms cubic-bezier(0.21, 1.02, 0.73, 1);z-index:9999;}.lsd-toast-provider__toast--top-left,.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--top-right{top:0;}.lsd-toast-provider__toast--bottom-left,.lsd-toast-provider__toast--bottom-center,.lsd-toast-provider__toast--bottom-right{bottom:0;}.lsd-toast-provider__toast--top-center,.lsd-toast-provider__toast--bottom-center{left:50%;}.lsd-toast-provider__toast--top-right,.lsd-toast-provider__toast--bottom-right{right:0;}</style><style data-emotion="css-global 9yw6e1">.lsd-button-group{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;}.lsd-button-group >*:not(:last-child).lsd-button--outlined,.lsd-button-group >*:not(:last-child) .lsd-button--outlined{border-right:none;}</style><style data-emotion="css-global 17u9w7w">.lsd-date-range-picker{box-sizing:border-box;}.lsd-date-range-picker .lsd-date-field--outlined{border:none;}.lsd-date-range-picker .lsd-date-field__input-container__icon{padding:8px;}.lsd-date-range-picker__label{display:block;}.lsd-date-range-picker__input-container{box-sizing:border-box;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:1px solid transparent;}.lsd-date-picker__calendar{border-top:none!important;}.lsd-date-picker__calendar .lsd-tooltip-base__arrow-tip{-webkit-transition:left 0.2s ease-in-out;transition:left 0.2s ease-in-out;}.lsd-date-range-picker--calendar-open .lsd-date-range-picker__input-container{border-bottom:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker__icon{cursor:pointer;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;padding:0 10px;}.lsd-date-range-picker--disabled{opacity:0.3;}.lsd-date-range-picker__supporting-text{position:absolute;}.lsd-date-range-picker--large{width:318px;}.lsd-date-range-picker--large .lsd-date-field--large{width:156px;}.lsd-date-range-picker--large .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--large .lsd-date-field__input-container__icon{padding:11px 12px;}.lsd-date-range-picker--large .lsd-date-range-picker__label{margin:0 0 6px 18px;}.lsd-date-range-picker--large .lsd-date-range-picker__input-container{height:40px;}.lsd-date-range-picker--large .lsd-date-range-picker__supporting-text{margin:6px 18px 0 18px;}.lsd-date-range-picker--medium{width:290px;}.lsd-date-range-picker--medium .lsd-date-field--medium{width:142px;}.lsd-date-range-picker--medium .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--medium .lsd-date-field__input-container__icon{padding:7px 8px;}.lsd-date-range-picker--medium .lsd-date-range-picker__label{margin:0 0 6px 14px;}.lsd-date-range-picker--medium .lsd-date-range-picker__input-container{height:32px;}.lsd-date-range-picker--medium .lsd-date-range-picker__supporting-text{margin:6px 14px 0 14px;}.lsd-date-range-picker--small{width:262px;}.lsd-date-range-picker--small .lsd-date-field--small{width:128px;}.lsd-date-range-picker--small .lsd-date-field__input-container__input{padding-right:0;}.lsd-date-range-picker--small .lsd-date-field__input-container__icon{padding:5px 7px;}.lsd-date-range-picker--small .lsd-date-range-picker__label{margin:0 0 6px 12px;}.lsd-date-range-picker--small .lsd-date-range-picker__input-container{height:28px;}.lsd-date-range-picker--small .lsd-date-range-picker__supporting-text{margin:6px 12px 0 12px;}.lsd-date-range-picker__separator{margin-left:3px;width:1px;height:100%;}.lsd-date-range-picker__separator{border-left:1px solid transparent;}.lsd-date-range-picker--outlined{border:1px solid rgb(var(--lsd-border-primary));}.lsd-date-range-picker--outlined .lsd-date-range-picker__separator{border-left:1px solid rgb(var(--lsd-border-primary));}</style><style data-emotion="css-global 19d282h">.lsd-tooltip-base{border:1px solid rgb(var(--lsd-border-primary));position:relative;}.lsd-tooltip-base__arrow-tip{border:1px solid rgb(var(--lsd-border-primary));position:absolute;background:rgb(var(--lsd-surface-primary));}.lsd-tooltip-base__content{background:rgb(var(--lsd-surface-primary));width:100%;height:100%;position:relative;z-index:1;}</style><style data-emotion="css-global js1ujt">html:not([data-theme]){--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}html[data-theme='light']{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:0,0,0;--lsd-theme-secondary:255,255,255;--lsd-surface-primary:255,255,255;--lsd-surface-secondary:0,0,0;--lsd-border-primary:0,0,0;--lsd-border-secondary:255,255,255;--lsd-icon-primary:0,0,0;--lsd-icon-secondary:255,255,255;--lsd-text-primary:0,0,0;--lsd-text-secondary:255,255,255;--lsd-text-tertiary:0,0,0,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}html[data-theme='dark']{--lsd-display1-fontSize:5.5rem;--lsd-display1-fontWeight:normal;--lsd-display1-lineHeight:6rem;--lsd-display2-fontSize:4rem;--lsd-display2-fontWeight:normal;--lsd-display2-lineHeight:4.5rem;--lsd-display3-fontSize:3.5rem;--lsd-display3-fontWeight:normal;--lsd-display3-lineHeight:4rem;--lsd-display4-fontSize:3rem;--lsd-display4-fontWeight:normal;--lsd-display4-lineHeight:3.5rem;--lsd-h1-fontSize:2.5rem;--lsd-h1-fontWeight:normal;--lsd-h1-lineHeight:3rem;--lsd-h2-fontSize:2rem;--lsd-h2-fontWeight:normal;--lsd-h2-lineHeight:2.5rem;--lsd-h3-fontSize:1.75rem;--lsd-h3-fontWeight:normal;--lsd-h3-lineHeight:2.25rem;--lsd-h4-fontSize:1.5rem;--lsd-h4-fontWeight:normal;--lsd-h4-lineHeight:2rem;--lsd-h5-fontSize:1.25rem;--lsd-h5-fontWeight:normal;--lsd-h5-lineHeight:1.75rem;--lsd-h6-fontSize:1rem;--lsd-h6-fontWeight:normal;--lsd-h6-lineHeight:1.5rem;--lsd-subtitle1-fontSize:1.125rem;--lsd-subtitle1-fontWeight:normal;--lsd-subtitle1-lineHeight:1.5rem;--lsd-subtitle2-fontSize:1rem;--lsd-subtitle2-fontWeight:normal;--lsd-subtitle2-lineHeight:1.5rem;--lsd-subtitle3-fontSize:0.875rem;--lsd-subtitle3-fontWeight:normal;--lsd-subtitle3-lineHeight:1.25rem;--lsd-subtitle4-fontSize:0.75rem;--lsd-subtitle4-fontWeight:normal;--lsd-subtitle4-lineHeight:1rem;--lsd-body1-fontSize:1rem;--lsd-body1-fontWeight:normal;--lsd-body1-lineHeight:1.5rem;--lsd-body2-fontSize:0.875rem;--lsd-body2-fontWeight:normal;--lsd-body2-lineHeight:1.25rem;--lsd-body3-fontSize:0.75rem;--lsd-body3-fontWeight:normal;--lsd-body3-lineHeight:1rem;--lsd-label1-fontSize:0.875rem;--lsd-label1-fontWeight:normal;--lsd-label1-lineHeight:1.25rem;--lsd-label2-fontSize:0.75rem;--lsd-label2-fontWeight:normal;--lsd-label2-lineHeight:1rem;--lsd-typography-generic-font-family:sans-serif;--lsd-theme-primary:255,255,255;--lsd-theme-secondary:0,0,0;--lsd-surface-primary:0,0,0;--lsd-surface-secondary:255,255,255;--lsd-border-primary:255,255,255;--lsd-border-secondary:0,0,0;--lsd-icon-primary:255,255,255;--lsd-icon-secondary:0,0,0;--lsd-text-primary:255,255,255;--lsd-text-secondary:0,0,0;--lsd-text-tertiary:255,255,255,0.34;--lsd-spacing-4:4px;--lsd-spacing-8:8px;--lsd-spacing-16:16px;--lsd-spacing-24:24px;--lsd-spacing-32:32px;--lsd-spacing-40:40px;--lsd-spacing-64:64px;--lsd-spacing-80:80px;--lsd-spacing-96:96px;--lsd-spacing-120:120px;}</style><div class="root_QACb"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_OoEf"><div class="navbar__inner"><div class="navbar__left"><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--light_BL8e" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--dark_OvIx" height="26"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__left-items"></div><div class="navbar__right-items"><div class="iconButtonGroup_ktNv lsd-icon-button-group lsd-icon-button-group--medium lsd-icon-button-group--outlined"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><aside class="theme-doc-sidebar-container docSidebarContainer_b6E3"><div class="sidebarViewport_Xe31"><div class="sidebar_UEyd sidebarWithHideableNavbar__00c"><a tabindex="-1" class="sidebarLogo_Ydl9" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--light_BL8e" height="26"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--dark_OvIx" height="26"><b></b></a><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_NjKY"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/codex/">Codex RFCs</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--active" aria-expanded="true" href="/codex/raw/codex-block-exchange"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="chevron_How5 lsd-icon lsd-icon--small lsd-icon--filled"><path d="M3.5 8.33875L4.3225 9.16125L7 6.48959L9.6775 9.16125L10.5 8.33875L7 4.83875L3.5 8.33875Z" fill="black"></path></svg><span class="lsd-typography lsd-typography--body2 lsd-typography--primary">raw</span></a></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/codex/raw/codex-block-exchange">CODEX-BLOCK-EXCHANGE</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/codex/raw/codex-marketplace">CODEX-MARKETPLACE</a></li></ul></li></ul></nav></div></div></aside><main class="docMainContainer_gTbr"><div class="container padding-top--md padding-bottom--lg"><div class="row docItemGrid_SzoZ"><div class="docItemCol_F52z"><div class="docItemContainer_hrrU"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_RLvU" aria-label="Breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><a class="breadcrumbs__item" href="/codex"><span class="lsd-typography lsd-typography--body3">Home</span></a><li class="breadcrumbs__item"><span class="lsd-typography lsd-typography--body3 breadcrumbs__link">raw</span><meta itemprop="position" content="1"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="lsd-typography lsd-typography--body3 breadcrumbs__link" itemprop="name">CODEX-BLOCK-EXCHANGE</span><meta itemprop="position" content="2"></li></ul></nav><div class="theme-doc-markdown markdown"><header><h1>CODEX-BLOCK-EXCHANGE</h1><div class="tocMobile_imaF"><div class="tocCollapsible_ROek theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_dxRj"><div></div><span class="lsd-typography lsd-typography--body2">On this page</span><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" class="lsd-icon lsd-icon--small lsd-icon--filled"><path d="M10.5 5.66125L9.6775 4.83875L7 7.51041L4.3225 4.83874L3.5 5.66125L7 9.16125L10.5 5.66125Z" fill="black"></path></svg></button></div></div></header><ul><li>Status: raw</li><li>Category: Standards Track</li><li>Editor: Codex Team</li><li>Contributors:<ul><li>Filip Dimitrijevic &lt;<a href="mailto:filip@status.im" target="_blank" rel="noopener noreferrer">filip@status.im</a>&gt;</li></ul></li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="specification-status">Specification Status<a href="#specification-status" class="hash-link" aria-label="Direct link to Specification Status" title="Direct link to Specification Status"></a></h2><p>This specification contains a mix of:</p><ul><li><strong>Verified protocol elements</strong>: Core message formats, protobuf structures, and addressing modes confirmed from implementation</li><li><strong>Design specifications</strong>: Payment flows, state machines, and negotiation strategies representing intended behavior</li><li><strong>Recommended values</strong>: Protocol limits and timeouts that serve as guidelines (actual implementations may vary)</li><li><strong>Pending verification</strong>: Some technical details (e.g., multicodec 0xCD02) require further validation</li></ul><p>Sections marked with notes indicate areas where implementation details may differ from this specification.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="abstract">Abstract<a href="#abstract" class="hash-link" aria-label="Direct link to Abstract" title="Direct link to Abstract"></a></h2><p>The Block Exchange (BE) is a core Codex component responsible for
peer-to-peer content distribution across the network.
It manages the sending and receiving of data blocks between nodes,
enabling efficient data sharing and retrieval.
This specification defines both an internal service interface and a
network protocol for referring to and providing data blocks.
Blocks are uniquely identifiable by means of an address and represent
fixed-length chunks of arbitrary data.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="semantics">Semantics<a href="#semantics" class="hash-link" aria-label="Direct link to Semantics" title="Direct link to Semantics"></a></h2><p>The keywords &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;,
&quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this
document are to be interpreted as described in
<a href="https://www.ietf.org/rfc/rfc2119.txt" target="_blank" rel="noopener noreferrer">RFC 2119</a>.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="definitions">Definitions<a href="#definitions" class="hash-link" aria-label="Direct link to Definitions" title="Direct link to Definitions"></a></h3><table><thead><tr><th>Term</th><th>Description</th></tr></thead><tbody><tr><td><strong>Block</strong></td><td>Fixed-length chunk of arbitrary data, uniquely identifiable</td></tr><tr><td><strong>Standalone Block</strong></td><td>Self-contained block addressed by SHA256 hash (CID)</td></tr><tr><td><strong>Dataset Block</strong></td><td>Block in ordered set, addressed by dataset CID + index</td></tr><tr><td><strong>Block Address</strong></td><td>Unique identifier for standalone/dataset addressing</td></tr><tr><td><strong>WantList</strong></td><td>List of block requests sent by a peer</td></tr><tr><td><strong>Block Delivery</strong></td><td>Transmission of block data from one peer to another</td></tr><tr><td><strong>Block Presence</strong></td><td>Indicator of whether peer has requested block</td></tr><tr><td><strong>Merkle Proof</strong></td><td>Proof verifying dataset block position correctness</td></tr><tr><td><strong>CodexProof</strong></td><td>Codex-specific Merkle proof format verifying a block&#x27;s position within a dataset tree</td></tr><tr><td><strong>Stream</strong></td><td>Bidirectional libp2p communication channel between two peers for exchanging messages</td></tr><tr><td><strong>Peer Context Store</strong></td><td>Internal data structure tracking active peer connections, their WantLists, and exchange state</td></tr><tr><td><strong>CID</strong></td><td>Content Identifier - hash-based identifier for content</td></tr><tr><td><strong>Multicodec</strong></td><td>Self-describing format identifier for data encoding</td></tr><tr><td><strong>Multihash</strong></td><td>Self-describing hash format</td></tr></tbody></table><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="motivation">Motivation<a href="#motivation" class="hash-link" aria-label="Direct link to Motivation" title="Direct link to Motivation"></a></h2><p>The Block Exchange module serves as the fundamental layer for content
distribution in the Codex network.
It provides primitives for requesting and delivering blocks of data
between peers, supporting both standalone blocks and blocks that are
part of larger datasets.
The protocol is designed to work over libp2p streams and integrates
with Codex&#x27;s discovery, storage, and payment systems.</p><p>When a peer wishes to obtain a block, it registers its unique address
with the Block Exchange, and the Block Exchange will then be in charge
of procuring it by finding a peer that has the block, if any, and then
downloading it.
The Block Exchange will also accept requests from peers which might
want blocks that the node has, and provide them.</p><p><strong>Discovery Separation:</strong> Throughout this specification we assume that
if a peer wants a block, then the peer has the means to locate and
connect to peers which either: (1) have the block; or (2) are
reasonably expected to obtain the block in the future.
In practical implementations, the Block Exchange will typically require
the support of an underlying discovery service, e.g., the Codex DHT,
to look up such peers, but this is beyond the scope of this document.</p><p>The protocol supports two distinct block types to accommodate different
use cases: standalone blocks for independent data chunks and dataset
blocks for ordered collections of data that form larger structures.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="block-format">Block Format<a href="#block-format" class="hash-link" aria-label="Direct link to Block Format" title="Direct link to Block Format"></a></h2><p>The Block Exchange protocol supports two types of blocks:</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="standalone-blocks">Standalone Blocks<a href="#standalone-blocks" class="hash-link" aria-label="Direct link to Standalone Blocks" title="Direct link to Standalone Blocks"></a></h3><p>Standalone blocks are self-contained pieces of data addressed by their
SHA256 content identifier (CID).
These blocks are independent and do not reference any larger structure.</p><p><strong>Properties:</strong></p><ul><li>Addressed by content hash (SHA256)</li><li>Default size: 64 KiB</li><li>Self-contained and independently verifiable</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="dataset-blocks">Dataset Blocks<a href="#dataset-blocks" class="hash-link" aria-label="Direct link to Dataset Blocks" title="Direct link to Dataset Blocks"></a></h3><p>Dataset blocks are part of ordered sets and are addressed by a
<code>(datasetCID, index)</code> tuple.
The datasetCID refers to the Merkle tree root of the entire dataset,
and the index indicates the block&#x27;s position within that dataset.</p><p>Formally, we can define a block as a tuple consisting of raw data and
its content identifier: <code>(data: seq[byte], cid: Cid)</code>, where standalone
blocks are addressed by <code>cid</code>, and dataset blocks can be addressed
either by <code>cid</code> or a <code>(datasetCID, index)</code> tuple.</p><p><strong>Properties:</strong></p><ul><li>Addressed by <code>(treeCID, index)</code> tuple</li><li>Part of a Merkle tree structure</li><li>Require Merkle proof for verification</li><li>Must be uniformly sized within a dataset</li><li>Final blocks MUST be zero-padded if incomplete</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="block-specifications">Block Specifications<a href="#block-specifications" class="hash-link" aria-label="Direct link to Block Specifications" title="Direct link to Block Specifications"></a></h3><p>All blocks in the Codex Block Exchange protocol adhere to the
following specifications:</p><table><thead><tr><th>Property</th><th>Value</th><th>Description</th></tr></thead><tbody><tr><td>Default Block Size</td><td>64 KiB</td><td>Standard size for data blocks</td></tr><tr><td>Maximum Block Size</td><td>100 MiB</td><td>Upper limit for block data field</td></tr><tr><td>Multicodec</td><td><code>codex-block</code> (0xCD02)*</td><td>Format identifier</td></tr><tr><td>Multihash</td><td><code>sha2-256</code> (0x12)</td><td>Hash algorithm for addressing</td></tr><tr><td>Padding Requirement</td><td>Zero-padding</td><td>Incomplete final blocks padded</td></tr></tbody></table><p><strong>Note:</strong> *The multicodec value 0xCD02 is not currently registered in the official <a href="https://github.com/multiformats/multicodec/blob/master/table.csv" target="_blank" rel="noopener noreferrer">multiformats multicodec table</a>. This may be a reserved/private code pending official registration.</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="protocol-limits">Protocol Limits<a href="#protocol-limits" class="hash-link" aria-label="Direct link to Protocol Limits" title="Direct link to Protocol Limits"></a></h3><p>To ensure network stability and prevent resource exhaustion, implementations
SHOULD enforce reasonable limits. The following are <strong>recommended values</strong>
(actual implementation limits may vary):</p><table><thead><tr><th>Limit</th><th>Recommended Value</th><th>Description</th></tr></thead><tbody><tr><td><strong>Maximum Block Size</strong></td><td>100 MiB</td><td>Maximum size of block data in BlockDelivery</td></tr><tr><td><strong>Maximum WantList Size</strong></td><td>1000 entries</td><td>Maximum entries per WantList message</td></tr><tr><td><strong>Maximum Concurrent Requests</strong></td><td>256 per peer</td><td>Maximum simultaneous block requests per peer</td></tr><tr><td><strong>Stream Timeout</strong></td><td>60 seconds</td><td>Idle stream closure timeout</td></tr><tr><td><strong>Request Timeout</strong></td><td>300 seconds</td><td>Maximum time to fulfill a block request</td></tr><tr><td><strong>Maximum Message Size</strong></td><td>105 MiB</td><td>Maximum total message size (protobuf)</td></tr><tr><td><strong>Maximum Pending Bytes</strong></td><td>10 GiB</td><td>Maximum pending data per peer connection</td></tr></tbody></table><p><strong>Note:</strong> These values are <strong>not verified from implementation</strong> and serve as
reasonable guidelines. Actual implementations MAY use different limits based
on their resource constraints and deployment requirements.</p><p><strong>Enforcement:</strong></p><ul><li>Implementations MUST reject messages exceeding their configured size limits</li><li>Implementations SHOULD track per-peer request counts</li><li>Implementations SHOULD close streams exceeding configured timeout limits</li><li>Implementations MAY implement stricter or more lenient limits based on local resources</li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="service-interface">Service Interface<a href="#service-interface" class="hash-link" aria-label="Direct link to Service Interface" title="Direct link to Service Interface"></a></h2><p>The Block Exchange module exposes two core primitives for
block management:</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="requestblock"><code>requestBlock</code><a href="#requestblock" class="hash-link" aria-label="Direct link to requestblock" title="Direct link to requestblock"></a></h3><div class="language-python codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-python codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">requestBlock</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> BlockAddress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token plain"> Block</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>Registers a block address for retrieval and returns the block data
when available.
This function can be awaited by the caller until the block is retrieved
from the network or local storage.</p><p><strong>Parameters:</strong></p><ul><li><code>address</code>: BlockAddress - The unique address identifying the block
to retrieve</li></ul><p><strong>Returns:</strong></p><ul><li><code>Block</code> - The retrieved block data</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="cancelrequest"><code>cancelRequest</code><a href="#cancelrequest" class="hash-link" aria-label="Direct link to cancelrequest" title="Direct link to cancelrequest"></a></h3><div class="language-python codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-python codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">async</span><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">cancelRequest</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">address</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> BlockAddress</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">bool</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p>Cancels a previously registered block request.</p><p><strong>Parameters:</strong></p><ul><li><code>address</code>: BlockAddress - The address of the block request to cancel</li></ul><p><strong>Returns:</strong></p><ul><li><code>bool</code> - True if the cancellation was successful, False otherwise</li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="dependencies">Dependencies<a href="#dependencies" class="hash-link" aria-label="Direct link to Dependencies" title="Direct link to Dependencies"></a></h2><p>The Block Exchange module depends on and interacts with several other
Codex components:</p><table><thead><tr><th>Component</th><th>Purpose</th></tr></thead><tbody><tr><td><strong>Discovery Module</strong></td><td>DHT-based peer discovery for locating nodes</td></tr><tr><td><strong>Local Store (Repo)</strong></td><td>Persistent block storage for local blocks</td></tr><tr><td><strong>Advertiser</strong></td><td>Announces block availability to the network</td></tr><tr><td><strong>Network Layer</strong></td><td>libp2p connections and stream management</td></tr></tbody></table><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="protocol-specification">Protocol Specification<a href="#protocol-specification" class="hash-link" aria-label="Direct link to Protocol Specification" title="Direct link to Protocol Specification"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="protocol-identifier">Protocol Identifier<a href="#protocol-identifier" class="hash-link" aria-label="Direct link to Protocol Identifier" title="Direct link to Protocol Identifier"></a></h3><p>The Block Exchange protocol uses the following libp2p protocol
identifier:</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">/codex/blockexc/1.0.0</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="version-negotiation">Version Negotiation<a href="#version-negotiation" class="hash-link" aria-label="Direct link to Version Negotiation" title="Direct link to Version Negotiation"></a></h3><p>The protocol version is negotiated through libp2p&#x27;s multistream-select
protocol during connection establishment. The following describes standard
libp2p version negotiation behavior; actual Codex implementation details
may vary.</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="protocol-versioning">Protocol Versioning<a href="#protocol-versioning" class="hash-link" aria-label="Direct link to Protocol Versioning" title="Direct link to Protocol Versioning"></a></h4><p><strong>Version Format</strong>: <code>/codex/blockexc/&lt;major&gt;.&lt;minor&gt;.&lt;patch&gt;</code></p><ul><li><strong>Major version</strong>: Incompatible protocol changes</li><li><strong>Minor version</strong>: Backward-compatible feature additions</li><li><strong>Patch version</strong>: Backward-compatible bug fixes</li></ul><p><strong>Current Version</strong>: <code>1.0.0</code></p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="version-negotiation-process">Version Negotiation Process<a href="#version-negotiation-process" class="hash-link" aria-label="Direct link to Version Negotiation Process" title="Direct link to Version Negotiation Process"></a></h4><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">1. Initiator opens stream</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">2. Initiator proposes: &quot;/codex/blockexc/1.0.0&quot;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">3. Responder checks supported versions</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">4. If supported:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Responder accepts: &quot;/codex/blockexc/1.0.0&quot;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Connection established</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">5. If not supported:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Responder rejects with: &quot;na&quot; (not available)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Try fallback version or close connection</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="compatibility-rules">Compatibility Rules<a href="#compatibility-rules" class="hash-link" aria-label="Direct link to Compatibility Rules" title="Direct link to Compatibility Rules"></a></h4><p><strong>Major Version Compatibility:</strong></p><ul><li>Major version <code>1.x.x</code> is incompatible with <code>2.x.x</code></li><li>Nodes MUST support only their major version</li><li>Cross-major-version communication requires protocol upgrade</li></ul><p><strong>Minor Version Compatibility:</strong></p><ul><li>Version <code>1.1.0</code> MUST be backward compatible with <code>1.0.0</code></li><li>Newer minors MAY include optional features</li><li>Older nodes ignore unknown message fields (protobuf semantics)</li></ul><p><strong>Patch Version Compatibility:</strong></p><ul><li>All patches within same minor version are fully compatible</li><li>Patches fix bugs without changing protocol behavior</li></ul><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="multi-version-support">Multi-Version Support<a href="#multi-version-support" class="hash-link" aria-label="Direct link to Multi-Version Support" title="Direct link to Multi-Version Support"></a></h4><p>Implementations MAY support multiple protocol versions simultaneously:</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Supported protocols (in preference order):</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 1. /codex/blockexc/1.2.0 (preferred, latest features)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 2. /codex/blockexc/1.1.0 (fallback, stable)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 3. /codex/blockexc/1.0.0 (legacy support)</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Negotiation Strategy:</strong></p><ol><li>Propose highest supported version first</li><li>If rejected, try next lower version</li><li>If all rejected, connection fails</li><li>Track peer&#x27;s supported version for future connections</li></ol><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="feature-detection">Feature Detection<a href="#feature-detection" class="hash-link" aria-label="Direct link to Feature Detection" title="Direct link to Feature Detection"></a></h4><p>For optional features within same major.minor version:</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Method 1: Message field presence</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> - Send message with optional field</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> - Peer ignores if not supported (protobuf default)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Method 2: Capability exchange (future extension)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> - Exchange capability bitmask in initial message</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> - Enable features only if both peers support</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="version-upgrade-path">Version Upgrade Path<a href="#version-upgrade-path" class="hash-link" aria-label="Direct link to Version Upgrade Path" title="Direct link to Version Upgrade Path"></a></h4><p><strong>Backward Compatibility:</strong></p><ul><li>New versions MUST handle messages from older versions</li><li>Unknown message fields silently ignored</li><li>Unknown WantList flags ignored</li><li>Unknown BlockPresence types treated as DontHave</li></ul><p><strong>Forward Compatibility:</strong></p><ul><li>Older versions MAY ignore new message types</li><li>Critical features require major version bump</li><li>Optional features use minor version bump</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="connection-model">Connection Model<a href="#connection-model" class="hash-link" aria-label="Direct link to Connection Model" title="Direct link to Connection Model"></a></h3><p>The protocol operates over libp2p streams.
When a node wants to communicate with a peer:</p><ol><li>The initiating node dials the peer using the protocol identifier</li><li>A bidirectional stream is established</li><li>Both sides can send and receive messages on this stream</li><li>Messages are encoded using Protocol Buffers</li><li>The stream remains open for the duration of the exchange session</li><li>Peers track active connections in a peer context store</li></ol><p>The protocol handles peer lifecycle events:</p><ul><li><strong>Peer Joined</strong>: When a peer connects, it is added to the active
peer set</li><li><strong>Peer Departed</strong>: When a peer disconnects gracefully, its context
is cleaned up</li><li><strong>Peer Dropped</strong>: When a peer connection fails, it is removed from
the active set</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="message-flow-examples">Message Flow Examples<a href="#message-flow-examples" class="hash-link" aria-label="Direct link to Message Flow Examples" title="Direct link to Message Flow Examples"></a></h3><p>This section illustrates typical message exchange sequences for common
block exchange scenarios.</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-1-standalone-block-request">Example 1: Standalone Block Request<a href="#example-1-standalone-block-request" class="hash-link" aria-label="Direct link to Example 1: Standalone Block Request" title="Direct link to Example 1: Standalone Block Request"></a></h4><p><strong>Scenario</strong>: Node A requests a standalone block from Node B</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Node A Node B</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |--- Message(wantlist) ------------------&gt;|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantlist.entries[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmABC123 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantType = wantBlock |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | priority = 0 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |&lt;-- Message(blockPresences, payload) ----|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | blockPresences[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmABC123 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | type = presenceHave |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | payload[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | cid = QmABC123 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | data = &lt;64 KiB block data&gt; |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmABC123 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Steps:</strong></p><ol><li>Node A sends WantList requesting block with <code>wantType = wantBlock</code></li><li>Node B checks local storage, finds block</li><li>Node B responds with BlockPresence confirming availability</li><li>Node B includes BlockDelivery with actual block data</li><li>Node A verifies CID matches SHA256(data)</li><li>Node A stores block locally</li></ol><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-2-dataset-block-request-with-merkle-proof">Example 2: Dataset Block Request with Merkle Proof<a href="#example-2-dataset-block-request-with-merkle-proof" class="hash-link" aria-label="Direct link to Example 2: Dataset Block Request with Merkle Proof" title="Direct link to Example 2: Dataset Block Request with Merkle Proof"></a></h4><p><strong>Scenario</strong>: Node A requests a dataset block from Node B</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Node A Node B</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |--- Message(wantlist) ------------------&gt;|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantlist.entries[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.leaf = true |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.treeCid = QmTree456 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.index = 42 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantType = wantBlock |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |&lt;-- Message(payload) ---------------------|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | payload[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | cid = QmBlock789 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | data = &lt;64 KiB zero-padded data&gt; |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.leaf = true |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.treeCid = QmTree456 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.index = 42 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | proof = &lt;CodexProof bytes&gt; |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Steps:</strong></p><ol><li>Node A sends WantList for dataset block at specific index</li><li>Node B locates block in dataset</li><li>Node B generates CodexProof for block position in Merkle tree</li><li>Node B delivers block with proof</li><li>Node A verifies proof against treeCid</li><li>Node A verifies block data integrity</li><li>Node A stores block with dataset association</li></ol><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-3-block-presence-check-wanthave">Example 3: Block Presence Check (wantHave)<a href="#example-3-block-presence-check-wanthave" class="hash-link" aria-label="Direct link to Example 3: Block Presence Check (wantHave)" title="Direct link to Example 3: Block Presence Check (wantHave)"></a></h4><p><strong>Scenario</strong>: Node A checks if Node B has a block without requesting full data</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Node A Node B</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |--- Message(wantlist) ------------------&gt;|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantlist.entries[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmCheck999 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantType = wantHave |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | sendDontHave = true |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |&lt;-- Message(blockPresences) -------------|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | blockPresences[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmCheck999 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | type = presenceHave |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | price = 0x00 (free) |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Steps:</strong></p><ol><li>Node A sends WantList with <code>wantType = wantHave</code></li><li>Node B checks local storage without loading block data</li><li>Node B responds with BlockPresence only (no payload)</li><li>Node A updates peer availability map</li><li>If Node A decides to request, sends new WantList with <code>wantType = wantBlock</code></li></ol><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-4-block-not-available">Example 4: Block Not Available<a href="#example-4-block-not-available" class="hash-link" aria-label="Direct link to Example 4: Block Not Available" title="Direct link to Example 4: Block Not Available"></a></h4><p><strong>Scenario</strong>: Node A requests block Node B doesn&#x27;t have</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Node A Node B</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |--- Message(wantlist) ------------------&gt;|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantlist.entries[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmMissing111 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantType = wantBlock |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | sendDontHave = true |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |&lt;-- Message(blockPresences) -------------|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | blockPresences[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmMissing111 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | type = presenceDontHave |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Steps:</strong></p><ol><li>Node A requests block with <code>sendDontHave = true</code></li><li>Node B checks storage, block not found</li><li>Node B sends BlockPresence with <code>presenceDontHave</code></li><li>Node A removes Node B from candidates for this block</li><li>Node A queries discovery service for alternative peers</li></ol><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-5-wantlist-cancellation">Example 5: WantList Cancellation<a href="#example-5-wantlist-cancellation" class="hash-link" aria-label="Direct link to Example 5: WantList Cancellation" title="Direct link to Example 5: WantList Cancellation"></a></h4><p><strong>Scenario</strong>: Node A cancels a previous block request</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Node A Node B</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |--- Message(wantlist) ------------------&gt;|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantlist.entries[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmCancel222 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | cancel = true |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Steps:</strong></p><ol><li>Node A sends WantList entry with <code>cancel = true</code></li><li>Node B removes block request from peer&#x27;s want queue</li><li>Node B stops any pending block transfer for this address</li><li>No response message required for cancellation</li></ol><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-6-delta-wantlist-update">Example 6: Delta WantList Update<a href="#example-6-delta-wantlist-update" class="hash-link" aria-label="Direct link to Example 6: Delta WantList Update" title="Direct link to Example 6: Delta WantList Update"></a></h4><p><strong>Scenario</strong>: Node A adds requests to existing WantList</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Node A Node B</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> |--- Message(wantlist) ------------------&gt;|</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantlist.full = false |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantlist.entries[0]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmNew1 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantType = wantBlock |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantlist.entries[1]: |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | address.cid = QmNew2 |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | wantType = wantBlock |</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> | |</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Steps:</strong></p><ol><li>Node A sends WantList with <code>full = false</code> (delta update)</li><li>Node B merges entries with existing WantList for Node A</li><li>Node B begins processing new requests</li><li>Previous WantList entries remain active</li></ol><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="sequence-diagrams">Sequence Diagrams<a href="#sequence-diagrams" class="hash-link" aria-label="Direct link to Sequence Diagrams" title="Direct link to Sequence Diagrams"></a></h3><p>These diagrams illustrate the complete flow of block exchange operations
including service interface, peer discovery, and network protocol interactions.</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="complete-block-request-flow">Complete Block Request Flow<a href="#complete-block-request-flow" class="hash-link" aria-label="Direct link to Complete Block Request Flow" title="Direct link to Complete Block Request Flow"></a></h4><p>The protocol supports two strategies for WantBlock requests,
each with different trade-offs.
Implementations may choose the strategy based on network conditions,
peer availability, and resource constraints.</p><h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="strategy-1-parallel-request-low-latency">Strategy 1: Parallel Request (Low Latency)<a href="#strategy-1-parallel-request-low-latency" class="hash-link" aria-label="Direct link to Strategy 1: Parallel Request (Low Latency)" title="Direct link to Strategy 1: Parallel Request (Low Latency)"></a></h5><p>In this strategy, the requester sends <code>wantType = wantBlock</code> to all
discovered peers simultaneously.
This minimizes latency as the first peer to respond with the block
data wins, but it wastes bandwidth since multiple peers may send
the same block data.</p><p><strong>Trade-offs:</strong></p><ul><li><strong>Pro</strong>: Lowest latency - block arrives as soon as any peer can deliver it</li><li><strong>Pro</strong>: More resilient to slow or unresponsive peers</li><li><strong>Con</strong>: Bandwidth-wasteful - multiple peers may send duplicate data</li><li><strong>Con</strong>: Higher network overhead for the requester</li><li><strong>Best for</strong>: Time-critical data retrieval, unreliable networks</li></ul><div class="wrapper_SWrM active_qZD5"><button class="fullscreenButton_Bocn lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M1.75 2.917V5.25h1.167V2.917H5.25V1.75H2.917A1.17 1.17 0 0 0 1.75 2.917ZM2.917 8.75H1.75v2.333a1.17 1.17 0 0 0 1.167 1.167H5.25v-1.167H2.917V8.75Zm8.166 2.333H8.75v1.167h2.333a1.17 1.17 0 0 0 1.167-1.167V8.75h-1.167v2.333Zm0-9.333H8.75v1.167h2.333V5.25h1.167V2.917a1.17 1.17 0 0 0-1.167-1.167Z" fill="#fff"></path></svg></div></button></div><h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="strategy-2-two-phase-discovery-bandwidth-efficient">Strategy 2: Two-Phase Discovery (Bandwidth Efficient)<a href="#strategy-2-two-phase-discovery-bandwidth-efficient" class="hash-link" aria-label="Direct link to Strategy 2: Two-Phase Discovery (Bandwidth Efficient)" title="Direct link to Strategy 2: Two-Phase Discovery (Bandwidth Efficient)"></a></h5><p>In this strategy, the requester first sends <code>wantType = wantHave</code> to
discover which peers have the block, then sends <code>wantType = wantBlock</code>
only to a single selected peer.
This conserves bandwidth but adds an extra round-trip of latency.</p><p><strong>Trade-offs:</strong></p><ul><li><strong>Pro</strong>: Bandwidth-efficient - only one peer sends block data</li><li><strong>Pro</strong>: Enables price comparison before committing to a peer</li><li><strong>Pro</strong>: Allows selection based on peer reputation or proximity</li><li><strong>Con</strong>: Higher latency due to extra round-trip for presence check</li><li><strong>Con</strong>: Selected peer may become unavailable between phases</li><li><strong>Best for</strong>: Large blocks, paid content, bandwidth-constrained networks</li></ul><div class="wrapper_SWrM active_qZD5"><button class="fullscreenButton_Bocn lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M1.75 2.917V5.25h1.167V2.917H5.25V1.75H2.917A1.17 1.17 0 0 0 1.75 2.917ZM2.917 8.75H1.75v2.333a1.17 1.17 0 0 0 1.167 1.167H5.25v-1.167H2.917V8.75Zm8.166 2.333H8.75v1.167h2.333a1.17 1.17 0 0 0 1.167-1.167V8.75h-1.167v2.333Zm0-9.333H8.75v1.167h2.333V5.25h1.167V2.917a1.17 1.17 0 0 0-1.167-1.167Z" fill="#fff"></path></svg></div></button></div><h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="hybrid-approach">Hybrid Approach<a href="#hybrid-approach" class="hash-link" aria-label="Direct link to Hybrid Approach" title="Direct link to Hybrid Approach"></a></h5><p>Implementations MAY combine both strategies:</p><ol><li>Use two-phase discovery for large blocks or paid content</li><li>Use parallel requests for small blocks or time-critical data</li><li>Adaptively switch strategies based on network conditions</li></ol><div class="wrapper_SWrM active_qZD5"><button class="fullscreenButton_Bocn lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M1.75 2.917V5.25h1.167V2.917H5.25V1.75H2.917A1.17 1.17 0 0 0 1.75 2.917ZM2.917 8.75H1.75v2.333a1.17 1.17 0 0 0 1.167 1.167H5.25v-1.167H2.917V8.75Zm8.166 2.333H8.75v1.167h2.333a1.17 1.17 0 0 0 1.167-1.167V8.75h-1.167v2.333Zm0-9.333H8.75v1.167h2.333V5.25h1.167V2.917a1.17 1.17 0 0 0-1.167-1.167Z" fill="#fff"></path></svg></div></button></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="dataset-block-verification-flow">Dataset Block Verification Flow<a href="#dataset-block-verification-flow" class="hash-link" aria-label="Direct link to Dataset Block Verification Flow" title="Direct link to Dataset Block Verification Flow"></a></h4><div class="wrapper_SWrM active_qZD5"><button class="fullscreenButton_Bocn lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M1.75 2.917V5.25h1.167V2.917H5.25V1.75H2.917A1.17 1.17 0 0 0 1.75 2.917ZM2.917 8.75H1.75v2.333a1.17 1.17 0 0 0 1.167 1.167H5.25v-1.167H2.917V8.75Zm8.166 2.333H8.75v1.167h2.333a1.17 1.17 0 0 0 1.167-1.167V8.75h-1.167v2.333Zm0-9.333H8.75v1.167h2.333V5.25h1.167V2.917a1.17 1.17 0 0 0-1.167-1.167Z" fill="#fff"></path></svg></div></button></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="payment-flow-with-state-channels">Payment Flow with State Channels<a href="#payment-flow-with-state-channels" class="hash-link" aria-label="Direct link to Payment Flow with State Channels" title="Direct link to Payment Flow with State Channels"></a></h4><div class="wrapper_SWrM active_qZD5"><button class="fullscreenButton_Bocn lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M1.75 2.917V5.25h1.167V2.917H5.25V1.75H2.917A1.17 1.17 0 0 0 1.75 2.917ZM2.917 8.75H1.75v2.333a1.17 1.17 0 0 0 1.167 1.167H5.25v-1.167H2.917V8.75Zm8.166 2.333H8.75v1.167h2.333a1.17 1.17 0 0 0 1.167-1.167V8.75h-1.167v2.333Zm0-9.333H8.75v1.167h2.333V5.25h1.167V2.917a1.17 1.17 0 0 0-1.167-1.167Z" fill="#fff"></path></svg></div></button></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="peer-lifecycle-management">Peer Lifecycle Management<a href="#peer-lifecycle-management" class="hash-link" aria-label="Direct link to Peer Lifecycle Management" title="Direct link to Peer Lifecycle Management"></a></h4><div class="wrapper_SWrM active_qZD5"><button class="fullscreenButton_Bocn lsd-icon-button lsd-icon-button--medium lsd-icon-button--outlined"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M1.75 2.917V5.25h1.167V2.917H5.25V1.75H2.917A1.17 1.17 0 0 0 1.75 2.917ZM2.917 8.75H1.75v2.333a1.17 1.17 0 0 0 1.167 1.167H5.25v-1.167H2.917V8.75Zm8.166 2.333H8.75v1.167h2.333a1.17 1.17 0 0 0 1.167-1.167V8.75h-1.167v2.333Zm0-9.333H8.75v1.167h2.333V5.25h1.167V2.917a1.17 1.17 0 0 0-1.167-1.167Z" fill="#fff"></path></svg></div></button></div><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="message-format">Message Format<a href="#message-format" class="hash-link" aria-label="Direct link to Message Format" title="Direct link to Message Format"></a></h3><p>All messages use Protocol Buffers encoding for serialization.
The main message structure supports multiple operation types in a
single message.</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="main-message-structure">Main Message Structure<a href="#main-message-structure" class="hash-link" aria-label="Direct link to Main Message Structure" title="Direct link to Main Message Structure"></a></h4><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message Message {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Wantlist wantlist = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> // Field 2 reserved for future use</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated BlockDelivery payload = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated BlockPresence blockPresences = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> int32 pendingBytes = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> AccountMessage account = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> StateChannelUpdate payment = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Fields:</strong></p><ul><li><code>wantlist</code>: Block requests from the sender</li><li>Field 2: Reserved (unused, see note below)</li><li><code>payload</code>: Block deliveries (actual block data)</li><li><code>blockPresences</code>: Availability indicators for requested blocks</li><li><code>pendingBytes</code>: Number of bytes pending delivery</li><li><code>account</code>: Account information for micropayments</li><li><code>payment</code>: State channel update for payment processing</li></ul><p><strong>Note on Missing Field 2:</strong></p><p>Field number 2 is intentionally skipped in the Message protobuf definition.
This is a common protobuf practice for several reasons:</p><ul><li><strong>Protocol Evolution</strong>: Field 2 may have been used in earlier versions and
removed, with the field number reserved to prevent reuse</li><li><strong>Forward Compatibility</strong>: Reserving field numbers ensures old clients can
safely ignore new fields</li><li><strong>Implementation History</strong>: May have been used during development and removed
before final release</li></ul><p>The gap does not affect protocol operation. Protobuf field numbers need not be
sequential, and skipping numbers is standard practice for protocol evolution.</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="block-address">Block Address<a href="#block-address" class="hash-link" aria-label="Direct link to Block Address" title="Direct link to Block Address"></a></h4><p>The BlockAddress structure supports both standalone and dataset
block addressing:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool leaf = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes treeCid = 2; // Present when leaf = true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> uint64 index = 3; // Present when leaf = true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes cid = 4; // Present when leaf = false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Fields:</strong></p><ul><li><code>leaf</code>: Indicates if this is dataset block (true) or standalone
(false)</li><li><code>treeCid</code>: Merkle tree root CID (present when <code>leaf = true</code>)</li><li><code>index</code>: Position of block within dataset (present when <code>leaf = true</code>)</li><li><code>cid</code>: Content identifier of the block (present when <code>leaf = false</code>)</li></ul><p><strong>Addressing Modes:</strong></p><ul><li><strong>Standalone Block</strong> (<code>leaf = false</code>): Direct CID reference to a
standalone content block</li><li><strong>Dataset Block</strong> (<code>leaf = true</code>): Reference to a block within an
ordered set, identified by a Merkle tree root and an index.
The Merkle root may refer to either a regular dataset, or a dataset
that has undergone erasure-coding</li></ul><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="wantlist">WantList<a href="#wantlist" class="hash-link" aria-label="Direct link to WantList" title="Direct link to WantList"></a></h4><p>The WantList communicates which blocks a peer desires to receive:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message Wantlist {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> enum WantType {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wantBlock = 0;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wantHave = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> message Entry {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> BlockAddress address = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> int32 priority = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool cancel = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> WantType wantType = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool sendDontHave = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated Entry entries = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bool full = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>WantType Values:</strong></p><ul><li><code>wantBlock (0)</code>: Request full block delivery</li><li><code>wantHave (1)</code>: Request availability information only (presence check)</li></ul><p><strong>Entry Fields:</strong></p><ul><li><code>address</code>: The block being requested</li><li><code>priority</code>: Request priority (currently always 0, reserved for future use)</li><li><code>cancel</code>: If true, cancels a previous want for this block</li><li><code>wantType</code>: Specifies whether full block or presence is desired<ul><li><code>wantHave (1)</code>: Only check if peer has the block</li><li><code>wantBlock (0)</code>: Request full block data</li></ul></li><li><code>sendDontHave</code>: If true, peer should respond even if it doesn&#x27;t have
the block</li></ul><p><strong>Priority Field Clarification:</strong></p><p>The <code>priority</code> field is currently fixed at <code>0</code> in all implementations and is
reserved for future protocol extensions. Originally intended for request
prioritization, this feature is not yet implemented.</p><p><strong>Current Behavior:</strong></p><ul><li>All WantList entries use <code>priority = 0</code></li><li>Implementations MUST accept priority values but MAY ignore them</li><li>Blocks are processed in order received, not by priority</li></ul><p><strong>Future Extensions:</strong></p><p>The priority field is reserved for:</p><ul><li><strong>Bandwidth Management</strong>: Higher priority blocks served first during congestion</li><li><strong>Time-Critical Data</strong>: Urgent blocks (e.g., recent dataset indices) prioritized</li><li><strong>Fair Queueing</strong>: Priority-based scheduling across multiple peers</li><li><strong>QoS Tiers</strong>: Different service levels based on payment/reputation</li></ul><p><strong>Implementation Notes:</strong></p><ul><li>Senders SHOULD set <code>priority = 0</code> for compatibility</li><li>Receivers MUST NOT reject messages with non-zero priority</li><li>Future protocol versions may activate priority-based scheduling</li><li>When activated, higher priority values = higher priority (0 = lowest)</li></ul><p><strong>WantList Fields:</strong></p><ul><li><code>entries</code>: List of block requests</li><li><code>full</code>: If true, replaces all previous entries; if false, delta update</li></ul><p><strong>Delta Updates:</strong></p><p>WantLists support delta updates for efficiency.
When <code>full = false</code>, entries represent additions or modifications to
the existing WantList rather than a complete replacement.</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="block-delivery">Block Delivery<a href="#block-delivery" class="hash-link" aria-label="Direct link to Block Delivery" title="Direct link to Block Delivery"></a></h4><p>Block deliveries contain the actual block data along with verification
information:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message BlockDelivery {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes cid = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes data = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> BlockAddress address = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes proof = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Fields:</strong></p><ul><li><code>cid</code>: Content identifier of the block</li><li><code>data</code>: Raw block data (up to 100 MiB)</li><li><code>address</code>: The BlockAddress identifying this block</li><li><code>proof</code>: Merkle proof (CodexProof) verifying block correctness
(required for dataset blocks)</li></ul><p><strong>Merkle Proof Verification:</strong></p><p>When delivering dataset blocks (<code>address.leaf = true</code>):</p><ul><li>The delivery MUST include a Merkle proof (CodexProof)</li><li>The proof verifies that the block at the given index is correctly
part of the Merkle tree identified by the tree CID</li><li>This applies to all datasets, irrespective of whether they have been
erasure-coded or not</li><li>Recipients MUST verify the proof before accepting the block</li><li>Invalid proofs result in block rejection</li></ul><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="block-presence">Block Presence<a href="#block-presence" class="hash-link" aria-label="Direct link to Block Presence" title="Direct link to Block Presence"></a></h4><p>Block presence messages indicate whether a peer has or does not have a
requested block:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">enum BlockPresenceType {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> presenceHave = 0;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> presenceDontHave = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message BlockPresence {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> BlockAddress address = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> BlockPresenceType type = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes price = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Fields:</strong></p><ul><li><code>address</code>: The block address being referenced</li><li><code>type</code>: Whether the peer has the block or not</li><li><code>price</code>: Price in wei (UInt256 format, see below)</li></ul><p><strong>UInt256 Price Format:</strong></p><p>The <code>price</code> field encodes a 256-bit unsigned integer representing the cost in
wei (the smallest Ethereum denomination, where 1 ETH = 10^18 wei).</p><p><strong>Encoding Specification:</strong></p><ul><li><strong>Format</strong>: 32 bytes, big-endian byte order</li><li><strong>Type</strong>: Unsigned 256-bit integer</li><li><strong>Range</strong>: 0 to 2^256 - 1</li><li><strong>Zero Price</strong>: <code>0x0000000000000000000000000000000000000000000000000000000000000000</code>
(block is free)</li></ul><p><strong>Examples:</strong></p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Free (0 wei):</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 0x0000000000000000000000000000000000000000000000000000000000000000</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">1 wei:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 0x0000000000000000000000000000000000000000000000000000000000000001</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">1 gwei (10^9 wei):</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 0x000000000000000000000000000000000000000000000000000000003b9aca00</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">0.001 ETH (10^15 wei):</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 0x00000000000000000000000000000000000000000000000000038d7ea4c68000</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">1 ETH (10^18 wei):</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 0x0000000000000000000000000000000000000000000000000de0b6b3a7640000</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Maximum (2^256 - 1):</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Conversion Logic:</strong></p><div class="language-python codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-python codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token comment" style="color:rgb(98, 114, 164)"># Wei to bytes (big-endian)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">wei_to_bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">amount_wei</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">int</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> amount_wei</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">to_bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token number">32</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> byteorder</span><span class="token operator">=</span><span class="token string" style="color:rgb(255, 121, 198)">&#x27;big&#x27;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># Bytes to wei</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">bytes_to_wei</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">price_bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">int</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">int</span><span class="token punctuation" style="color:rgb(248, 248, 242)">.</span><span class="token plain">from_bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">price_bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> byteorder</span><span class="token operator">=</span><span class="token string" style="color:rgb(255, 121, 198)">&#x27;big&#x27;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token comment" style="color:rgb(98, 114, 164)"># ETH to wei to bytes</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">def</span><span class="token plain"> </span><span class="token function" style="color:rgb(80, 250, 123)">eth_to_price_bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">amount_eth</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">float</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"> </span><span class="token operator">-</span><span class="token operator">&gt;</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> amount_wei </span><span class="token operator">=</span><span class="token plain"> </span><span class="token builtin" style="color:rgb(189, 147, 249)">int</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">amount_eth </span><span class="token operator">*</span><span class="token plain"> </span><span class="token number">10</span><span class="token operator">**</span><span class="token number">18</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token keyword" style="color:rgb(189, 147, 249);font-style:italic">return</span><span class="token plain"> wei_to_bytes</span><span class="token punctuation" style="color:rgb(248, 248, 242)">(</span><span class="token plain">amount_wei</span><span class="token punctuation" style="color:rgb(248, 248, 242)">)</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="payment-messages">Payment Messages<a href="#payment-messages" class="hash-link" aria-label="Direct link to Payment Messages" title="Direct link to Payment Messages"></a></h4><p>Payment-related messages for micropayments using Nitro state channels.</p><p><strong>Account Message:</strong></p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message AccountMessage {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes address = 1; // Ethereum address to which payments should be made</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Fields:</strong></p><ul><li><code>address</code>: Ethereum address for receiving payments</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="concrete-message-examples">Concrete Message Examples<a href="#concrete-message-examples" class="hash-link" aria-label="Direct link to Concrete Message Examples" title="Direct link to Concrete Message Examples"></a></h3><p>This section provides real-world examples of protobuf messages for different
block exchange scenarios.</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-1-simple-standalone-block-request">Example 1: Simple Standalone Block Request<a href="#example-1-simple-standalone-block-request" class="hash-link" aria-label="Direct link to Example 1: Simple Standalone Block Request" title="Direct link to Example 1: Simple Standalone Block Request"></a></h4><p><strong>Scenario</strong>: Request a single standalone block</p><p><strong>Protobuf (wire format representation):</strong></p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Message {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wantlist: Wantlist {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> entries: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Entry {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> leaf: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cid: 0x0155a0e40220b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9 // CID bytes</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> priority: 0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cancel: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wantType: wantBlock // 0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> sendDontHave: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> full: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Hex representation (sample):</strong></p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">0a2e 0a2c 0a24 0001 5512 2012 20b9 4d27</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">b993 4d3e 08a5 2e52 d7da 7dab fac4 84ef</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">e37a 5380 ee90 88f7 ace2 efcd e910 0018</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">0020 0028 011201 01</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-2-dataset-block-request">Example 2: Dataset Block Request<a href="#example-2-dataset-block-request" class="hash-link" aria-label="Direct link to Example 2: Dataset Block Request" title="Direct link to Example 2: Dataset Block Request"></a></h4><p><strong>Scenario</strong>: Request block at index 100 from dataset</p><p><strong>Protobuf:</strong></p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Message {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wantlist: Wantlist {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> entries: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Entry {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> leaf: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> treeCid: 0x0155a0e40220c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 // Tree CID</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> index: 100</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> priority: 0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cancel: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wantType: wantBlock</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> sendDontHave: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> full: false // Delta update</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-3-block-delivery-with-proof">Example 3: Block Delivery with Proof<a href="#example-3-block-delivery-with-proof" class="hash-link" aria-label="Direct link to Example 3: Block Delivery with Proof" title="Direct link to Example 3: Block Delivery with Proof"></a></h4><p><strong>Scenario</strong>: Provider sends dataset block with Merkle proof</p><p><strong>Protobuf:</strong></p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Message {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> payload: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> BlockDelivery {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cid: 0x0155a0e40220a1b2c3d4e5f6071829... // Block CID</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> data: &lt;65536 bytes of block data&gt; // 64 KiB</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> leaf: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> treeCid: 0x0155a0e40220c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> index: 100</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> proof: &lt;CodexProof bytes&gt; // Merkle proof data</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> // Contains: path indices, sibling hashes, tree height</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> // Format: Implementation-specific (e.g., [height][index][hash1][hash2]...[hashN])</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> // Size varies by tree depth (illustrative: ~1KB for depth-10 tree)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-4-block-presence-response">Example 4: Block Presence Response<a href="#example-4-block-presence-response" class="hash-link" aria-label="Direct link to Example 4: Block Presence Response" title="Direct link to Example 4: Block Presence Response"></a></h4><p><strong>Scenario</strong>: Provider indicates block availability with price</p><p><strong>Protobuf:</strong></p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Message {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> blockPresences: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> BlockPresence {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> leaf: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cid: 0x0155a0e40220b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> type: presenceHave // 0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> price: 0x00000000000000000000000000000000000000000000000000038d7ea4c68000 // 0.001 ETH in wei</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-5-payment-message">Example 5: Payment Message<a href="#example-5-payment-message" class="hash-link" aria-label="Direct link to Example 5: Payment Message" title="Direct link to Example 5: Payment Message"></a></h4><p><strong>Scenario</strong>: Send payment via state channel update</p><p><strong>Protobuf:</strong></p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Message {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> account: AccountMessage {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: 0x742d35Cc6634C0532925a3b844200a717C48D6d9 // 20 bytes Ethereum address</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> payment: StateChannelUpdate {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> update: &lt;JSON bytes&gt;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> // Contains signed Nitro state as UTF-8 JSON string</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> // Example: {&quot;channelId&quot;:&quot;0x1234...&quot;,&quot;nonce&quot;:42,...}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-6-multiple-operations-in-one-message">Example 6: Multiple Operations in One Message<a href="#example-6-multiple-operations-in-one-message" class="hash-link" aria-label="Direct link to Example 6: Multiple Operations in One Message" title="Direct link to Example 6: Multiple Operations in One Message"></a></h4><p><strong>Scenario</strong>: Combined WantList, BlockPresence, and Delivery</p><p><strong>Protobuf:</strong></p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Message {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wantlist: Wantlist {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> entries: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Entry {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> leaf: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cid: 0x0155a0e40220... // Requesting new block</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wantType: wantBlock</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> priority: 0</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cancel: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> sendDontHave: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> full: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> blockPresences: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> BlockPresence {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> leaf: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cid: 0x0155a0e40220... // Response to previous request</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> type: presenceHave</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> price: 0x00 // Free</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> payload: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> BlockDelivery {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cid: 0x0155a0e40220... // Delivering another block</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> data: &lt;65536 bytes&gt;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> leaf: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cid: 0x0155a0e40220...</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> pendingBytes: 131072 // 128 KiB more data pending</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="example-7-wantlist-cancellation">Example 7: WantList Cancellation<a href="#example-7-wantlist-cancellation" class="hash-link" aria-label="Direct link to Example 7: WantList Cancellation" title="Direct link to Example 7: WantList Cancellation"></a></h4><p><strong>Scenario</strong>: Cancel multiple pending requests</p><p><strong>Protobuf:</strong></p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Message {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> wantlist: Wantlist {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> entries: [</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Entry {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> leaf: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cid: 0x0155a0e40220abc123...</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cancel: true // Cancellation flag</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> },</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Entry {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: BlockAddress {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> leaf: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> treeCid: 0x0155a0e40220def456...</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> index: 50</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> cancel: true</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> full: false</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="cid-format-details">CID Format Details<a href="#cid-format-details" class="hash-link" aria-label="Direct link to CID Format Details" title="Direct link to CID Format Details"></a></h4><p><strong>CID Structure:</strong></p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">CID v1 format (multibase + multicodec + multihash):</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">[0x01] [0x55] [0xa0] [0xe4] [0x02] [0x20] [&lt;32 bytes SHA256 hash&gt;]</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ │ │ │ │ │ │</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ │ │ │ │ │ └─ Hash digest</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ │ │ │ │ └───────── Hash length (32)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ │ │ │ └──────────────── Hash algorithm (SHA2-256)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ │ │ └─────────────────────── Codec size</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ │ └────────────────────────────── Codec (raw = 0x55)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ └───────────────────────────────────── Multicodec prefix</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> └──────────────────────────────────────────── CID version (1)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Actual: 0x01 55 a0 e4 02 20 &lt;hash bytes&gt;</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Example Block CID Breakdown:</strong></p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Full CID: 0x0155a0e40220b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Parts:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Version: 0x01 (CID v1)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Multicodec: 0x55 (raw)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Codec Size: 0xa0e402 (codex-block = 0xCD02, varint encoded)*</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Hash Type: 0x20 (SHA2-256)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Hash Len: 0x12 (20) (32 bytes)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Hash: b94d27b993... (32 bytes SHA256)</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>State Channel Update:</strong></p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message StateChannelUpdate {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> bytes update = 1; // Signed Nitro state, serialized as JSON</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Fields:</strong></p><ul><li><code>update</code>: Nitro state channel update containing payment information</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="payment-flow-and-price-negotiation">Payment Flow and Price Negotiation<a href="#payment-flow-and-price-negotiation" class="hash-link" aria-label="Direct link to Payment Flow and Price Negotiation" title="Direct link to Payment Flow and Price Negotiation"></a></h3><p>The Block Exchange protocol integrates with Nitro state channels to enable
micropayments for block delivery.</p><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="payment-requirements">Payment Requirements<a href="#payment-requirements" class="hash-link" aria-label="Direct link to Payment Requirements" title="Direct link to Payment Requirements"></a></h4><p><strong>When Payment is Required:</strong></p><ul><li>Blocks marked as paid content by the provider</li><li>Provider&#x27;s local policy requires payment for specific blocks</li><li>Block size exceeds free tier threshold (implementation-defined)</li><li>Requester has insufficient credit with provider</li></ul><p><strong>Free Blocks:</strong></p><ul><li>Blocks explicitly marked as free (<code>price = 0x00</code>)</li><li>Blocks exchanged between trusted peers</li><li>Small metadata blocks (implementation-defined)</li></ul><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="price-discovery">Price Discovery<a href="#price-discovery" class="hash-link" aria-label="Direct link to Price Discovery" title="Direct link to Price Discovery"></a></h4><p><strong>Initial Price Advertisement:</strong></p><ol><li>Requester sends WantList with <code>wantType = wantHave</code></li><li>Provider responds with BlockPresence including <code>price</code> field</li><li>Price encoded as UInt256 in wei (smallest Ethereum unit)</li><li>Requester evaluates price against local policy</li></ol><p><strong>Price Format:</strong></p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">price: bytes (32 bytes, big-endian UInt256)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Example: 0x0000000000000000000000000000000000000000000000000de0b6b3a7640000</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> represents 1 ETH = 10^18 wei</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="payment-negotiation-process">Payment Negotiation Process<a href="#payment-negotiation-process" class="hash-link" aria-label="Direct link to Payment Negotiation Process" title="Direct link to Payment Negotiation Process"></a></h4><h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-1-price-quote">Step 1: Price Quote<a href="#step-1-price-quote" class="hash-link" aria-label="Direct link to Step 1: Price Quote" title="Direct link to Step 1: Price Quote"></a></h5><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Requester → Provider: Message(wantlist: wantHave)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Provider → Requester: BlockPresence(type=presenceHave, price=&lt;amount&gt;)</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-2-payment-decision">Step 2: Payment Decision<a href="#step-2-payment-decision" class="hash-link" aria-label="Direct link to Step 2: Payment Decision" title="Direct link to Step 2: Payment Decision"></a></h5><p>Requester evaluates price:</p><ul><li><strong>Accept</strong>: Proceed to payment</li><li><strong>Reject</strong>: Send cancellation</li><li><strong>Counter</strong>: Not supported in current protocol (future extension)</li></ul><h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-3-state-channel-update">Step 3: State Channel Update<a href="#step-3-state-channel-update" class="hash-link" aria-label="Direct link to Step 3: State Channel Update" title="Direct link to Step 3: State Channel Update"></a></h5><p>If accepted:</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Requester:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 1. Load existing state channel with Provider</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 2. Create new state with updated balance</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 3. Sign state update</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 4. Encode as JSON</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Requester → Provider: Message(payment: StateChannelUpdate(update=&lt;signed JSON&gt;))</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-4-payment-verification">Step 4: Payment Verification<a href="#step-4-payment-verification" class="hash-link" aria-label="Direct link to Step 4: Payment Verification" title="Direct link to Step 4: Payment Verification"></a></h5><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Provider:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 1. Decode state channel update</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 2. Verify signatures</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 3. Check balance increase matches price</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 4. Verify state channel validity</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 5. Check nonce/sequence number</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">If valid:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Provider → Requester: BlockDelivery(data, proof)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">Else:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Provider → Requester: BlockPresence(price) // Retry with correct payment</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h5 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="step-5-delivery-and-finalization">Step 5: Delivery and Finalization<a href="#step-5-delivery-and-finalization" class="hash-link" aria-label="Direct link to Step 5: Delivery and Finalization" title="Direct link to Step 5: Delivery and Finalization"></a></h5><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Requester:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 1. Receive and verify block</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 2. Store block locally</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 3. Finalize state channel update</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> 4. Update peer credit balance</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="payment-state-machine">Payment State Machine<a href="#payment-state-machine" class="hash-link" aria-label="Direct link to Payment State Machine" title="Direct link to Payment State Machine"></a></h4><p><strong>Note:</strong> The following state machine represents a <strong>design specification</strong> for
payment flow logic. Actual implementation may differ.</p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">State: INIT</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Send wantHave</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Transition to PRICE_DISCOVERY</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">State: PRICE_DISCOVERY</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ← Receive BlockPresence(price)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → If price acceptable: Transition to PAYMENT_CREATION</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → If price rejected: Transition to CANCELLED</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">State: PAYMENT_CREATION</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Create state channel update</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Send payment message</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Transition to PAYMENT_PENDING</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">State: PAYMENT_PENDING</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ← Receive BlockDelivery: Transition to DELIVERY_VERIFICATION</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ← Receive BlockPresence(price): Transition to PAYMENT_FAILED</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">State: PAYMENT_FAILED</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Retry with corrected payment: Transition to PAYMENT_CREATION</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Abort: Transition to CANCELLED</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">State: DELIVERY_VERIFICATION</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Verify block</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → If valid: Transition to COMPLETED</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → If invalid: Transition to DISPUTE</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">State: COMPLETED</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Finalize state channel</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → End</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">State: CANCELLED</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Send cancellation</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → End</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">State: DISPUTE</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Reject block</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → Dispute state channel update</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> → End</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="state-channel-integration">State Channel Integration<a href="#state-channel-integration" class="hash-link" aria-label="Direct link to State Channel Integration" title="Direct link to State Channel Integration"></a></h4><p><strong>Account Message Usage:</strong></p><p>Sent early in connection to establish payment address:</p><div class="language-protobuf codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-protobuf codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">Message {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> account: AccountMessage {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> address: 0x742d35Cc6634C0532925a3b8... // Ethereum address</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>State Channel Update Format:</strong></p><div class="language-json codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-json codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">&quot;channelId&quot;</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">&quot;0x1234...&quot;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">&quot;nonce&quot;</span><span class="token operator">:</span><span class="token plain"> </span><span class="token number">42</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">&quot;balances&quot;</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">&quot;0x742d35Cc...&quot;</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">&quot;1000000000000000000&quot;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Seller balance</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">&quot;0x8ab5d2F3...&quot;</span><span class="token operator">:</span><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">&quot;500000000000000000&quot;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Buyer balance</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token property">&quot;signatures&quot;</span><span class="token operator">:</span><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">&quot;0x789abc...&quot;</span><span class="token punctuation" style="color:rgb(248, 248, 242)">,</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Buyer signature</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token string" style="color:rgb(255, 121, 198)">&quot;0x456def...&quot;</span><span class="token plain"> </span><span class="token comment" style="color:rgb(98, 114, 164)">// Seller signature</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> </span><span class="token punctuation" style="color:rgb(248, 248, 242)">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><span class="token punctuation" style="color:rgb(248, 248, 242)">}</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-scenarios">Error Scenarios<a href="#error-scenarios" class="hash-link" aria-label="Direct link to Error Scenarios" title="Direct link to Error Scenarios"></a></h4><p><strong>Insufficient Funds:</strong></p><ul><li>State channel balance &lt; block price</li><li>Response: BlockPresence with price (retry after funding)</li></ul><p><strong>Invalid Signature:</strong></p><ul><li>State update signature verification fails</li><li>Response: Reject payment, close stream if repeated</li></ul><p><strong>Nonce Mismatch:</strong></p><ul><li>State update nonce doesn&#x27;t match expected sequence</li><li>Response: Request state sync, retry with correct nonce</li></ul><p><strong>Channel Expired:</strong></p><ul><li>State channel past expiration time</li><li>Response: Refuse payment, request new channel creation</li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling">Error Handling<a href="#error-handling" class="hash-link" aria-label="Direct link to Error Handling" title="Direct link to Error Handling"></a></h2><p>The Block Exchange protocol defines error handling for common failure scenarios:</p><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="verification-failures">Verification Failures<a href="#verification-failures" class="hash-link" aria-label="Direct link to Verification Failures" title="Direct link to Verification Failures"></a></h3><p><strong>Merkle Proof Verification Failure:</strong></p><ul><li><strong>Condition</strong>: CodexProof validation fails for dataset block</li><li><strong>Action</strong>: Reject block delivery, do NOT store block</li><li><strong>Response</strong>: Send BlockPresence with <code>presenceDontHave</code> for the address</li><li><strong>Logging</strong>: Log verification failure with peer ID and block address</li><li><strong>Peer Management</strong>: Track repeated failures; disconnect after threshold</li></ul><p><strong>CID Mismatch:</strong></p><ul><li><strong>Condition</strong>: SHA256 hash of block data doesn&#x27;t match provided CID</li><li><strong>Action</strong>: Reject block delivery immediately</li><li><strong>Response</strong>: Close stream and mark peer as potentially malicious</li><li><strong>Logging</strong>: Log CID mismatch with peer ID and expected/actual CIDs</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="network-failures">Network Failures<a href="#network-failures" class="hash-link" aria-label="Direct link to Network Failures" title="Direct link to Network Failures"></a></h3><p><strong>Stream Disconnection:</strong></p><ul><li><strong>Condition</strong>: libp2p stream closes unexpectedly during transfer</li><li><strong>Action</strong>: Cancel pending block requests for that peer</li><li><strong>Recovery</strong>: Attempt to request blocks from alternative peers</li><li><strong>Timeout</strong>: Wait for stream timeout (60s) before peer cleanup</li></ul><p><strong>Missing Blocks:</strong></p><ul><li><strong>Condition</strong>: Peer responds with <code>presenceDontHave</code> for requested block</li><li><strong>Action</strong>: Remove peer from candidates for this block</li><li><strong>Recovery</strong>: Query discovery service for alternative peers</li><li><strong>Fallback</strong>: If no peers have block, return error to <code>requestBlock</code> caller</li></ul><p><strong>Request Timeout:</strong></p><ul><li><strong>Condition</strong>: Block not received within request timeout (300s)</li><li><strong>Action</strong>: Cancel request with that peer</li><li><strong>Recovery</strong>: Retry with different peer if available</li><li><strong>User Notification</strong>: If all retry attempts exhausted, <code>requestBlock</code> returns timeout error</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="protocol-violations">Protocol Violations<a href="#protocol-violations" class="hash-link" aria-label="Direct link to Protocol Violations" title="Direct link to Protocol Violations"></a></h3><p><strong>Oversized Messages:</strong></p><ul><li><strong>Condition</strong>: Message exceeds maximum size limits</li><li><strong>Action</strong>: Close stream immediately</li><li><strong>Peer Management</strong>: Mark peer as non-compliant</li><li><strong>No Response</strong>: Do not send error message (message may be malicious)</li></ul><p><strong>Invalid WantList:</strong></p><ul><li><strong>Condition</strong>: WantList exceeds entry limit or contains malformed addresses</li><li><strong>Action</strong>: Ignore malformed entries, process valid ones</li><li><strong>Response</strong>: Continue processing stream</li><li><strong>Logging</strong>: Log validation errors for debugging</li></ul><p><strong>Payment Failures:</strong></p><ul><li><strong>Condition</strong>: State channel update invalid or payment insufficient</li><li><strong>Action</strong>: Do not deliver blocks requiring payment</li><li><strong>Response</strong>: Send BlockPresence with price indicating payment needed</li><li><strong>Stream</strong>: Keep stream open for payment retry</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="recovery-strategies">Recovery Strategies<a href="#recovery-strategies" class="hash-link" aria-label="Direct link to Recovery Strategies" title="Direct link to Recovery Strategies"></a></h3><h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="retry-responsibility-model">Retry Responsibility Model<a href="#retry-responsibility-model" class="hash-link" aria-label="Direct link to Retry Responsibility Model" title="Direct link to Retry Responsibility Model"></a></h4><p>The protocol defines a clear separation between system-level and caller-level
retry responsibilities:</p><p><strong>System-Level Retry (Automatic):</strong></p><p>The Block Exchange module automatically retries in these scenarios:</p><ul><li><strong>Peer failure</strong>: If a peer disconnects or times out, the system
transparently tries alternative peers from the discovery set</li><li><strong>Transient errors</strong>: Network glitches, temporary unavailability</li><li><strong>Peer rotation</strong>: Automatic failover to next available peer</li></ul><p>The caller&#x27;s <code>requestBlock</code> call remains pending during system-level retries.
This is transparent to the caller.</p><p><strong>Caller-Level Retry (Manual):</strong></p><p>The caller is responsible for retry decisions when:</p><ul><li><strong>All peers exhausted</strong>: No more peers available from discovery</li><li><strong>Permanent failures</strong>: Block doesn&#x27;t exist in the network</li><li><strong>Timeout exceeded</strong>: Request timeout (300s) expired</li><li><strong>Verification failures</strong>: All peers provided invalid data</li></ul><p>In these cases, <code>requestBlock</code> returns an error and the caller decides
whether to retry, perhaps after waiting or refreshing the peer list
via discovery.</p><p><strong>Retry Flow:</strong></p><div class="language-text codeBlockContainer_EB2s codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:rgba(var(--lsd-surface-secondary), 0.08)"><div class="codeBlockContent_ugSV"><pre tabindex="0" class="prism-code language-text codeBlock_TWhw thin-scrollbar"><code class="codeBlockLines_LDrR"><span class="token-line" style="color:#F8F8F2"><span class="token plain">requestBlock(address)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ├─► System tries Peer A ──► Fails</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ │</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ └─► System tries Peer B ──► Fails (automatic, transparent)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ │</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> │ └─► System tries Peer C ──► Success ──► Return block</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> └─► All peers failed ──► Return error to caller</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> └─► Caller decides: retry? wait? abort?</span><br></span></code></pre><div class="buttonGroup_Qu4e"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_an20" aria-hidden="true"><div class="icon_S7Kx m_thRi copyButtonIcon_ZL7v"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M2.917 12.833c-.321 0-.596-.114-.825-.343a1.121 1.121 0 0 1-.342-.823V3.5h1.167v8.167h6.416v1.166H2.917ZM5.25 10.5c-.32 0-.596-.114-.824-.343a1.121 1.121 0 0 1-.343-.824v-7c0-.32.115-.595.343-.824.229-.229.504-.343.824-.342h5.25c.32 0 .596.114.824.343.229.228.343.503.343.823v7c0 .321-.115.596-.343.825a1.121 1.121 0 0 1-.824.342H5.25Zm0-1.167h5.25v-7H5.25v7Z" fill="#fff"></path></svg></div></span></button></div></div></div><p><strong>Peer Rotation:</strong></p><p>When a peer fails to deliver blocks:</p><ol><li>Mark peer as temporarily unavailable for this block</li><li>Query discovery service for alternative peers</li><li>Send WantList to new peers</li><li>Implement exponential backoff before retrying failed peer</li></ol><p><strong>Graceful Degradation:</strong></p><ul><li>If verification fails, request block from alternative peer</li><li>If all peers fail, propagate error to caller</li><li>Clean up resources (memory, pending requests) on unrecoverable failures</li></ul><p><strong>Error Propagation:</strong></p><ul><li>Service interface functions (<code>requestBlock</code>, <code>cancelRequest</code>) return errors
to callers only after system-level retries are exhausted</li><li>Internal errors logged for debugging</li><li>Network errors trigger automatic peer rotation before surfacing to caller</li><li>Verification errors result in block rejection and peer reputation impact</li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="security-considerations">Security Considerations<a href="#security-considerations" class="hash-link" aria-label="Direct link to Security Considerations" title="Direct link to Security Considerations"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="block-verification">Block Verification<a href="#block-verification" class="hash-link" aria-label="Direct link to Block Verification" title="Direct link to Block Verification"></a></h3><ul><li>All dataset blocks MUST include and verify Merkle proofs before acceptance</li><li>Standalone blocks MUST verify CID matches the SHA256 hash of the data</li><li>Peers SHOULD reject blocks that fail verification immediately</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="dos-protection">DoS Protection<a href="#dos-protection" class="hash-link" aria-label="Direct link to DoS Protection" title="Direct link to DoS Protection"></a></h3><ul><li>Implementations SHOULD limit the number of concurrent block requests per peer</li><li>Implementations SHOULD implement rate limiting for WantList updates</li><li>Large WantLists MAY be rejected to prevent resource exhaustion</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="data-integrity">Data Integrity<a href="#data-integrity" class="hash-link" aria-label="Direct link to Data Integrity" title="Direct link to Data Integrity"></a></h3><ul><li>All blocks MUST be validated before being stored or forwarded</li><li>Zero-padding in dataset blocks MUST be verified to prevent data corruption</li><li>Block sizes MUST be validated against protocol limits</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="privacy-considerations">Privacy Considerations<a href="#privacy-considerations" class="hash-link" aria-label="Direct link to Privacy Considerations" title="Direct link to Privacy Considerations"></a></h3><ul><li>Block requests reveal information about what data a peer is seeking</li><li>Implementations MAY implement request obfuscation strategies</li><li>Presence information can leak storage capacity details</li></ul><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="rationale">Rationale<a href="#rationale" class="hash-link" aria-label="Direct link to Rationale" title="Direct link to Rationale"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="design-decisions">Design Decisions<a href="#design-decisions" class="hash-link" aria-label="Direct link to Design Decisions" title="Direct link to Design Decisions"></a></h3><p><strong>Two-Tier Block Addressing:</strong>
The protocol supports both standalone and dataset blocks to accommodate
different use cases.
Standalone blocks are simpler and don&#x27;t require Merkle proofs, while
dataset blocks enable efficient verification of large datasets without
requiring the entire dataset.</p><p><strong>WantList Delta Updates:</strong>
Supporting delta updates reduces bandwidth consumption when peers only
need to modify a small portion of their wants, which is common in
long-lived connections.</p><p><strong>Separate Presence Messages:</strong>
Decoupling presence information from block delivery allows peers to
quickly assess availability without waiting for full block transfers.</p><p><strong>Fixed Block Size:</strong>
The 64 KiB default block size balances efficient network transmission
with manageable memory overhead.</p><p><strong>Zero-Padding Requirement:</strong>
Requiring zero-padding for incomplete dataset blocks ensures uniform
block sizes within datasets, simplifying Merkle tree construction and
verification.</p><p><strong>Protocol Buffers:</strong>
Using Protocol Buffers provides efficient serialization, forward
compatibility, and wide language support.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="copyright">Copyright<a href="#copyright" class="hash-link" aria-label="Direct link to Copyright" title="Direct link to Copyright"></a></h2><p>Copyright and related rights waived via
<a href="https://creativecommons.org/publicdomain/zero/1.0/" target="_blank" rel="noopener noreferrer">CC0</a>.</p><h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="references">References<a href="#references" class="hash-link" aria-label="Direct link to References" title="Direct link to References"></a></h2><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="normative">Normative<a href="#normative" class="hash-link" aria-label="Direct link to Normative" title="Direct link to Normative"></a></h3><ul><li><a href="https://www.ietf.org/rfc/rfc2119.txt" target="_blank" rel="noopener noreferrer">RFC 2119</a> - Key words for use
in RFCs to Indicate Requirement Levels</li><li><strong>libp2p</strong>: &lt;<a href="https://libp2p.io" target="_blank" rel="noopener noreferrer">https://libp2p.io</a>&gt;</li><li><strong>Protocol Buffers</strong>: &lt;<a href="https://protobuf.dev" target="_blank" rel="noopener noreferrer">https://protobuf.dev</a>&gt;</li><li><strong>Multihash</strong>: &lt;<a href="https://multiformats.io/multihash/" target="_blank" rel="noopener noreferrer">https://multiformats.io/multihash/</a>&gt;</li><li><strong>Multicodec</strong>: &lt;<a href="https://github.com/multiformats/multicodec" target="_blank" rel="noopener noreferrer">https://github.com/multiformats/multicodec</a>&gt;</li></ul><h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="informative">Informative<a href="#informative" class="hash-link" aria-label="Direct link to Informative" title="Direct link to Informative"></a></h3><ul><li><strong>Codex Documentation</strong>: &lt;<a href="https://docs.codex.storage" target="_blank" rel="noopener noreferrer">https://docs.codex.storage</a>&gt;</li><li><strong>Codex Block Exchange Module Spec</strong>:
&lt;<a href="https://github.com/codex-storage/codex-docs-obsidian/blob/main/10%20Notes/Specs/Block%20Exchange%20Module%20Spec.md" target="_blank" rel="noopener noreferrer">https://github.com/codex-storage/codex-docs-obsidian/blob/main/10%20Notes/Specs/Block%20Exchange%20Module%20Spec.md</a>&gt;</li><li><strong>Merkle Trees</strong>: &lt;<a href="https://en.wikipedia.org/wiki/Merkle_tree" target="_blank" rel="noopener noreferrer">https://en.wikipedia.org/wiki/Merkle_tree</a>&gt;</li><li><strong>Content Addressing</strong>:
&lt;<a href="https://en.wikipedia.org/wiki/Content-addressable_storage" target="_blank" rel="noopener noreferrer">https://en.wikipedia.org/wiki/Content-addressable_storage</a>&gt;</li></ul></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/codex/"><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="M11.667 6.417h-7.1l3.261-3.261L7 2.333 2.333 7 7 11.667l.823-.823-3.255-3.26h7.099V6.417Z" fill="#fff"></path></svg></div><span class="lsd-typography lsd-typography--body2 pagination-nav__label">Codex RFCs</span></a><a class="pagination-nav__link pagination-nav__link--next" href="/codex/raw/codex-marketplace"><span class="lsd-typography lsd-typography--body2 pagination-nav__label">CODEX-MARKETPLACE</span><div class="icon_S7Kx m_thRi"><svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg" role="img"><path d="m7 2.333-.823.823 3.255 3.26H2.333v1.167h7.1l-3.256 3.261.823.823L11.667 7 7 2.333Z" fill="#fff"></path></svg></div></a></nav></div></div><div class="gap1_XuuQ"></div><div class="toc_pP_5"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#specification-status" class="table-of-contents__link toc-highlight">Specification Status</a></li><li><a href="#abstract" class="table-of-contents__link toc-highlight">Abstract</a></li><li><a href="#semantics" class="table-of-contents__link toc-highlight">Semantics</a><ul><li><a href="#definitions" class="table-of-contents__link toc-highlight">Definitions</a></li></ul></li><li><a href="#motivation" class="table-of-contents__link toc-highlight">Motivation</a></li><li><a href="#block-format" class="table-of-contents__link toc-highlight">Block Format</a><ul><li><a href="#standalone-blocks" class="table-of-contents__link toc-highlight">Standalone Blocks</a></li><li><a href="#dataset-blocks" class="table-of-contents__link toc-highlight">Dataset Blocks</a></li><li><a href="#block-specifications" class="table-of-contents__link toc-highlight">Block Specifications</a></li><li><a href="#protocol-limits" class="table-of-contents__link toc-highlight">Protocol Limits</a></li></ul></li><li><a href="#service-interface" class="table-of-contents__link toc-highlight">Service Interface</a><ul><li><a href="#requestblock" class="table-of-contents__link toc-highlight"><code>requestBlock</code></a></li><li><a href="#cancelrequest" class="table-of-contents__link toc-highlight"><code>cancelRequest</code></a></li></ul></li><li><a href="#dependencies" class="table-of-contents__link toc-highlight">Dependencies</a></li><li><a href="#protocol-specification" class="table-of-contents__link toc-highlight">Protocol Specification</a><ul><li><a href="#protocol-identifier" class="table-of-contents__link toc-highlight">Protocol Identifier</a></li><li><a href="#version-negotiation" class="table-of-contents__link toc-highlight">Version Negotiation</a></li><li><a href="#connection-model" class="table-of-contents__link toc-highlight">Connection Model</a></li><li><a href="#message-flow-examples" class="table-of-contents__link toc-highlight">Message Flow Examples</a></li><li><a href="#sequence-diagrams" class="table-of-contents__link toc-highlight">Sequence Diagrams</a></li><li><a href="#message-format" class="table-of-contents__link toc-highlight">Message Format</a></li><li><a href="#concrete-message-examples" class="table-of-contents__link toc-highlight">Concrete Message Examples</a></li><li><a href="#payment-flow-and-price-negotiation" class="table-of-contents__link toc-highlight">Payment Flow and Price Negotiation</a></li></ul></li><li><a href="#error-handling" class="table-of-contents__link toc-highlight">Error Handling</a><ul><li><a href="#verification-failures" class="table-of-contents__link toc-highlight">Verification Failures</a></li><li><a href="#network-failures" class="table-of-contents__link toc-highlight">Network Failures</a></li><li><a href="#protocol-violations" class="table-of-contents__link toc-highlight">Protocol Violations</a></li><li><a href="#recovery-strategies" class="table-of-contents__link toc-highlight">Recovery Strategies</a></li></ul></li><li><a href="#security-considerations" class="table-of-contents__link toc-highlight">Security Considerations</a><ul><li><a href="#block-verification" class="table-of-contents__link toc-highlight">Block Verification</a></li><li><a href="#dos-protection" class="table-of-contents__link toc-highlight">DoS Protection</a></li><li><a href="#data-integrity" class="table-of-contents__link toc-highlight">Data Integrity</a></li><li><a href="#privacy-considerations" class="table-of-contents__link toc-highlight">Privacy Considerations</a></li></ul></li><li><a href="#rationale" class="table-of-contents__link toc-highlight">Rationale</a><ul><li><a href="#design-decisions" class="table-of-contents__link toc-highlight">Design Decisions</a></li></ul></li><li><a href="#copyright" class="table-of-contents__link toc-highlight">Copyright</a></li><li><a href="#references" class="table-of-contents__link toc-highlight">References</a><ul><li><a href="#normative" class="table-of-contents__link toc-highlight">Normative</a></li><li><a href="#informative" class="table-of-contents__link toc-highlight">Informative</a></li></ul></li></ul></div></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid firstRow_ar1q"><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a class="footerLogoLink_BH7S" href="/"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--light_BL8e footer__logo" width="22"><img src="/theme/image/logo.svg" alt="Vac Research" class="themedImage_kfRS themedImage--dark_OvIx footer__logo" width="22"></a></div><div class="footer__copyright">Vac @2025<br>All Rights Reserved.</div></div><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://x.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://discord.gg/PQFdubGt6d" target="_blank" rel="noopener noreferrer" class="footer__link-item">Discord<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://github.com/vacp2p" target="_blank" rel="noopener noreferrer" class="footer__link-item">Github<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://jobs.status.im/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Work with us<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a class="footer__link-item" href="/terms">Terms &amp; conditions</a></li><li class="footer__item"><a class="footer__link-item" href="/privacy-policy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" href="/security">Security</a></li></ul></div></div></div><div class="secondRow__ww3"><span class="footer__bottom text--center">Built by <a href="https://free.technology/" target="_blank" class="footerLink_sh7M">IFT</a></span><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Research</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://vac.dev" target="_blank" rel="noopener noreferrer" class="footer__link-item">VacP2P<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://afaik.institute" target="_blank" rel="noopener noreferrer" class="footer__link-item">AFAIK<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Infrastructure</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://waku.org/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Waku<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://nimbus.team/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nimbus<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://codex.storage" target="_blank" rel="noopener noreferrer" class="footer__link-item">Codex<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://nomos.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Nomos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Creative Studio</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://acid.info" target="_blank" rel="noopener noreferrer" class="footer__link-item">Acid.info<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">Movement</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://logos.co" target="_blank" rel="noopener noreferrer" class="footer__link-item">Logos<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div><div class="col footer__col"><div class="footer__title">User-facing products</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://status.im" target="_blank" rel="noopener noreferrer" class="footer__link-item">Status<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://keycard.tech" target="_blank" rel="noopener noreferrer" class="footer__link-item">Keycard<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div></div></div><button class="backToTop_wDfN lsd-button lsd-button--small lsd-button--outlined"><span class="lsd-typography lsd-typography--label2 lsd-button__text">Back to top ↑</span></button></footer></div></div>
<script src="/assets/js/runtime~main.db01e95f.js"></script>
<script src="/assets/js/main.7bd63d25.js"></script>
</body>
</html>