[{"data":1,"prerenderedAt":829},["ShallowReactive",2],{"navigation_docs":3,"-guide-custom":196,"-guide-custom-surround":824},[4,44],{"title":5,"path":6,"stem":7,"children":8,"icon":43},"Guide","\u002Fguide","1.guide\u002F01.index",[9,11,15,19,23,27,31,35,39],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Registry and aliases","\u002Fguide\u002Fregistry","1.guide\u002F02.registry",{"title":16,"path":17,"stem":18},"Address validation","\u002Fguide\u002Fvalidation","1.guide\u002F03.validation",{"title":20,"path":21,"stem":22},"Identify","\u002Fguide\u002Fidentify","1.guide\u002F04.identify",{"title":24,"path":25,"stem":26},"Metadata","\u002Fguide\u002Fmetadata","1.guide\u002F05.metadata",{"title":28,"path":29,"stem":30},"CLI","\u002Fguide\u002Fcli","1.guide\u002F06.cli",{"title":32,"path":33,"stem":34},"Agents","\u002Fguide\u002Fagents","1.guide\u002F07.agents",{"title":36,"path":37,"stem":38},"Custom chains","\u002Fguide\u002Fcustom","1.guide\u002F08.custom",{"title":40,"path":41,"stem":42},"Playground","\u002Fguide\u002Fplayground","1.guide\u002F09.playground","i-lucide-book-open",{"title":45,"path":46,"stem":47,"children":48,"icon":195},"Chains","\u002Fchains","2.chains\u002F00.index",[49,51,55,59,63,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143,147,151,155,159,163,167,171,175,179,183,187,191],{"title":50,"path":46,"stem":47},"Overview",{"title":52,"path":53,"stem":54},"Ethereum","\u002Fchains\u002Fethereum","2.chains\u002F01.ethereum",{"title":56,"path":57,"stem":58},"Base","\u002Fchains\u002Fbase","2.chains\u002F02.base",{"title":60,"path":61,"stem":62},"Arbitrum One","\u002Fchains\u002Farbitrum","2.chains\u002F03.arbitrum",{"title":64,"path":65,"stem":66},"Optimism","\u002Fchains\u002Foptimism","2.chains\u002F04.optimism",{"title":68,"path":69,"stem":70},"Polygon PoS","\u002Fchains\u002Fpolygon","2.chains\u002F05.polygon",{"title":72,"path":73,"stem":74},"BNB Chain","\u002Fchains\u002Fbsc","2.chains\u002F06.bsc",{"title":76,"path":77,"stem":78},"Avalanche C-Chain","\u002Fchains\u002Favalanche","2.chains\u002F07.avalanche",{"title":80,"path":81,"stem":82},"Fantom Opera","\u002Fchains\u002Ffantom","2.chains\u002F08.fantom",{"title":84,"path":85,"stem":86},"Gnosis Chain","\u002Fchains\u002Fgnosis","2.chains\u002F09.gnosis",{"title":88,"path":89,"stem":90},"Linea","\u002Fchains\u002Flinea","2.chains\u002F10.linea",{"title":92,"path":93,"stem":94},"zkSync Era","\u002Fchains\u002Fzksync","2.chains\u002F11.zksync",{"title":96,"path":97,"stem":98},"Scroll","\u002Fchains\u002Fscroll","2.chains\u002F12.scroll",{"title":100,"path":101,"stem":102},"Berachain","\u002Fchains\u002Fberachain","2.chains\u002F13.berachain",{"title":104,"path":105,"stem":106},"Bitcoin","\u002Fchains\u002Fbitcoin","2.chains\u002F14.bitcoin",{"title":108,"path":109,"stem":110},"Litecoin","\u002Fchains\u002Flitecoin","2.chains\u002F15.litecoin",{"title":112,"path":113,"stem":114},"Pepecoin","\u002Fchains\u002Fpepecoin","2.chains\u002F16.pepecoin",{"title":116,"path":117,"stem":118},"eCash","\u002Fchains\u002Fecash","2.chains\u002F17.ecash",{"title":120,"path":121,"stem":122},"Cardano","\u002Fchains\u002Fcardano","2.chains\u002F18.cardano",{"title":124,"path":125,"stem":126},"Solana","\u002Fchains\u002Fsolana","2.chains\u002F19.solana",{"title":128,"path":129,"stem":130},"Stellar","\u002Fchains\u002Fstellar","2.chains\u002F20.stellar",{"title":132,"path":133,"stem":134},"XRP Ledger","\u002Fchains\u002Fxrpl","2.chains\u002F21.xrpl",{"title":136,"path":137,"stem":138},"Aptos","\u002Fchains\u002Faptos","2.chains\u002F22.aptos",{"title":140,"path":141,"stem":142},"Sui","\u002Fchains\u002Fsui","2.chains\u002F23.sui",{"title":144,"path":145,"stem":146},"TON (The Open Network)","\u002Fchains\u002Fton","2.chains\u002F24.ton",{"title":148,"path":149,"stem":150},"TRON","\u002Fchains\u002Ftron","2.chains\u002F25.tron",{"title":152,"path":153,"stem":154},"Octra","\u002Fchains\u002Foctra","2.chains\u002F26.octra",{"title":156,"path":157,"stem":158},"Arweave","\u002Fchains\u002Farweave","2.chains\u002F27.arweave",{"title":160,"path":161,"stem":162},"Monero","\u002Fchains\u002Fmonero","2.chains\u002F28.monero",{"title":164,"path":165,"stem":166},"Decred","\u002Fchains\u002Fdecred","2.chains\u002F29.decred",{"title":168,"path":169,"stem":170},"Arc","\u002Fchains\u002Farc","2.chains\u002F30.arc",{"title":172,"path":173,"stem":174},"Dogecoin","\u002Fchains\u002Fdogecoin","2.chains\u002F31.dogecoin",{"title":176,"path":177,"stem":178},"Bitcoin Cash","\u002Fchains\u002Fbitcoincash","2.chains\u002F32.bitcoincash",{"title":180,"path":181,"stem":182},"Bitcoin SV","\u002Fchains\u002Fbitcoinsv","2.chains\u002F33.bitcoinsv",{"title":184,"path":185,"stem":186},"Bitcoin Gold","\u002Fchains\u002Fbitcoingold","2.chains\u002F34.bitcoingold",{"title":188,"path":189,"stem":190},"Dash","\u002Fchains\u002Fdash","2.chains\u002F35.dash",{"title":192,"path":193,"stem":194},"Zcash","\u002Fchains\u002Fzcash","2.chains\u002F36.zcash","i-lucide-link",{"id":197,"title":36,"body":198,"description":817,"extension":818,"links":819,"meta":820,"navigation":278,"path":37,"seo":822,"stem":38,"__hash__":823},"docs\u002F1.guide\u002F08.custom.md",{"type":199,"value":200,"toc":811},"minimark",[201,206,223,556,620,642,646,765,769,780,784,807],[202,203,205],"h2",{"id":204},"one-class-one-file","One class, one file",[207,208,209,210,214,215,218,219,222],"p",{},"Every built-in is a concrete class extending the exported abstract ",[211,212,213],"code",{},"Chain",", or ",[211,216,217],{},"EVM"," and ",[211,220,221],{},"Move"," when the address format is theirs. Yours is the same shape:",[224,225,231],"pre",{"className":226,"code":227,"filename":228,"language":229,"meta":230,"style":230},"language-ts shiki shiki-themes chains chains chains","import { Chain, InvalidAddressError, register } from \"@agntn\u002Fchains\";\nimport type { ChainKey, ChainType } from \"@agntn\u002Fchains\";\n\n\u002F** The shape of a Nano account. Its checksum stays unchecked here. *\u002F\nconst ADDRESS = \u002F^nano_[13][13456789abcdefghijkmnopqrstuwxyz]{59}$\u002F;\n\nclass Nano extends Chain {\n  static readonly key = \"nano\" as ChainKey;\n  readonly type = \"nano\" as ChainType;\n  readonly name = \"Nano\";\n  readonly symbol = \"XNO\";\n  override readonly decimals = 30;\n  readonly explorer = \"https:\u002F\u002Fnanexplorer.com\u002Fnano\";\n  readonly bip44 = 165;\n\n  override assertAddress(address: string): string {\n    if (!ADDRESS.test(address)) throw new InvalidAddressError(this.key, address);\n    return address;\n  }\n}\n\nregister(Nano);\n","nano.ts","ts","",[211,232,233,256,273,280,287,316,321,337,362,382,397,412,428,443,456,461,488,521,530,536,542,547],{"__ignoreMap":230},[234,235,238,242,246,249,253],"span",{"class":236,"line":237},"line",1,[234,239,241],{"class":240},"skH_V","import",[234,243,245],{"class":244},"s38Sx"," { Chain, InvalidAddressError, register } ",[234,247,248],{"class":240},"from",[234,250,252],{"class":251},"shU9J"," \"@agntn\u002Fchains\"",[234,254,255],{"class":244},";\n",[234,257,259,261,264,267,269,271],{"class":236,"line":258},2,[234,260,241],{"class":240},[234,262,263],{"class":240}," type",[234,265,266],{"class":244}," { ChainKey, ChainType } ",[234,268,248],{"class":240},[234,270,252],{"class":251},[234,272,255],{"class":244},[234,274,276],{"class":236,"line":275},3,[234,277,279],{"emptyLinePlaceholder":278},true,"\n",[234,281,283],{"class":236,"line":282},4,[234,284,286],{"class":285},"scIB-","\u002F** The shape of a Nano account. Its checksum stays unchecked here. *\u002F\n",[234,288,290,293,296,299,302,305,308,311,314],{"class":236,"line":289},5,[234,291,292],{"class":240},"const",[234,294,295],{"class":244}," ADDRESS ",[234,297,298],{"class":240},"=",[234,300,301],{"class":251}," \u002F",[234,303,304],{"class":240},"^",[234,306,307],{"class":251},"nano_[13][13456789abcdefghijkmnopqrstuwxyz]",[234,309,310],{"class":240},"{59}$",[234,312,313],{"class":251},"\u002F",[234,315,255],{"class":244},[234,317,319],{"class":236,"line":318},6,[234,320,279],{"emptyLinePlaceholder":278},[234,322,324,327,331,334],{"class":236,"line":323},7,[234,325,326],{"class":240},"class",[234,328,330],{"class":329},"sK71F"," Nano",[234,332,333],{"class":240}," extends",[234,335,336],{"class":244}," Chain {\n",[234,338,340,343,346,349,351,354,357,360],{"class":236,"line":339},8,[234,341,342],{"class":240},"  static",[234,344,345],{"class":240}," readonly",[234,347,348],{"class":244}," key ",[234,350,298],{"class":240},[234,352,353],{"class":251}," \"nano\"",[234,355,356],{"class":240}," as",[234,358,359],{"class":329}," ChainKey",[234,361,255],{"class":244},[234,363,365,368,371,373,375,377,380],{"class":236,"line":364},9,[234,366,367],{"class":240},"  readonly",[234,369,370],{"class":244}," type ",[234,372,298],{"class":240},[234,374,353],{"class":251},[234,376,356],{"class":240},[234,378,379],{"class":329}," ChainType",[234,381,255],{"class":244},[234,383,385,387,390,392,395],{"class":236,"line":384},10,[234,386,367],{"class":240},[234,388,389],{"class":244}," name ",[234,391,298],{"class":240},[234,393,394],{"class":251}," \"Nano\"",[234,396,255],{"class":244},[234,398,400,402,405,407,410],{"class":236,"line":399},11,[234,401,367],{"class":240},[234,403,404],{"class":244}," symbol ",[234,406,298],{"class":240},[234,408,409],{"class":251}," \"XNO\"",[234,411,255],{"class":244},[234,413,415,418,420,423,425],{"class":236,"line":414},12,[234,416,417],{"class":240},"  override",[234,419,345],{"class":240},[234,421,422],{"class":244}," decimals ",[234,424,298],{"class":240},[234,426,427],{"class":244}," 30;\n",[234,429,431,433,436,438,441],{"class":236,"line":430},13,[234,432,367],{"class":240},[234,434,435],{"class":244}," explorer ",[234,437,298],{"class":240},[234,439,440],{"class":251}," \"https:\u002F\u002Fnanexplorer.com\u002Fnano\"",[234,442,255],{"class":244},[234,444,446,448,451,453],{"class":236,"line":445},14,[234,447,367],{"class":240},[234,449,450],{"class":244}," bip44 ",[234,452,298],{"class":240},[234,454,455],{"class":244}," 165;\n",[234,457,459],{"class":236,"line":458},15,[234,460,279],{"emptyLinePlaceholder":278},[234,462,464,466,469,472,475,478,481,483,485],{"class":236,"line":463},16,[234,465,417],{"class":240},[234,467,468],{"class":329}," assertAddress",[234,470,471],{"class":244},"(address",[234,473,474],{"class":240},":",[234,476,477],{"class":329}," string",[234,479,480],{"class":244},")",[234,482,474],{"class":240},[234,484,477],{"class":329},[234,486,487],{"class":244}," {\n",[234,489,491,494,497,500,503,506,509,512,515,518],{"class":236,"line":490},17,[234,492,493],{"class":240},"    if",[234,495,496],{"class":244}," (",[234,498,499],{"class":240},"!",[234,501,502],{"class":244},"ADDRESS.",[234,504,505],{"class":329},"test",[234,507,508],{"class":244},"(address)) ",[234,510,511],{"class":240},"throw",[234,513,514],{"class":240}," new",[234,516,517],{"class":329}," InvalidAddressError",[234,519,520],{"class":244},"(this.key, address);\n",[234,522,524,527],{"class":236,"line":523},18,[234,525,526],{"class":240},"    return",[234,528,529],{"class":244}," address;\n",[234,531,533],{"class":236,"line":532},19,[234,534,535],{"class":244},"  }\n",[234,537,539],{"class":236,"line":538},20,[234,540,541],{"class":244},"}\n",[234,543,545],{"class":236,"line":544},21,[234,546,279],{"emptyLinePlaceholder":278},[234,548,550,553],{"class":236,"line":549},22,[234,551,552],{"class":329},"register",[234,554,555],{"class":244},"(Nano);\n",[224,557,559],{"className":226,"code":558,"language":229,"meta":230,"style":230},"import \".\u002Fnano\";\nimport { create, getChain, identify } from \"@agntn\u002Fchains\";\n\ngetChain(\"nano\").name; \u002F\u002F \"Nano\"\nidentify(\"nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3\").matches[0]?.key; \u002F\u002F \"nano\"\n",[211,560,561,570,583,587,604],{"__ignoreMap":230},[234,562,563,565,568],{"class":236,"line":237},[234,564,241],{"class":240},[234,566,567],{"class":251}," \".\u002Fnano\"",[234,569,255],{"class":244},[234,571,572,574,577,579,581],{"class":236,"line":258},[234,573,241],{"class":240},[234,575,576],{"class":244}," { create, getChain, identify } ",[234,578,248],{"class":240},[234,580,252],{"class":251},[234,582,255],{"class":244},[234,584,585],{"class":236,"line":275},[234,586,279],{"emptyLinePlaceholder":278},[234,588,589,592,595,598,601],{"class":236,"line":282},[234,590,591],{"class":329},"getChain",[234,593,594],{"class":244},"(",[234,596,597],{"class":251},"\"nano\"",[234,599,600],{"class":244},").name; ",[234,602,603],{"class":285},"\u002F\u002F \"Nano\"\n",[234,605,606,609,611,614,617],{"class":236,"line":289},[234,607,608],{"class":329},"identify",[234,610,594],{"class":244},[234,612,613],{"class":251},"\"nano_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3\"",[234,615,616],{"class":244},").matches[0]?.key; ",[234,618,619],{"class":285},"\u002F\u002F \"nano\"\n",[207,621,622,623,218,626,629,630,633,634,637,638,641],{},"Two casts, and they are the honest part of this page. ",[211,624,625],{},"ChainKey",[211,627,628],{},"ChainType"," are closed unions of the built-in values, so a new key doesn't type check without ",[211,631,632],{},"as ChainKey",", and ",[211,635,636],{},"create(\"nano\")"," wants the same cast. ",[211,639,640],{},"getChain(\"nano\")"," takes a plain string and needs none. The unions exist so a typo in a key is a compile error inside the package; the price is paid once, in your class.",[202,643,645],{"id":644},"the-contract","The contract",[647,648,649,663,701,714,733,753],"ul",{},[650,651,652,655,656,658,659,662],"li",{},[211,653,654],{},"static readonly key"," is what ",[211,657,552],{}," files the class under and what ",[211,660,661],{},"chain.key"," returns. Lowercase, the chain's name rather than its ticker. Registering the same key again replaces the class.",[650,664,665,668,669,668,672,218,675,678,679,668,682,668,685,668,688,668,691,668,694,218,697,700],{},[211,666,667],{},"name",", ",[211,670,671],{},"symbol",[211,673,674],{},"type",[211,676,677],{},"explorer"," are required. ",[211,680,681],{},"decimals",[211,683,684],{},"bip44",[211,686,687],{},"chainId",[211,689,690],{},"caip2",[211,692,693],{},"magic",[211,695,696],{},"pow",[211,698,699],{},"rpcDefault"," are optional and mean unknown when left out, never a default.",[650,702,703,706,707,710,711,713],{},[211,704,705],{},"assertAddress"," returns the address or throws ",[211,708,709],{},"InvalidAddressError(this.key, address)",". Throw that class and nothing else for a bad address, because ",[211,712,608],{}," counts only that as a miss and lets any other throw come back out as a bug.",[650,715,716,717,218,719,722,723,726,727,633,730,732],{},"Skip ",[211,718,705],{},[211,720,721],{},"validatesAddress"," says ",[211,724,725],{},"false",", the base method throws ",[211,728,729],{},"AddressValidationUnsupportedError",[211,731,608],{}," lists your chain as unchecked rather than pretending it said no.",[650,734,735,738,739,742,743,722,746,748,749,752],{},[211,736,737],{},"assertTxid"," is optional the same way. Override it and throw ",[211,740,741],{},"InvalidTxidError",", or skip it and ",[211,744,745],{},"validatesTxid",[211,747,725],{},". ",[211,750,751],{},"class Mine extends UTXO"," gets the 64 hex digit check for free.",[650,754,755,756,759,760,668,762,764],{},"An EVM chain is ",[211,757,758],{},"class Mine extends EVM"," with ",[211,761,687],{},[211,763,690],{}," and the rest. Both format checks come with the family.",[202,766,768],{"id":767},"decode-when-you-can","Decode when you can",[207,770,771,772,775,776,779],{},"A regex is fine when the width is the whole format, as it is for Octra. When the format is Base58Check with a known byte length, decode and look at the bytes: a character window takes neighbouring chains and half the typos. The built-ins are the reference, ",[211,773,774],{},"src\u002Fchains\u002Ftron.ts"," is the short one and ",[211,777,778],{},"src\u002Fchains\u002Fcardano.ts"," the long one.",[202,781,783],{"id":782},"where-it-shows-up","Where it shows up",[207,785,786,787,668,790,793,794,796,797,799,800,218,803,806],{},"Once the module is imported, the chain is in ",[211,788,789],{},"chains()",[211,791,792],{},"has()"," says true, ",[211,795,591],{}," finds it by key and by display name, ",[211,798,608],{}," asks it like any other. The CLI and the MCP server only load the built-ins. To use a custom chain there you build your own binary around ",[211,801,802],{},"create",[211,804,805],{},"createMcpServer",". There's no plugin path, and I'd rather say so than invent one that half works.",[808,809,810],"style",{},"html pre.shiki code .skH_V, html code.shiki .skH_V{--shiki-light:var(--shiki-token-keyword);--shiki-default:var(--shiki-token-keyword);--shiki-dark:var(--shiki-token-keyword)}html pre.shiki code .s38Sx, html code.shiki .s38Sx{--shiki-light:var(--ui-text-highlighted);--shiki-default:var(--ui-text-highlighted);--shiki-dark:var(--ui-text-highlighted)}html pre.shiki code .shU9J, html code.shiki .shU9J{--shiki-light:var(--shiki-token-string);--shiki-default:var(--shiki-token-string);--shiki-dark:var(--shiki-token-string)}html pre.shiki code .scIB-, html code.shiki .scIB-{--shiki-light:var(--shiki-token-comment);--shiki-default:var(--shiki-token-comment);--shiki-dark:var(--shiki-token-comment)}html pre.shiki code .sK71F, html code.shiki .sK71F{--shiki-light:var(--shiki-token-function);--shiki-default:var(--shiki-token-function);--shiki-dark:var(--shiki-token-function)}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":230,"searchDepth":258,"depth":258,"links":812},[813,814,815,816],{"id":204,"depth":258,"text":205},{"id":644,"depth":258,"text":645},{"id":767,"depth":258,"text":768},{"id":782,"depth":258,"text":783},"Extend the abstract Chain with a key and a validator and register the class. From then on the registry treats it like a built-in.","md",null,{"icon":821},"i-lucide-plus",{"title":36,"description":817},"WZkGsazsWlS4bREH4veXYYGXq9WriFkFjg-AhsfSI8M",[825,827],{"title":32,"path":33,"stem":34,"description":826,"children":-1},"The same five tools over MCP and the Pi and OMP extensions. What the text carries and what sets isError. What a model can't hand the process.",{"title":40,"path":41,"stem":42,"description":828,"children":-1},"The page behind chains.agntn.dev\u002Fplayground runs the library in your browser. What it can tell you and what it can't.",1790548037282]