[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6GY5VTH09QTT41HTDHVE12S":3,"skill-same:01M6GY5VTH09QTT41HTDHVE12S":78},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":19,"publishedAt":36,"linkOnly":37,"markdownContent":38,"markdownBody":39,"frontMatter":40,"refName":41,"commitSha":42,"skillDirectory":43,"forksCount":44,"repositoryHtmlUrl":45,"repositoryHomepageUrl":6,"ownerHtmlUrl":46,"ownerBlogUrl":47,"ownerDescription":48,"updatedAt":49,"install":50,"resources":63},"01M6GY5VTH09QTT41HTDHVE12S","decode-a-rollup-batch-from-l1-calldata",null,"Use when reconstructing an L2 batch from the L1 batch-inbox transaction (calldata or blob) for indexing, verification, or a data-availability check.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",81,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-decode-a-rollup-batch-from-l1-calldata\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-decode-a-rollup-batch-from-l1-calldata\u002FSKILL.md",[],[20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"batch","rollup","decode a rollup batch from l1 calldata","decode","inbox","verification","data","check","use","transaction","indexing","availability","l2","for","blob","when","2026-11-10 10:12:30",false,"---\nname: decode-a-rollup-batch-from-l1-calldata\ndescription: Use when reconstructing an L2 batch from the L1 batch-inbox transaction (calldata or blob) for indexing, verification, or a data-availability check.\n---\n\n# Decode a rollup batch from L1 calldata\n\nThe L1 batch-inbox transaction is the ground truth for an L2's data, but it is framed, often\ncompressed, and split across transactions — so decoding means reassembling frames into channels before\nyou can parse L2 blocks.\n\n## Procedure\n\n1. Locate the batch-posting transaction. On OP Stack everything sent to the batch inbox address\n   `0x00...FF00000000000000000000000000000000000010` (the `BatchInboxAddress`, `0xFF` followed by\n   zeros and `10`) is batcher data; find recent ones:\n\n       cast logs --from-block $RECENT --to-block latest --address 0xFF00000000000000000000000000000000000010 --rpc-url $L1RPC\n\n2. Fetch the raw input. Post-Dencun a batcher may post blobs; check the tx type and grab calldata or\n   the blob sidecar:\n\n       cast tx $BATCH_TX --json --rpc-url $L1RPC | jq '{type, input, blobVersionedHashes}'\n\n3. Parse the channel frame format (OP Stack version 0): `channel_id (16 bytes) || frame_number (2) ||\n   frame_data_length (4) || frame_data`. Frames of the same channel can be spread across transactions;\n   reassemble by `channel_id`, concatenate frame data in `frame_number` order, and require all frames.\n\n4. Decompress the reassembled channel. OP Stack channels are zlib-compressed, so inflate to get the\n   batch stream. If you skipped a frame you will get a decompression error — that is the signal a frame\n   is missing, not corrupt data:\n\n       python3 - \u003C\u003C'PY'\n       import zlib\n       data = open('channel.bin','rb').read()\n       print(len(zlib.decompress(data)))\n       PY\n\n5. Split the decompressed stream into batches (span-batch format version 1: block timestamp, block\n   number, tx count, then per-tx fields), yielding the L2 blocks and their transactions.\n\n6. Cross-check the reconstruction against the chain: the derived L2 block must hash to the state root\n   that was committed, and the block header fields must match what the L2 RPC reports for that height.\n   A mismatch means a decoding bug or a frame you missed.\n\n7. Arbitrum instead uses a `SequencerInbox` batch with its own header and brotli compression; adjust\n   the framer and decompressor to the chain's format rather than assuming the OP layout.\n\n## Pitfalls\n\n- Assuming one transaction is one channel; frames split across many L1 txs and must be joined by\n  channel id, which is why a naive per-tx decode fails at block boundaries.\n- Hard-coding zlib when the chain uses brotli (Arbitrum) or a different compression level.\n- Reading calldata when the batch went in a blob; the tx input is empty and the data is in the sidecar.\n- Losing the frame because you started from a later L1 block than the channel's first frame — always\n  scan back a few hours for stragglers.\n- Trusting the reconstructed blocks without the state-root check, missing a silent frame corruption.\n\n## Verification\n\n    cast tx $BATCH_TX --json --rpc-url $L1RPC | jq -r .input | cut -c1-100\n    python3 -c \"import zlib;d=open('channel.bin','rb').read();print('ok',len(zlib.decompress(d)))\"\n    # decoded L2 block header must match cast block $N --rpc-url $L2RPC\n\nReport the batch-inbox tx hash, the number of frames\u002Fchannels reassembled, the decompressed size, and\nwhether the derived block matches the committed state root.\n","# Decode a rollup batch from L1 calldata\n\nThe L1 batch-inbox transaction is the ground truth for an L2's data, but it is framed, often\ncompressed, and split across transactions — so decoding means reassembling frames into channels before\nyou can parse L2 blocks.\n\n## Procedure\n\n1. Locate the batch-posting transaction. On OP Stack everything sent to the batch inbox address\n   `0x00...FF00000000000000000000000000000000000010` (the `BatchInboxAddress`, `0xFF` followed by\n   zeros and `10`) is batcher data; find recent ones:\n\n       cast logs --from-block $RECENT --to-block latest --address 0xFF00000000000000000000000000000000000010 --rpc-url $L1RPC\n\n2. Fetch the raw input. Post-Dencun a batcher may post blobs; check the tx type and grab calldata or\n   the blob sidecar:\n\n       cast tx $BATCH_TX --json --rpc-url $L1RPC | jq '{type, input, blobVersionedHashes}'\n\n3. Parse the channel frame format (OP Stack version 0): `channel_id (16 bytes) || frame_number (2) ||\n   frame_data_length (4) || frame_data`. Frames of the same channel can be spread across transactions;\n   reassemble by `channel_id`, concatenate frame data in `frame_number` order, and require all frames.\n\n4. Decompress the reassembled channel. OP Stack channels are zlib-compressed, so inflate to get the\n   batch stream. If you skipped a frame you will get a decompression error — that is the signal a frame\n   is missing, not corrupt data:\n\n       python3 - \u003C\u003C'PY'\n       import zlib\n       data = open('channel.bin','rb').read()\n       print(len(zlib.decompress(data)))\n       PY\n\n5. Split the decompressed stream into batches (span-batch format version 1: block timestamp, block\n   number, tx count, then per-tx fields), yielding the L2 blocks and their transactions.\n\n6. Cross-check the reconstruction against the chain: the derived L2 block must hash to the state root\n   that was committed, and the block header fields must match what the L2 RPC reports for that height.\n   A mismatch means a decoding bug or a frame you missed.\n\n7. Arbitrum instead uses a `SequencerInbox` batch with its own header and brotli compression; adjust\n   the framer and decompressor to the chain's format rather than assuming the OP layout.\n\n## Pitfalls\n\n- Assuming one transaction is one channel; frames split across many L1 txs and must be joined by\n  channel id, which is why a naive per-tx decode fails at block boundaries.\n- Hard-coding zlib when the chain uses brotli (Arbitrum) or a different compression level.\n- Reading calldata when the batch went in a blob; the tx input is empty and the data is in the sidecar.\n- Losing the frame because you started from a later L1 block than the channel's first frame — always\n  scan back a few hours for stragglers.\n- Trusting the reconstructed blocks without the state-root check, missing a silent frame corruption.\n\n## Verification\n\n    cast tx $BATCH_TX --json --rpc-url $L1RPC | jq -r .input | cut -c1-100\n    python3 -c \"import zlib;d=open('channel.bin','rb').read();print('ok',len(zlib.decompress(d)))\"\n    # decoded L2 block header must match cast block $N --rpc-url $L2RPC\n\nReport the batch-inbox tx hash, the number of frames\u002Fchannels reassembled, the decompressed size, and\nwhether the derived block matches the committed state root.\n",{"name":5,"description":7},"main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Fpayments\u002F0xklen-decode-a-rollup-batch-from-l1-calldata",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-15 02:28:10",{"source":8,"skillName":5,"commands":51,"prompt":61,"zipAvailable":62},[52,55,58],{"tool":53,"command":54},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill decode-a-rollup-batch-from-l1-calldata",{"tool":56,"command":57},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill decode-a-rollup-batch-from-l1-calldata",{"tool":59,"command":60},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill decode-a-rollup-batch-from-l1-calldata","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-decode-a-rollup-batch-from-l1-calldata\u002FSKILL.md",true,[64,68,74],{"path":65,"resourceType":65,"resourceTypeDesc":66,"sizeBytes":67,"sourceHtmlUrl":16},"LICENSE","许可证",1063,{"path":69,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":72,"sourceHtmlUrl":73},"SOURCE.md","REFERENCE","参考文档",364,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-decode-a-rollup-batch-from-l1-calldata\u002FSOURCE.md",{"path":75,"resourceType":70,"resourceTypeDesc":71,"sizeBytes":76,"sourceHtmlUrl":77},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-decode-a-rollup-batch-from-l1-calldata\u002FTRUST.auto.yaml",[79,107,129,146,159,169],{"skillNo":80,"name":81,"nameZh":6,"description":82,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":83,"sourceHtmlUrl":84,"categories":85,"keywords":86,"publishedAt":36},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106],"performance","recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":108,"name":109,"nameZh":6,"description":110,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":111,"licenseFileUrl":112,"sourceHtmlUrl":113,"categories":114,"keywords":115,"publishedAt":36},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[116,117,118,119,120,121,122,123,124,125,33,126,127,128],"mexc spot websocket","spot","websocket","api","workflows","public","listen","streams","depth","keys","api keys","maintenance","protobuf",{"skillNo":130,"name":131,"nameZh":6,"description":132,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":111,"licenseFileUrl":133,"sourceHtmlUrl":134,"categories":135,"keywords":136,"publishedAt":36},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[137,117,138,139,140,141,142,126,33,125,143,144,26,121,145,120,119],"mexc spot rest","REST","admin","signing","Wallet","requests","actions","secure","orders",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":111,"licenseFileUrl":150,"sourceHtmlUrl":151,"categories":152,"keywords":153,"publishedAt":36},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[154,155,118,156,157,127,33,158,124,123,121,120],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":160,"name":161,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":162,"sourceHtmlUrl":163,"categories":164,"keywords":165,"publishedAt":36},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[166,167,168],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":170,"name":171,"nameZh":6,"description":172,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":173,"sourceHtmlUrl":174,"categories":175,"keywords":176,"publishedAt":36},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[177,178,179,180,181,182,183,28,184,185,186],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","patch","code","share"]