[{"data":1,"prerenderedAt":814},["ShallowReactive",2],{"navigation_docs":3,"-guide-evm":72,"-guide-evm-surround":809},[4,32],{"title":5,"path":6,"stem":7,"children":8,"icon":31},"Guide","\u002Fguide","1.guide\u002F1.index",[9,11,15,19,23,27],{"title":10,"path":6,"stem":7},"Getting Started",{"title":12,"path":13,"stem":14},"Working with Keys","\u002Fguide\u002Fkeys","1.guide\u002F2.keys",{"title":16,"path":17,"stem":18},"Working with Addresses","\u002Fguide\u002Faddresses","1.guide\u002F3.addresses",{"title":20,"path":21,"stem":22},"Generating Wallets","\u002Fguide\u002Fwallets","1.guide\u002F4.wallets",{"title":24,"path":25,"stem":26},"Working with EVM Chains","\u002Fguide\u002Fevm","1.guide\u002F5.evm",{"title":28,"path":29,"stem":30},"Creating Custom Blockchains","\u002Fguide\u002Fcustom","1.guide\u002F6.custom","i-lucide-book-open",{"title":33,"path":34,"stem":35,"children":36,"icon":71},"Blockchains","\u002Fblockchains","2.blockchains\u002F0.index",[37,39,43,47,51,55,59,63,67],{"title":38,"path":34,"stem":35},"Overview",{"title":40,"path":41,"stem":42},"Aptos","\u002Fblockchains\u002Faptos","2.blockchains\u002Faptos",{"title":44,"path":45,"stem":46},"Base","\u002Fblockchains\u002Fbase","2.blockchains\u002Fbase",{"title":48,"path":49,"stem":50},"Bitcoin","\u002Fblockchains\u002Fbitcoin","2.blockchains\u002Fbitcoin",{"title":52,"path":53,"stem":54},"Cardano","\u002Fblockchains\u002Fcardano","2.blockchains\u002Fcardano",{"title":56,"path":57,"stem":58},"Ethereum","\u002Fblockchains\u002Fethereum","2.blockchains\u002Fethereum",{"title":60,"path":61,"stem":62},"Solana","\u002Fblockchains\u002Fsolana","2.blockchains\u002Fsolana",{"title":64,"path":65,"stem":66},"Sui","\u002Fblockchains\u002Fsui","2.blockchains\u002Fsui",{"title":68,"path":69,"stem":70},"TRON","\u002Fblockchains\u002Ftron","2.blockchains\u002Ftron","i-lucide-boxes",{"id":73,"title":24,"body":74,"description":802,"extension":803,"links":804,"meta":805,"navigation":149,"path":25,"seo":807,"stem":26,"__hash__":808},"docs\u002F1.guide\u002F5.evm.md",{"type":75,"value":76,"toc":794},"minimark",[77,82,91,231,234,238,468,471,475,486,519,525,529,599,602,606,620,624,631,745,787,790],[78,79,81],"h2",{"id":80},"one-base-class","One base class",[83,84,85,86,90],"p",{},"Ethereum and Base extend ",[87,88,89],"code",{},"AbstractEVMBlockchain",". Keys, addresses, validation, and message signing all live in the base, so a new EVM chain is two lines:",[92,93,98],"pre",{"className":94,"code":95,"language":96,"meta":97,"style":97},"language-ts shiki shiki-themes github-light github-light poimandres","import { AbstractEVMBlockchain, BIP44 } from \"@agntn\u002Fkeys\";\n\nexport default class Ethereum extends AbstractEVMBlockchain {\n  override readonly name = \"ethereum\";\n  override readonly bip44 = BIP44.ETHEREUM;\n}\n","ts","",[87,99,100,144,151,176,201,225],{"__ignoreMap":97},[101,102,105,109,113,117,120,123,126,130,134,138,141],"span",{"class":103,"line":104},"line",1,[101,106,108],{"class":107},"sP0CR","import",[101,110,112],{"class":111},"sKlNE"," {",[101,114,116],{"class":115},"snHMy"," AbstractEVMBlockchain",[101,118,119],{"class":111},",",[101,121,122],{"class":115}," BIP44",[101,124,125],{"class":111}," }",[101,127,129],{"class":128},"stCPd"," from",[101,131,133],{"class":132},"scVjq"," \"",[101,135,137],{"class":136},"sQ7BG","@agntn\u002Fkeys",[101,139,140],{"class":132},"\"",[101,142,143],{"class":111},";\n",[101,145,147],{"class":103,"line":146},2,[101,148,150],{"emptyLinePlaceholder":149},true,"\n",[101,152,154,157,160,164,168,171,173],{"class":103,"line":153},3,[101,155,156],{"class":107},"export",[101,158,159],{"class":107}," default",[101,161,163],{"class":162},"s1TYA"," class",[101,165,167],{"class":166},"scZRh"," Ethereum",[101,169,170],{"class":107}," extends",[101,172,116],{"class":166},[101,174,175],{"class":111}," {\n",[101,177,179,182,185,189,192,194,197,199],{"class":103,"line":178},4,[101,180,181],{"class":107},"  override",[101,183,184],{"class":107}," readonly",[101,186,188],{"class":187},"svU0y"," name",[101,190,191],{"class":162}," =",[101,193,133],{"class":132},[101,195,196],{"class":136},"ethereum",[101,198,140],{"class":132},[101,200,143],{"class":111},[101,202,204,206,208,211,213,216,219,223],{"class":103,"line":203},5,[101,205,181],{"class":107},[101,207,184],{"class":107},[101,209,210],{"class":187}," bip44",[101,212,191],{"class":162},[101,214,122],{"class":215},"sqT1Y",[101,217,218],{"class":111},".",[101,220,222],{"class":221},"saoiD","ETHEREUM",[101,224,143],{"class":111},[101,226,228],{"class":103,"line":227},6,[101,229,230],{"class":111},"}\n",[83,232,233],{},"Base looks identical apart from the name. It even keeps coin type 60, because that is what every wallet does for L2s.",[78,235,237],{"id":236},"same-key-same-address-everywhere","Same key, same address everywhere",[92,239,243],{"className":240,"code":241,"language":242,"meta":97,"style":97},"language-js shiki shiki-themes github-light github-light poimandres","import { useBlockchain } from \"@agntn\u002Fkeys\";\nimport Ethereum from \"@agntn\u002Fkeys\u002Fblockchains\u002Fethereum\";\nimport Base from \"@agntn\u002Fkeys\u002Fblockchains\u002Fbase\";\n\nconst ethereumChain = useBlockchain(new Ethereum());\nconst baseChain = useBlockchain(new Base());\n\nconst privateKey = ethereumChain.generateKeyPrivate();\n\nconst ethAddress = ethereumChain.getAddress(ethereumChain.getKeyPublic(privateKey));\nconst baseAddress = baseChain.getAddress(baseChain.getKeyPublic(privateKey));\n\nethAddress === baseAddress; \u002F\u002F true\n","js",[87,244,245,266,283,301,305,329,348,353,374,379,414,445,450],{"__ignoreMap":97},[101,246,247,249,251,254,256,258,260,262,264],{"class":103,"line":104},[101,248,108],{"class":107},[101,250,112],{"class":111},[101,252,253],{"class":115}," useBlockchain",[101,255,125],{"class":111},[101,257,129],{"class":128},[101,259,133],{"class":132},[101,261,137],{"class":136},[101,263,140],{"class":132},[101,265,143],{"class":111},[101,267,268,270,272,274,276,279,281],{"class":103,"line":146},[101,269,108],{"class":107},[101,271,167],{"class":115},[101,273,129],{"class":128},[101,275,133],{"class":132},[101,277,278],{"class":136},"@agntn\u002Fkeys\u002Fblockchains\u002Fethereum",[101,280,140],{"class":132},[101,282,143],{"class":111},[101,284,285,287,290,292,294,297,299],{"class":103,"line":153},[101,286,108],{"class":107},[101,288,289],{"class":115}," Base",[101,291,129],{"class":128},[101,293,133],{"class":132},[101,295,296],{"class":136},"@agntn\u002Fkeys\u002Fblockchains\u002Fbase",[101,298,140],{"class":132},[101,300,143],{"class":111},[101,302,303],{"class":103,"line":178},[101,304,150],{"emptyLinePlaceholder":149},[101,306,307,310,313,315,318,321,324,326],{"class":103,"line":203},[101,308,309],{"class":162},"const",[101,311,312],{"class":221}," ethereumChain",[101,314,191],{"class":162},[101,316,253],{"class":317},"sULi6",[101,319,320],{"class":111},"(",[101,322,323],{"class":107},"new",[101,325,167],{"class":317},[101,327,328],{"class":111},"());\n",[101,330,331,333,336,338,340,342,344,346],{"class":103,"line":227},[101,332,309],{"class":162},[101,334,335],{"class":221}," baseChain",[101,337,191],{"class":162},[101,339,253],{"class":317},[101,341,320],{"class":111},[101,343,323],{"class":107},[101,345,289],{"class":317},[101,347,328],{"class":111},[101,349,351],{"class":103,"line":350},7,[101,352,150],{"emptyLinePlaceholder":149},[101,354,356,358,361,363,366,368,371],{"class":103,"line":355},8,[101,357,309],{"class":162},[101,359,360],{"class":221}," privateKey",[101,362,191],{"class":162},[101,364,312],{"class":365},"spVlQ",[101,367,218],{"class":111},[101,369,370],{"class":317},"generateKeyPrivate",[101,372,373],{"class":111},"();\n",[101,375,377],{"class":103,"line":376},9,[101,378,150],{"emptyLinePlaceholder":149},[101,380,382,384,387,389,391,393,396,398,401,403,406,408,411],{"class":103,"line":381},10,[101,383,309],{"class":162},[101,385,386],{"class":221}," ethAddress",[101,388,191],{"class":162},[101,390,312],{"class":365},[101,392,218],{"class":111},[101,394,395],{"class":317},"getAddress",[101,397,320],{"class":111},[101,399,400],{"class":365},"ethereumChain",[101,402,218],{"class":111},[101,404,405],{"class":317},"getKeyPublic",[101,407,320],{"class":111},[101,409,410],{"class":365},"privateKey",[101,412,413],{"class":111},"));\n",[101,415,417,419,422,424,426,428,430,432,435,437,439,441,443],{"class":103,"line":416},11,[101,418,309],{"class":162},[101,420,421],{"class":221}," baseAddress",[101,423,191],{"class":162},[101,425,335],{"class":365},[101,427,218],{"class":111},[101,429,395],{"class":317},[101,431,320],{"class":111},[101,433,434],{"class":365},"baseChain",[101,436,218],{"class":111},[101,438,405],{"class":317},[101,440,320],{"class":111},[101,442,410],{"class":365},[101,444,413],{"class":111},[101,446,448],{"class":103,"line":447},12,[101,449,150],{"emptyLinePlaceholder":149},[101,451,453,456,459,461,464],{"class":103,"line":452},13,[101,454,455],{"class":365},"ethAddress",[101,457,458],{"class":162}," ===",[101,460,421],{"class":365},[101,462,463],{"class":111},"; ",[101,465,467],{"class":466},"sjhu3","\u002F\u002F true\n",[83,469,470],{},"This is a feature of the EVM, not of the library. Address is a function of the public key alone, so one wallet serves every EVM chain. It also means sending to the wrong chain lands the funds at the right address on the wrong network, which is a much worse afternoon than a typo.",[78,472,474],{"id":473},"the-address","The address",[83,476,477,478,481,482,485],{},"Take the uncompressed public key without the leading ",[87,479,480],{},"04",", Keccak-256 it, keep the last 20 bytes, add ",[87,483,484],{},"0x",". Then EIP-55:",[92,487,489],{"className":240,"code":488,"language":242,"meta":97,"style":97},"\"0x7e5f4552091a69125d5dfcb7b8c2659029395bdf\"; \u002F\u002F valid, no checksum\n\"0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf\"; \u002F\u002F same address, checksummed\n",[87,490,491,505],{"__ignoreMap":97},[101,492,493,495,498,500,502],{"class":103,"line":104},[101,494,140],{"class":132},[101,496,497],{"class":136},"0x7e5f4552091a69125d5dfcb7b8c2659029395bdf",[101,499,140],{"class":132},[101,501,463],{"class":111},[101,503,504],{"class":466},"\u002F\u002F valid, no checksum\n",[101,506,507,509,512,514,516],{"class":103,"line":146},[101,508,140],{"class":132},[101,510,511],{"class":136},"0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf",[101,513,140],{"class":132},[101,515,463],{"class":111},[101,517,518],{"class":466},"\u002F\u002F same address, checksummed\n",[83,520,521,522,524],{},"The checksum hides in the letter case. Hash the lowercase hex, and every character whose hash nibble is 8 or more gets uppercased. ",[87,523,395],{}," always returns the checksummed form.",[78,526,528],{"id":527},"validation","Validation",[92,530,532],{"className":240,"code":531,"language":242,"meta":97,"style":97},"ethereumChain.validateAddress(\"0x7E5F4552091A69125d5DfCb7b8C2659029395Bdf\"); \u002F\u002F true\nethereumChain.validateAddress(\"0x7e5f4552091a69125d5dfcb7b8c2659029395bdf\"); \u002F\u002F true, all lowercase\nethereumChain.validateAddress(\"0x7e5F4552091A69125d5DfCb7b8C2659029395Bdf\"); \u002F\u002F false, mixed case, wrong checksum\n",[87,533,534,556,577],{"__ignoreMap":97},[101,535,536,538,540,543,545,547,549,551,554],{"class":103,"line":104},[101,537,400],{"class":365},[101,539,218],{"class":111},[101,541,542],{"class":317},"validateAddress",[101,544,320],{"class":111},[101,546,140],{"class":132},[101,548,511],{"class":136},[101,550,140],{"class":132},[101,552,553],{"class":111},"); ",[101,555,467],{"class":466},[101,557,558,560,562,564,566,568,570,572,574],{"class":103,"line":146},[101,559,400],{"class":365},[101,561,218],{"class":111},[101,563,542],{"class":317},[101,565,320],{"class":111},[101,567,140],{"class":132},[101,569,497],{"class":136},[101,571,140],{"class":132},[101,573,553],{"class":111},[101,575,576],{"class":466},"\u002F\u002F true, all lowercase\n",[101,578,579,581,583,585,587,589,592,594,596],{"class":103,"line":153},[101,580,400],{"class":365},[101,582,218],{"class":111},[101,584,542],{"class":317},[101,586,320],{"class":111},[101,588,140],{"class":132},[101,590,591],{"class":136},"0x7e5F4552091A69125d5DfCb7b8C2659029395Bdf",[101,593,140],{"class":132},[101,595,553],{"class":111},[101,597,598],{"class":466},"\u002F\u002F false, mixed case, wrong checksum\n",[83,600,601],{},"All lowercase and all uppercase pass, because those carry no checksum and plenty of tooling still emits them. Mixed case has to match EIP-55 exactly.",[78,603,605],{"id":604},"signing","Signing",[83,607,608,611,612,615,616,619],{},[87,609,610],{},"signMessage"," uses the ",[87,613,614],{},"personal_sign"," preamble, ",[87,617,618],{},"\"\\x19Ethereum Signed Message:\\n\" + length + message",", hashed with Keccak-256 and signed with secp256k1. That is what MetaMask and every EVM verifier expect, so signatures made here verify elsewhere and the other way round.",[78,621,623],{"id":622},"adding-another-evm-chain","Adding another EVM chain",[83,625,626,627,630],{},"Drop a file into ",[87,628,629],{},"src\u002Fblockchains\u002F"," and register it in the lazy loader:",[92,632,634],{"className":94,"code":633,"language":96,"meta":97,"style":97},"\u002F\u002F src\u002Fblockchains\u002Fpolygon.ts\nimport { AbstractEVMBlockchain } from \"..\u002Futils\u002Fevm.ts\";\nimport { BIP44 } from \"..\u002Futils\u002Fbip44\u002Findex.ts\";\n\nexport default class Polygon extends AbstractEVMBlockchain {\n  override readonly name = \"polygon\";\n  override readonly bip44 = BIP44.ETHEREUM;\n}\n",[87,635,636,641,662,683,687,704,723,741],{"__ignoreMap":97},[101,637,638],{"class":103,"line":104},[101,639,640],{"class":466},"\u002F\u002F src\u002Fblockchains\u002Fpolygon.ts\n",[101,642,643,645,647,649,651,653,655,658,660],{"class":103,"line":146},[101,644,108],{"class":107},[101,646,112],{"class":111},[101,648,116],{"class":115},[101,650,125],{"class":111},[101,652,129],{"class":128},[101,654,133],{"class":132},[101,656,657],{"class":136},"..\u002Futils\u002Fevm.ts",[101,659,140],{"class":132},[101,661,143],{"class":111},[101,663,664,666,668,670,672,674,676,679,681],{"class":103,"line":153},[101,665,108],{"class":107},[101,667,112],{"class":111},[101,669,122],{"class":115},[101,671,125],{"class":111},[101,673,129],{"class":128},[101,675,133],{"class":132},[101,677,678],{"class":136},"..\u002Futils\u002Fbip44\u002Findex.ts",[101,680,140],{"class":132},[101,682,143],{"class":111},[101,684,685],{"class":103,"line":178},[101,686,150],{"emptyLinePlaceholder":149},[101,688,689,691,693,695,698,700,702],{"class":103,"line":203},[101,690,156],{"class":107},[101,692,159],{"class":107},[101,694,163],{"class":162},[101,696,697],{"class":166}," Polygon",[101,699,170],{"class":107},[101,701,116],{"class":166},[101,703,175],{"class":111},[101,705,706,708,710,712,714,716,719,721],{"class":103,"line":227},[101,707,181],{"class":107},[101,709,184],{"class":107},[101,711,188],{"class":187},[101,713,191],{"class":162},[101,715,133],{"class":132},[101,717,718],{"class":136},"polygon",[101,720,140],{"class":132},[101,722,143],{"class":111},[101,724,725,727,729,731,733,735,737,739],{"class":103,"line":350},[101,726,181],{"class":107},[101,728,184],{"class":107},[101,730,210],{"class":187},[101,732,191],{"class":162},[101,734,122],{"class":215},[101,736,218],{"class":111},[101,738,222],{"class":221},[101,740,143],{"class":111},[101,742,743],{"class":103,"line":355},[101,744,230],{"class":111},[92,746,748],{"className":94,"code":747,"language":96,"meta":97,"style":97},"\u002F\u002F src\u002F_blockchains.ts\npolygon: lazy(() => import(\".\u002Fblockchains\u002Fpolygon.ts\")),\n",[87,749,750,755],{"__ignoreMap":97},[101,751,752],{"class":103,"line":104},[101,753,754],{"class":466},"\u002F\u002F src\u002F_blockchains.ts\n",[101,756,757,760,763,766,769,772,775,777,779,782,784],{"class":103,"line":146},[101,758,718],{"class":759},"sseY5",[101,761,762],{"class":111},": ",[101,764,765],{"class":317},"lazy",[101,767,768],{"class":111},"(() ",[101,770,771],{"class":162},"=>",[101,773,774],{"class":162}," import",[101,776,320],{"class":111},[101,778,140],{"class":132},[101,780,781],{"class":136},".\u002Fblockchains\u002Fpolygon.ts",[101,783,140],{"class":132},[101,785,786],{"class":111},")),\n",[83,788,789],{},"Nothing else. The base class already knows how to do everything the chain needs.",[791,792,793],"style",{},"html pre.shiki code .sP0CR, html code.shiki .sP0CR{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#5DE4C7}html pre.shiki code .sKlNE, html code.shiki .sKlNE{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#A6ACCD}html pre.shiki code .snHMy, html code.shiki .snHMy{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#ADD7FF}html pre.shiki code .stCPd, html code.shiki .stCPd{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#A6ACCD}html pre.shiki code .scVjq, html code.shiki .scVjq{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#A6ACCD}html pre.shiki code .sQ7BG, html code.shiki .sQ7BG{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#5DE4C7}html pre.shiki code .s1TYA, html code.shiki .s1TYA{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#91B4D5}html pre.shiki code .scZRh, html code.shiki .scZRh{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#ADD7FF}html pre.shiki code .svU0y, html code.shiki .svU0y{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#5DE4C7}html pre.shiki code .sqT1Y, html code.shiki .sqT1Y{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#ADD7FF}html pre.shiki code .saoiD, html code.shiki .saoiD{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#E4F0FB}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);}html pre.shiki code .sULi6, html code.shiki .sULi6{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#E4F0FBD0}html pre.shiki code .spVlQ, html code.shiki .spVlQ{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E4F0FB}html pre.shiki code .sjhu3, html code.shiki .sjhu3{--shiki-light:#6A737D;--shiki-light-font-style:inherit;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#767C9DB0;--shiki-dark-font-style:italic}html pre.shiki code .sseY5, html code.shiki .sseY5{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#91B4D5}",{"title":97,"searchDepth":146,"depth":146,"links":795},[796,797,798,799,800,801],{"id":80,"depth":146,"text":81},{"id":236,"depth":146,"text":237},{"id":473,"depth":146,"text":474},{"id":527,"depth":146,"text":528},{"id":604,"depth":146,"text":605},{"id":622,"depth":146,"text":623},"Ethereum and Base share one implementation, one address, and one signing scheme.","md",null,{"icon":806},"i-simple-icons-ethereum",{"title":24,"description":802},"RAFj2sLD82-W58usqtW9yltcoE0BnfTXtRDV7jgmiKA",[810,812],{"title":20,"path":21,"stem":22,"description":811,"children":-1},"One call for keys plus address, importing a key you already have, and walking a mnemonic down a path.",{"title":28,"path":29,"stem":30,"description":813,"children":-1},"Extend AbstractBlockchain, implement five methods, register it, test it.",1788428716372]