@latticexyz/cli 2.2.0 → 2.2.1-main-0738d295f802be28524d517d75efe3b5837f10c1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,42 +0,0 @@
1
- import{a as V}from"./chunk-JXC4VYGI.js";import ia from"@latticexyz/gas-report";import da from"@latticexyz/abi-ts";import{loadConfig as Jo,resolveConfigPath as qo}from"@latticexyz/config/node";import{tablegen as Lo}from"@latticexyz/store/codegen";import{buildSystemsManifest as Vo,worldgen as Uo}from"@latticexyz/world/node";import{forge as _o}from"@latticexyz/common/foundry";import{execa as Ko}from"execa";async function U({rootDir:e,config:o,foundryProfile:r=process.env.FOUNDRY_PROFILE}){await Promise.all([Lo({rootDir:e,config:o}),Uo({rootDir:e,config:o})]),await _o(["build"],{profile:r}),await Vo({rootDir:e,config:o}),await Ko("mud",["abi-ts"],{stdio:"inherit"})}import Yo from"node:path";var Go={command:"build",describe:"Build contracts and generate MUD artifacts (table libraries, world interface, ABI)",builder(e){return e.options({configPath:{type:"string",desc:"Path to the MUD config file"},profile:{type:"string",desc:"The foundry profile to use"}})},async handler(e){let o=await qo(e.configPath),r=await Jo(o);await U({rootDir:Yo.dirname(o),config:r,foundryProfile:e.profile}),process.exit(0)}},xe=Go;import{rmSync as Qo}from"fs";import{homedir as Zo}from"os";import Xo from"path";import{execa as et}from"execa";var ot={command:"devnode",describe:"Start a local Ethereum node for development",builder(e){return e.options({blocktime:{type:"number",default:1,decs:"Interval in which new blocks are produced"}})},async handler({blocktime:e}){console.log("Clearing devnode history");let o=Zo();Qo(Xo.join(o,".foundry","anvil","tmp"),{recursive:!0,force:!0});let r=["-b",String(e),"--block-base-fee-per-gas","0"];console.log(`Running: anvil ${r.join(" ")}`);let n=et("anvil",r,{stdio:["inherit","inherit","inherit"]});process.on("SIGINT",()=>{console.log(`
2
- gracefully shutting down from SIGINT (Crtl-C)`),n.kill(),process.exit()}),await n}},Ce=ot;var tt={command:"hello <name>",describe:"Greet <name> with Hello",builder(e){return e.options({upper:{type:"boolean"}}).positional("name",{type:"string",demandOption:!0})},handler({name:e}){let o=`Gm, ${e}!`;console.log(o),process.exit(0)}},Se=tt;import{loadConfig as rt,resolveConfigPath as nt}from"@latticexyz/config/node";import{tablegen as st}from"@latticexyz/store/codegen";import at from"node:path";var it={command:"tablegen",describe:"Autogenerate MUD Store table libraries based on the config file",builder(e){return e.options({configPath:{type:"string",desc:"Path to the MUD config file"}})},async handler(e){let o=await nt(e.configPath),r=await rt(o);await st({rootDir:at.dirname(o),config:r}),process.exit(0)}},ve=it;import ie from"node:path";import{existsSync as On,mkdirSync as Bn,readFileSync as In,writeFileSync as ue}from"node:fs";import{stringToHex as Zr}from"viem";import{getBalance as ft,sendRawTransaction as yt,sendTransaction as De,waitForTransactionReceipt as Te}from"viem/actions";var D={gasPrice:1e11,gasLimit:1e5,signerAddress:"3fab184622dc19b6109349b94811493bf2a45362",transaction:"f8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222",address:"4e59b44847b379578588920ca78fbf26c0b4956c",creationCode:"604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"};import Ae from"debug";var _=Ae("mud:cli"),lt=Ae("mud:cli");_.log=console.debug.bind(console);lt.log=console.error.bind(console);var m=_.extend("deploy"),ct=_.extend("deploy");m.log=console.debug.bind(console);ct.log=console.error.bind(console);import{sliceHex as mt}from"viem";import{getBytecode as pt}from"viem/actions";var K=`0x${D.address}`;async function J(e){let o=await pt(e,{address:K});if(o)return m("found CREATE2 deployer at",K),o!==mt(`0x${D.creationCode}`,14)&&console.warn(`
3
- \u26A0\uFE0F Bytecode for deployer at ${K} did not match the expected CREATE2 bytecode. You may have unexpected results.
4
- `),K}var de=`0x${D.address}`;async function Pe(e){let o=await J(e);if(o!==void 0)return o;let r=BigInt(D.gasLimit)*BigInt(D.gasPrice),n=await ft(e,{address:`0x${D.signerAddress}`}),t=r-n;if(t>0){m("sending gas for CREATE2 deployer to signer at",D.signerAddress);let a=await De(e,{chain:e.chain??null,to:`0x${D.signerAddress}`,value:t}),c=await Te(e,{hash:a});if(c.status!=="success")throw console.error("failed to send gas to deployer signer",c),new Error("failed to send gas to deployer signer")}m("deploying CREATE2 deployer at",de);let s=await yt(e,{serializedTransaction:`0x${D.transaction}`}).catch(a=>{if(String(a).includes("only replay-protected (EIP-155) transactions allowed over RPC"))return console.warn(`
5
- \u26A0\uFE0F Your chain or RPC does not allow for non EIP-155 signed transactions, so your deploys will not be determinstic and contract addresses may change between deploys.
6
-
7
- We recommend running your chain's node with \`--rpc.allow-unprotected-txs\` to enable determinstic deployments.
8
- `),m("deploying CREATE2 deployer"),De(e,{chain:e.chain??null,data:`0x${D.creationCode}`});throw a}),i=await Te(e,{hash:s});if(!i.contractAddress)throw new Error("Deploy receipt did not have contract address, was the deployer not deployed?");return i.contractAddress!==de&&console.warn(`
9
- \u26A0\uFE0F CREATE2 deployer created at ${i.contractAddress} does not match the CREATE2 determinstic deployer we expected (${de})`),i.contractAddress}import{waitForTransactionReceipt as Nt}from"viem/actions";import{waitForTransactionReceipt as Dt}from"viem/actions";import{concatHex as wt,getCreate2Address as xt}from"viem";import{getBytecode as Ct}from"viem/actions";import{padHex as ut}from"viem";import gt from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import{helloStoreEvent as bt}from"@latticexyz/store";import{helloWorldEvent as ht}from"@latticexyz/world";var S=ut("0x",{size:32}),E=parseInt("6000",16),q=[bt,ht],x=gt,ke=["2.0.0","2.0.1","2.0.2"],Me=["2.0.0","2.0.1","2.0.2"];import{sendTransaction as St}from"@latticexyz/common";import vt from"p-retry";import{wait as At}from"@latticexyz/common/utils";async function Oe({client:e,deployerAddress:o,bytecode:r,deployedBytecodeSize:n,debugLabel:t="contract"}){if(r.includes("__$"))throw new Error(`Found unlinked public library in ${t} bytecode`);let s=xt({from:o,salt:S,bytecode:r});return await Ct(e,{address:s,blockTag:"pending"})?(m("found",t,"at",s),[]):(n>E?console.warn(`
10
- Bytecode for ${t} (${n} bytes) is over the contract size limit (${E} bytes). Run \`forge build --sizes\` for more info.
11
- `):n>E*.95&&console.warn(`
12
- Bytecode for ${t} (${n} bytes) is almost over the contract size limit (${E} bytes). Run \`forge build --sizes\` for more info.
13
- `),m("deploying",t,"at",s),[await vt(()=>St(e,{chain:e.chain??null,to:o,data:wt([S,r])}),{retries:3,onFailedAttempt:async a=>{let c=a.attemptNumber*500;m(`failed to deploy ${t}, retrying in ${c}ms...`),await At(c)}})])}import{uniqueBy as Tt}from"@latticexyz/common/utils";async function P({client:e,deployerAddress:o,contracts:r}){let n=Tt(r,s=>s.bytecode),t=(await Promise.all(n.map(s=>Oe({client:e,deployerAddress:o,...s})))).flat();if(t.length){m("waiting for contracts");for(let s of t)await Dt(e,{hash:s})}return t}import je from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.json"assert{type:"json"};import Mt from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{getCreate2Address as Ot,encodeDeployData as Bt,size as It}from"viem";import Be from"@latticexyz/world/out/AccessManagementSystem.sol/AccessManagementSystem.json"assert{type:"json"};import Ie from"@latticexyz/world/out/BalanceTransferSystem.sol/BalanceTransferSystem.json"assert{type:"json"};import We from"@latticexyz/world/out/BatchCallSystem.sol/BatchCallSystem.json"assert{type:"json"};import Re from"@latticexyz/world/out/RegistrationSystem.sol/RegistrationSystem.json"assert{type:"json"};import He from"@latticexyz/world/out/InitModule.sol/InitModule.json"assert{type:"json"};import Pt from"@latticexyz/world/out/InitModule.sol/InitModule.abi.json"assert{type:"json"};import{getCreate2Address as F,encodeDeployData as kt,size as z}from"viem";function Y(e){let o=z(Be.deployedBytecode.object),r=Be.bytecode.object,n=F({from:e,bytecode:r,salt:S}),t=z(Ie.deployedBytecode.object),s=Ie.bytecode.object,i=F({from:e,bytecode:s,salt:S}),a=z(We.deployedBytecode.object),c=We.bytecode.object,d=F({from:e,bytecode:c,salt:S}),p=z(Re.deployedBytecode.object),l=Re.bytecode.object,u=F({from:e,bytecode:l,salt:S}),b=z(He.deployedBytecode.object),w=kt({bytecode:He.bytecode.object,abi:Pt,args:[n,i,d,u]}),C=F({from:e,bytecode:w,salt:S});return{AccessManagementSystem:{bytecode:r,deployedBytecodeSize:o,debugLabel:"access management system",address:n},BalanceTransferSystem:{bytecode:s,deployedBytecodeSize:t,debugLabel:"balance transfer system",address:i},BatchCallSystem:{bytecode:c,deployedBytecodeSize:a,debugLabel:"batch call system",address:d},RegistrationSystem:{bytecode:l,deployedBytecodeSize:p,debugLabel:"core registration system",address:u},InitModule:{bytecode:w,deployedBytecodeSize:b,debugLabel:"core module",address:C}}}function G(e){let o=Y(e),r=It(je.deployedBytecode.object),n=Bt({bytecode:je.bytecode.object,abi:Mt,args:[o.InitModule.address]}),t=Ot({from:e,bytecode:n,salt:S});return{...o,WorldFactory:{bytecode:n,deployedBytecodeSize:r,debugLabel:"world factory",address:t}}}import $e from"@latticexyz/world/out/WorldProxyFactory.sol/WorldProxyFactory.json"assert{type:"json"};import Wt from"@latticexyz/world/out/WorldProxyFactory.sol/WorldProxyFactory.abi.json"assert{type:"json"};import{getCreate2Address as Rt,encodeDeployData as Ht,size as jt}from"viem";function Q(e){let o=Y(e),r=jt($e.deployedBytecode.object),n=Ht({bytecode:$e.bytecode.object,abi:Wt,args:[o.InitModule.address]}),t=Rt({from:e,bytecode:n,salt:S});return{...o,WorldProxyFactory:{bytecode:n,deployedBytecodeSize:r,debugLabel:"world proxy factory",address:t}}}async function Z(e,o,r){if(r){let t=Q(o);return await P({client:e,deployerAddress:o,contracts:Object.values(t)}),t.WorldProxyFactory.address}let n=G(o);return await P({client:e,deployerAddress:o,contracts:Object.values(n)}),n.WorldFactory.address}import Lt from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{writeContract as Vt}from"@latticexyz/common";import{AbiEventSignatureNotFoundError as $t,decodeEventLog as Et,hexToString as Ee,parseAbi as Ft}from"viem";import{isDefined as zt}from"@latticexyz/common/utils";function X(e){let o=e.map(i=>{try{return{...i,...Et({strict:!0,abi:Ft(q),topics:i.topics,data:i.data})}}catch(a){if(a instanceof $t)return;throw a}}).filter(zt),{address:r,deployBlock:n,worldVersion:t,storeVersion:s}=o.reduce((i,a)=>({...i,address:a.address,deployBlock:a.blockNumber,...a.eventName==="HelloWorld"?{worldVersion:Ee(a.args.worldVersion).replace(/\0+$/,"")}:null,...a.eventName==="HelloStore"?{storeVersion:Ee(a.args.storeVersion).replace(/\0+$/,"")}:null}),{});if(r==null)throw new Error("could not find world address");if(n==null)throw new Error("could not find world deploy block number");if(t==null)throw new Error("could not find world version");if(s==null)throw new Error("could not find store version");return{address:r,deployBlock:n,worldVersion:t,storeVersion:s}}async function Fe(e,o,r,n){let t=await Z(e,o,n);m("deploying world");let s=await Vt(e,{chain:e.chain??null,address:t,abi:Lt,functionName:"deployWorld",args:[r]});m("waiting for world deploy");let i=await Nt(e,{hash:s});if(i.status!=="success")throw console.error("world deploy failed",i),new Error("world deploy failed");let a=X(i.logs);return m("deployed world to",a.address,"at block",a.deployBlock),{...a,stateBlock:a.deployBlock}}import{resourceToLabel as ce,writeContract as Zt}from"@latticexyz/common";import{valueSchemaToFieldLayoutHex as Xt,keySchemaToHex as er,valueSchemaToHex as or,getSchemaTypes as _e,getValueSchema as tr,getKeySchema as rr}from"@latticexyz/protocol-parser/internal";import{parseAbiItem as Ut,decodeAbiParameters as ze,parseAbiParameters as Ne}from"viem";import{hexToResource as _t}from"@latticexyz/common";import{storeSetRecordEvent as Kt}from"@latticexyz/store";import{getLogs as Jt}from"viem/actions";import{decodeKey as qt,decodeValueArgs as Yt,getKeySchema as Gt,getSchemaTypes as Le,getValueSchema as Qt,hexToSchema as Ve}from"@latticexyz/protocol-parser/internal";import le from"@latticexyz/store/mud.config";async function Ue({client:e,worldDeploy:o}){m("looking up tables for",o.address);let n=(await Jt(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:Ut(Kt),args:{tableId:le.namespaces.store.tables.Tables.tableId}})).map(t=>{let{tableId:s}=qt(Le(Gt(le.namespaces.store.tables.Tables)),t.args.keyTuple),{type:i,namespace:a,name:c}=_t(s),d=Yt(Le(Qt(le.namespaces.store.tables.Tables)),t.args),p=Ve(d.keySchema),l=Ve(d.valueSchema),u=ze(Ne("string[]"),d.abiEncodedKeyNames)[0],b=ze(Ne("string[]"),d.abiEncodedFieldNames)[0],w=[...l.staticFields,...l.dynamicFields],C=Object.fromEntries(p.staticFields.map((g,v)=>[u[v],{type:g,internalType:g}])),A=Object.fromEntries(w.map((g,v)=>[b[v],{type:g,internalType:g}]));return{type:i,namespace:a,name:c,tableId:s,schema:{...C,...A},key:Object.keys(C)}});return m("found",n.length,"tables for",o.address),n}import nr from"p-retry";import{wait as sr}from"@latticexyz/common/utils";async function Ke({client:e,worldDeploy:o,tables:r}){let t=(await Ue({client:e,worldDeploy:o})).map(a=>a.tableId),s=r.filter(a=>t.includes(a.tableId));s.length&&m("existing tables:",s.map(ce).join(", "));let i=r.filter(a=>!t.includes(a.tableId));return i.length?(m("registering tables:",i.map(ce).join(", ")),await Promise.all(i.map(a=>{let c=_e(rr(a)),d=_e(tr(a));return nr(()=>Zt(e,{chain:e.chain??null,address:o.address,abi:x,functionName:"registerTable",args:[a.tableId,Xt(d),er(c),or(d),Object.keys(c),Object.keys(d)]}),{retries:3,onFailedAttempt:async p=>{let l=p.attemptNumber*500;m(`failed to register table ${ce(a)}, retrying in ${l}ms...`),await sr(l)}})}))):[]}import{getAddress as M}from"viem";import{writeContract as pe,resourceToLabel as N}from"@latticexyz/common";import{hexToResource as Ar,resourceToLabel as Dr}from"@latticexyz/common";import{getFunctions as Tr}from"@latticexyz/world/internal";import{parseAbiItem as ar,HttpRequestError as ir}from"viem";import{getLogs as dr}from"viem/actions";import{storeSpliceStaticDataEvent as lr}from"@latticexyz/store";import cr from"p-retry";import mr from"@latticexyz/store/mud.config";async function ee({client:e,worldDeploy:o}){m("looking up resource IDs for",o.address);let n=(await cr(()=>dr(e,{strict:!0,address:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock,event:ar(lr),args:{tableId:mr.namespaces.store.tables.ResourceIds.tableId}}),{retries:3,onFailedAttempt:async t=>{if(!(t instanceof ir&&t.status===400&&t.message.includes("block is out of range")))throw t}})).map(t=>t.args.keyTuple[0]);return m("found",n.length,"resource IDs for",o.address),n}import{decodeValueArgs as pr,encodeKey as fr,getKeySchema as yr,getSchemaTypes as Je,getValueSchema as ur}from"@latticexyz/protocol-parser/internal";import{readContract as gr}from"viem/actions";async function I({client:e,worldDeploy:o,table:r,key:n}){let[t,s,i]=await gr(e,{blockNumber:o.stateBlock,address:o.address,abi:x,functionName:"getRecord",args:[r.tableId,fr(Je(yr(r)),n)]});return pr(Je(ur(r)),{staticData:t,encodedLengths:s,dynamicData:i})}import{parseAbiItem as br,getAddress as hr}from"viem";import{storeSpliceStaticDataEvent as wr}from"@latticexyz/store";import{getLogs as xr}from"viem/actions";import{decodeKey as Cr,getKeySchema as Sr,getSchemaTypes as vr}from"@latticexyz/protocol-parser/internal";import me from"@latticexyz/world/mud.config";async function oe({client:e,worldDeploy:o}){m("looking up resource access for",o.address);let n=(await xr(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:br(wr),args:{tableId:me.namespaces.world.tables.ResourceAccess.tableId}})).map(s=>Cr(vr(Sr(me.namespaces.world.tables.ResourceAccess)),s.args.keyTuple)),t=(await Promise.all(n.map(async s=>[s,await I({client:e,worldDeploy:o,table:me.namespaces.world.tables.ResourceAccess,key:s})]))).filter(([,s])=>s.access).map(([s])=>({resourceId:s.resourceId,address:hr(s.caller)}));return m("found",t.length,"resource<>address access pairs"),t}import Pr from"@latticexyz/world/mud.config";async function qe({client:e,worldDeploy:o}){let[r,n,t]=await Promise.all([ee({client:e,worldDeploy:o}),Tr({client:e,worldAddress:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock}),oe({client:e,worldDeploy:o})]),s=r.map(Ar).filter(i=>i.type==="system");return m("looking up systems:",s.map(Dr).join(", ")),await Promise.all(s.map(async i=>{let{system:a,publicAccess:c}=await I({client:e,worldDeploy:o,table:Pr.namespaces.world.tables.Systems,key:{systemId:i.resourceId}}),d=n.filter(p=>p.systemId===i.resourceId);return{address:a,namespace:i.namespace,name:i.name,systemId:i.resourceId,allowAll:c,allowedAddresses:t.filter(({resourceId:p})=>p===i.resourceId).map(({address:p})=>p),worldFunctions:d}}))}import{wait as fe}from"@latticexyz/common/utils";import ye from"p-retry";async function Ye({client:e,deployerAddress:o,libraries:r,worldDeploy:n,systems:t}){let[s,i]=await Promise.all([qe({client:e,worldDeploy:n}),oe({client:e,worldDeploy:n})]),a=t.filter(y=>s.some(f=>f.systemId===y.systemId&&M(f.address)===M(y.prepareDeploy(o,r).address)));a.length&&m("existing systems:",a.map(N).join(", "));let c=a.map(y=>y.systemId),d=t.filter(y=>!c.includes(y.systemId));if(!d.length)return[];let p=d.filter(y=>s.some(f=>f.systemId===y.systemId&&M(f.address)!==M(y.prepareDeploy(o,r).address)));p.length&&m("upgrading systems:",p.map(N).join(", "));let l=d.filter(y=>!s.some(f=>f.systemId===y.systemId));l.length&&m("registering new systems:",l.map(N).join(", ")),await P({client:e,deployerAddress:o,contracts:d.map(y=>({bytecode:y.prepareDeploy(o,r).bytecode,deployedBytecodeSize:y.deployedBytecodeSize,debugLabel:`${N(y)} system`}))});let u=await Promise.all(d.map(y=>ye(()=>pe(e,{chain:e.chain??null,address:n.address,abi:x,functionName:"registerSystem",args:[y.systemId,y.prepareDeploy(o,r).address,y.allowAll]}),{retries:3,onFailedAttempt:async f=>{let h=f.attemptNumber*500;m(`failed to register system ${N(y)}, retrying in ${h}ms...`),await fe(h)}}))),b=t.map(y=>y.systemId),w=i.filter(({resourceId:y})=>b.includes(y)),C=[...t.flatMap(y=>y.allowedAddresses.map(f=>({resourceId:y.systemId,address:f}))),...t.flatMap(y=>y.allowedSystemIds.map(f=>({resourceId:y.systemId,address:s.find(h=>h.systemId===f)?.address??t.find(h=>h.systemId===f)?.prepareDeploy(o,r).address})).filter(f=>f.address!=null))],A=C.filter(y=>!w.some(({resourceId:f,address:h})=>f===y.resourceId&&M(h)===M(y.address))),g=w.filter(y=>!C.some(({resourceId:f,address:h})=>f===y.resourceId&&M(h)===M(y.address)));g.length&&m("revoking",g.length,"access grants"),A.length&&m("adding",A.length,"access grants");let v=await Promise.all([...g.map(y=>ye(()=>pe(e,{chain:e.chain??null,address:n.address,abi:x,functionName:"revokeAccess",args:[y.resourceId,y.address]}),{retries:3,onFailedAttempt:async f=>{let h=f.attemptNumber*500;m(`failed to revoke access, retrying in ${h}ms...`),await fe(h)}})),...A.map(y=>ye(()=>pe(e,{chain:e.chain??null,address:n.address,abi:x,functionName:"grantAccess",args:[y.resourceId,y.address]}),{retries:3,onFailedAttempt:async f=>{let h=f.attemptNumber*500;m(`failed to grant access, retrying in ${h}ms...`),await fe(h)}}))]);return[...u,...v]}import{waitForTransactionReceipt as fo}from"viem/actions";import{getAddress as kr,parseAbi as Mr}from"viem";import{getBlockNumber as Or,getLogs as Br}from"viem/actions";var Ge=new Map;async function Qe(e,o){let r=kr(o),n=Ge.get(r);if(n!=null)return n;m("looking up world deploy for",r);let t=await Or(e),s=await Br(e,{strict:!0,address:r,events:Mr(q),fromBlock:"earliest",toBlock:t});return n={...X(s),stateBlock:t},Ge.set(r,n),m("found world deploy for",r,"at block",n.deployBlock),n}import{hexToResource as Ir,writeContract as Ze}from"@latticexyz/common";import{getFunctions as Wr}from"@latticexyz/world/internal";import Xe from"p-retry";import{wait as eo}from"@latticexyz/common/utils";async function oo({client:e,worldDeploy:o,functions:r}){let n=await Wr({client:e,worldAddress:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock}),t=Object.fromEntries(n.map(a=>[a.selector,a])),s=r.filter(a=>t[a.selector]),i=r.filter(a=>!s.includes(a));if(s.length){m("functions already registered:",s.map(c=>c.signature).join(", "));let a=s.filter(c=>c.systemId!==t[c.selector]?.systemId);a.length&&console.warn("found",a.length,"functions already registered but pointing at a different system ID:",a.map(c=>c.signature).join(", "))}return i.length?(m("registering functions:",i.map(a=>a.signature).join(", ")),Promise.all(i.map(a=>{let{namespace:c}=Ir(a.systemId);return c===""?Xe(()=>Ze(e,{chain:e.chain??null,address:o.address,abi:x,functionName:"registerRootFunctionSelector",args:[a.systemId,a.systemFunctionSignature,a.systemFunctionSignature]}),{retries:3,onFailedAttempt:async d=>{let p=d.attemptNumber*500;m(`failed to register function ${a.signature}, retrying in ${p}ms...`),await eo(p)}}):Xe(()=>Ze(e,{chain:e.chain??null,address:o.address,abi:x,functionName:"registerFunctionSelector",args:[a.systemId,a.systemFunctionSignature]}),{retries:3,onFailedAttempt:async d=>{let p=d.attemptNumber*500;m(`failed to register function ${a.signature}, retrying in ${p}ms...`),await eo(p)}})}))):[]}import{BaseError as Rr}from"viem";import{writeContract as to}from"@latticexyz/common";import{isDefined as Hr,wait as jr}from"@latticexyz/common/utils";import $r from"p-retry";async function ro({client:e,deployerAddress:o,libraries:r,worldDeploy:n,modules:t}){return t.length?(await P({client:e,deployerAddress:o,contracts:t.map(s=>({bytecode:s.prepareDeploy(o,r).bytecode,deployedBytecodeSize:s.deployedBytecodeSize,debugLabel:`${s.name} module`}))}),m("installing modules:",t.map(s=>s.name).join(", ")),(await Promise.all(t.map(s=>$r(async()=>{try{let i=[...x,...s.abi],a=s.prepareDeploy(o,r).address;return s.installAsRoot?await to(e,{chain:e.chain??null,address:n.address,abi:i,functionName:"installRootModule",args:[a,s.installData]}):await to(e,{chain:e.chain??null,address:n.address,abi:i,functionName:"installModule",args:[a,s.installData]})}catch(i){if(i instanceof Rr&&i.message.includes("Module_AlreadyInstalled")){m(`module ${s.name} already installed`);return}if(s.optional){m(`optional module ${s.name} install failed, skipping`),m(i);return}throw i}},{retries:3,onFailedAttempt:async i=>{let a=i.attemptNumber*500;m(`failed to install module ${s.name}, retrying in ${a}ms...`),await jr(a)}})))).filter(Hr)):[]}import{getAddress as no}from"viem";import{hexToResource as so,resourceToHex as ao,writeContract as Er}from"@latticexyz/common";import Fr from"@latticexyz/world/mud.config";async function io({client:e,worldDeploy:o,resourceIds:r}){let n=Array.from(new Set(r.map(l=>so(l).namespace))),t=await ee({client:e,worldDeploy:o}),s=new Set(t.map(l=>so(l).namespace));s.size&&m("found",s.size,"existing namespaces:",Array.from(s).map(l=>l===""?"<root>":l).join(", "));let i=n.filter(l=>s.has(l)),c=(await Promise.all(i.map(async l=>{let{owner:u}=await I({client:e,worldDeploy:o,table:Fr.namespaces.world.tables.NamespaceOwner,key:{namespaceId:ao({type:"namespace",namespace:l,name:""})}});return[l,u]}))).filter(([,l])=>no(l)!==no(e.account.address)).map(([l])=>l);if(c.length)throw new Error(`You are attempting to deploy to namespaces you do not own: ${c.join(", ")}`);let d=n.filter(l=>!s.has(l));return d.length>0&&m("registering namespaces:",Array.from(d).join(", ")),Promise.all(d.map(l=>Er(e,{chain:e.chain??null,address:o.address,abi:x,functionName:"registerNamespace",args:[ao({namespace:l,type:"namespace",name:""})]})))}import{resourceToLabel as Xr}from"@latticexyz/common";import{randomBytes as en}from"crypto";import{stringToHex as co,BaseError as Kr}from"viem";import{hexToResource as Jr,writeContract as qr}from"@latticexyz/common";import{identity as Yr,isDefined as mo}from"@latticexyz/common/utils";import Gr from"@latticexyz/world-module-metadata/mud.config";import Qr from"@latticexyz/world-module-metadata/out/IMetadataSystem.sol/IMetadataSystem.abi.json"assert{type:"json"};import{decodeValueArgs as zr,getKeyTuple as Nr,getSchemaTypes as Lr,getValueSchema as Vr}from"@latticexyz/protocol-parser/internal";import{readContract as Ur}from"viem/actions";import{mapObject as _r}from"@latticexyz/common/utils";async function lo({client:e,worldDeploy:o,table:r,key:n}){let[t,s,i]=await Ur(e,{blockNumber:o.stateBlock,address:o.address,abi:x,functionName:"getRecord",args:[r.tableId,Nr(r,n)]}),a={...n,...zr(Lr(Vr(r)),{staticData:t,encodedLengths:s,dynamicData:i})};return _r(r.schema,(c,d)=>a[d])}async function po({client:e,worldDeploy:o,tags:r,valueToHex:n=Yr}){let t=(await Promise.all(r.map(async s=>{let{value:i}=await lo({client:e,worldDeploy:o,table:Gr.tables.metadata__ResourceTag,key:{resource:s.resourceId,tag:co(s.tag,{size:32})}});if(i!==n(s.value))return s}))).filter(mo);return t.length===0?[]:(m("setting",t.length,"resource tags"),(await Promise.all(t.map(async s=>{let i=Jr(s.resourceId),a=`${i.type}:${i.namespace}:${i.name}`;m(`tagging ${a} with ${s.tag}: ${JSON.stringify(s.value)}`);try{return await qr(e,{chain:e.chain??null,address:o.address,abi:Qr,functionName:"metadata__setResourceTag",args:[s.resourceId,co(s.tag,{size:32}),n(s.value)]})}catch(c){m(`failed to set resource tag for ${a}, skipping
14
- ${c instanceof Kr?c.shortMessage:c}`)}}))).filter(mo))}async function yo({client:e,tables:o,systems:r,libraries:n,modules:t=[],salt:s,worldAddress:i,deployerAddress:a,withWorldProxy:c}){let d=a??await Pe(e);await Z(e,d,c),await P({client:e,deployerAddress:d,contracts:[...n.map(f=>({bytecode:f.prepareDeploy(d,n).bytecode,deployedBytecodeSize:f.deployedBytecodeSize,debugLabel:`${f.path}:${f.name} library`})),...r.map(f=>({bytecode:f.prepareDeploy(d,n).bytecode,deployedBytecodeSize:f.deployedBytecodeSize,debugLabel:`${Xr(f)} system`})),...t.map(f=>({bytecode:f.prepareDeploy(d,n).bytecode,deployedBytecodeSize:f.deployedBytecodeSize,debugLabel:`${f.name} module`}))]});let p=i?await Qe(e,i):await Fe(e,d,s??`0x${en(32).toString("hex")}`,c);if(!ke.includes(p.storeVersion))throw new Error(`Unsupported Store version: ${p.storeVersion}`);if(!Me.includes(p.worldVersion))throw new Error(`Unsupported World version: ${p.worldVersion}`);let l=await io({client:e,worldDeploy:p,resourceIds:[...o.map(({tableId:f})=>f),...r.map(({systemId:f})=>f)]});m("waiting for all namespace registration transactions to confirm");for(let f of l)await fo(e,{hash:f});let u=await Ke({client:e,worldDeploy:p,tables:o}),b=await Ye({client:e,deployerAddress:d,libraries:n,worldDeploy:p,systems:r}),w=await oo({client:e,worldDeploy:p,functions:r.flatMap(f=>f.worldFunctions)}),C=await ro({client:e,deployerAddress:d,libraries:n,worldDeploy:p,modules:t}),A=o.map(({tableId:f,label:h})=>({resourceId:f,tag:"label",value:h})),g=r.flatMap(({systemId:f,label:h,abi:zo,worldAbi:No})=>[{resourceId:f,tag:"label",value:h},{resourceId:f,tag:"abi",value:zo.join(`
15
- `)},{resourceId:f,tag:"worldAbi",value:No.join(`
16
- `)}]),v=await po({client:e,worldDeploy:p,tags:[...A,...g],valueToHex:Zr}),y=[...u,...b,...w,...C,...v];m("waiting for all transactions to confirm");for(let f of y)await fo(e,{hash:f});return m("deploy complete"),p}import{createWalletClient as Wn,http as Rn,isHex as Hn}from"viem";import{privateKeyToAccount as jn}from"viem/accounts";import{loadConfig as $n,resolveConfigPath as En}from"@latticexyz/config/node";import{getOutDirectory as Fn,getRpcUrl as zn}from"@latticexyz/common/foundry";import H from"chalk";import{MUDError as ge}from"@latticexyz/common/errors";import cn from"path";import{loadSystemsManifest as mn,resolveSystems as pn}from"@latticexyz/world/node";import{isHex as bo,toFunctionSelector as ho,toFunctionSignature as wo}from"viem";import{readFileSync as on}from"fs";import tn from"path";import{MUDError as re}from"@latticexyz/common/errors";import{size as rn}from"viem";function te(e){return Object.entries(e).flatMap(([o,r])=>Object.entries(r).flatMap(([n,t])=>t.map(s=>({path:o,name:n,start:s.start,length:s.length}))))}function W(e,o,r){let n,t=tn.join(r,e,o+".json");try{n=JSON.parse(on(t,"utf8"))}catch{throw new re(`Error reading file at ${t}`)}let s=n?.bytecode?.object;if(!s)throw new re(`No bytecode found in ${t}`);let i=n?.deployedBytecode?.object;if(!i)throw new re(`No deployed bytecode found in ${t}`);let a=n?.abi;if(!a)throw new re(`No ABI found in ${t}`);let c=te(n?.bytecode?.linkReferences??{});return{abi:a,bytecode:s,placeholders:c,deployedBytecodeSize:rn(i)}}import{groupBy as fn}from"@latticexyz/common/utils";import{readFileSync as sn}from"fs";import{globSync as an}from"glob";import nn from"toposort";function uo(e,o,r){let n=nn(e.flatMap(t=>r(t).map(s=>[o(t),s])));return[...e].sort((t,s)=>n.indexOf(o(t))-n.indexOf(o(s)))}function go(e){let r=an(`${e}/**/*.json`,{ignore:"**/*.abi.json"}).sort().map(n=>JSON.parse(sn(n,"utf8"))).flatMap(n=>{if(!n.metadata)return[];let t=Object.keys(n.metadata.settings.compilationTarget)[0],s=n.metadata.settings.compilationTarget[t],i=n.bytecode.linkReferences;return Object.entries(i).flatMap(([a,c])=>Object.keys(c).map(d=>({path:a,name:d,dependentPath:t,dependentName:s})))});return uo(r,n=>`${n.path}:${n.name}`,n=>[`${n.dependentPath}:${n.dependentName}`])}import{spliceHex as dn}from"@latticexyz/common";import{getCreate2Address as ln}from"viem";function R(e,o){return function(n,t){let s=e;for(let i of o){let a=t.find(c=>c.path===i.path&&c.name===i.name);if(!a)throw new Error(`Could not find library for bytecode placeholder ${i.path}:${i.name}`);s=dn(s,i.start,i.length,a.prepareDeploy(n,t).address)}return{bytecode:s,address:ln({from:n,bytecode:s,salt:S})}}}async function xo({rootDir:e,config:o,forgeOutDir:r}){let n=go(r).map(l=>{let u=W(cn.basename(l.path),l.name,r);return{path:l.path,name:l.name,abi:u.abi,prepareDeploy:R(u.bytecode,u.placeholders),deployedBytecodeSize:u.deployedBytecodeSize}}),s=W("System.sol","System",r).abi.filter(l=>l.type==="function").map(wo),i=await pn({rootDir:e,config:o}),a=await mn({rootDir:e,config:o}),c=i.filter(l=>!l.deploy.disabled).map(l=>{let u=a.systems.find(({systemId:g})=>g===l.systemId);if(!u)throw new Error(`System "${l.label}" not found in systems manifest. Run \`mud build\` before trying again.`);let b=W(`${l.label}.sol`,l.label,r),w=l.deploy.registerWorldFunctions?b.abi.filter(g=>g.type==="function").map(wo).filter(g=>!s.includes(g)).map(g=>{let v=l.namespace===""?g:`${l.namespace}__${g}`;return{signature:v,selector:ho(v),systemId:l.systemId,systemFunctionSignature:g,systemFunctionSelector:ho(g)}}):[],C=l.accessList.filter(g=>bo(g)),A=l.accessList.filter(g=>!bo(g)).map(g=>i.find(y=>y.label===g).systemId);return{...l,allowAll:l.openAccess,allowedAddresses:C,allowedSystemIds:A,prepareDeploy:R(b.bytecode,b.placeholders),deployedBytecodeSize:b.deployedBytecodeSize,worldFunctions:w,abi:u.abi,worldAbi:u.worldAbi}}),d=fn(c,l=>l.systemId),p=Array.from(d.values()).filter(l=>l.length>1).flat();if(p.length){let l=p.map(u=>u.name);throw new Error(`Found systems with overlapping system ID: ${l.join(", ")}.
17
-
18
- System IDs are generated from the first 16 bytes of the name, so you may need to rename them to avoid the overlap.`)}return{systems:c,libraries:n}}import{getChainId as Nn}from"viem/actions";import{existsSync as yn}from"fs";import un from"path";import gn from"chalk";import{getScriptDirectory as bn,forge as hn}from"@latticexyz/common/foundry";async function Co(e,o,r,n,t,s){let i=t?.replaceAll("\\","").split(" ")??[],a=un.join(await bn(),e+".s.sol");if(!yn(a)){console.log(`No script at ${a}, skipping post deploy hook`);return}console.log(gn.blue(`Executing post deploy script at ${a}`)),await hn(["script",e,"--broadcast","--sig","run(address)",o,"--rpc-url",r,"-vvv",s?"--aws":"",...i],{profile:n})}import{kmsKeyToAccount as Ln}from"@latticexyz/common/kms";import Ao from"node:path";import{encodeField as Dn}from"@latticexyz/protocol-parser/internal";import{bytesToHex as Tn}from"viem";import{isHex as wn,size as xn}from"viem";import{z as k}from"zod";import{Abi as Cn}from"abitype/zod";var So=k.object({object:k.string().refine(wn),linkReferences:k.record(k.record(k.array(k.object({start:k.number(),length:k.number()}))))}),Sn=k.object({bytecode:So,deployedBytecode:So,abi:Cn});function ne(e){let o=Sn.parse(e),r=te(o.bytecode.linkReferences);return{abi:o.abi,bytecode:o.bytecode.object,placeholders:r,deployedBytecodeSize:xn(o.deployedBytecode.object)}}import{createRequire as vn}from"node:module";import{findUp as An}from"find-up";async function vo({packageJsonPath:e,artifactPath:o}){let r;try{let n=e??await An("package.json",{cwd:process.cwd()});if(!n)throw new Error("Could not find package.json to import relative to.");r=vn(n)(o)}catch(n){throw console.error(),console.error("Could not import contract artifact at",o),console.error(),n}return ne(r)}import{resolveWithContext as Pn}from"@latticexyz/world/internal";import kn from"@latticexyz/world-module-metadata/out/MetadataModule.sol/MetadataModule.json"assert{type:"json"};var Mn={KeysWithValueModule:"@latticexyz/world-modules/out/KeysWithValueModule.sol/KeysWithValueModule.json",KeysInTableModule:"@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json",UniqueEntityModule:"@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json",Unstable_CallWithSignatureModule:"@latticexyz/world-modules/out/Unstable_CallWithSignatureModule.sol/Unstable_CallWithSignatureModule.json"},se=ne(kn);async function ae(e,o){let r=[{optional:!0,name:"MetadataModule",installAsRoot:!1,installData:"0x",prepareDeploy:R(se.bytecode,se.placeholders),deployedBytecodeSize:se.deployedBytecodeSize,abi:se.abi}],n=await Promise.all(e.modules.map(async t=>{let s=t.artifactPath;if(!s)if(t.name)s=Mn[t.name]??Ao.join(o,`${t.name}.sol`,`${t.name}.json`),console.warn(["","\u26A0\uFE0F Your `mud.config.ts` is using a module with a `name`, but this option is deprecated.","","To resolve this, you can replace this:","",` name: ${JSON.stringify(t.name)}`,"","with this:","",` artifactPath: ${JSON.stringify(s)}`,""].join(`
19
- `));else throw new Error("No `artifactPath` provided for module.");let i=Ao.basename(s,".json"),a=await vo({artifactPath:s}),c=t.args.map(d=>Pn(d,{config:e})).map(d=>{let p=d.value instanceof Uint8Array?Tn(d.value):d.value;return Dn(d.type,p)});if(c.length>1)throw new Error(`${i} module should only have 0-1 args, but had ${c.length} args.`);return{name:i,installAsRoot:t.root,installData:c.length===0?"0x":c[0],prepareDeploy:R(a.bytecode,a.placeholders),deployedBytecodeSize:a.deployedBytecodeSize,abi:a.abi}}));return[...r,...n]}var T={configPath:{type:"string",desc:"Path to the MUD config file"},printConfig:{type:"boolean",desc:"Print the resolved config"},profile:{type:"string",desc:"The foundry profile to use"},saveDeployment:{type:"boolean",desc:"Save the deployment info to a file",default:!0},rpc:{type:"string",desc:"The RPC URL to use. Defaults to the RPC url from the local foundry.toml"},rpcBatch:{type:"boolean",desc:"Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)"},deployerAddress:{type:"string",desc:"Deploy using an existing deterministic deployer (https://github.com/Arachnid/deterministic-deployment-proxy)"},worldAddress:{type:"string",desc:"Deploy to an existing World at the given address"},skipBuild:{type:"boolean",desc:"Skip rebuilding the contracts before deploying"},alwaysRunPostDeploy:{type:"boolean",desc:"Always run PostDeploy.s.sol after each deploy (including during upgrades). By default, PostDeploy.s.sol is only run once after a new world is deployed."},forgeScriptOptions:{type:"string",description:"Options to pass to forge script PostDeploy.s.sol"},salt:{type:"string",desc:"The deployment salt to use. Defaults to a random salt."},kms:{type:"boolean",desc:"Deploy the World with an AWS KMS key instead of local private key."}};async function j(e){let o=e.salt;if(o!=null&&!Hn(o))throw new ge("Expected hex string for salt");let r=e.profile??process.env.FOUNDRY_PROFILE,n=await En(e.configPath),t=await $n(n),s=ie.dirname(n);e.printConfig&&console.log(H.green(`
20
- Resolved config:
21
- `),JSON.stringify(t,null,2));let i=await Fn(r),a=e.rpc??await zn(r);console.log(H.bgBlue(H.whiteBright(`
22
- Deploying MUD contracts${r?" with profile "+r:""} to RPC ${a}
23
- `))),e.skipBuild||await U({rootDir:s,config:t,foundryProfile:r});let{systems:c,libraries:d}=await xo({rootDir:s,config:t,forgeOutDir:i}),p=await ae(t,i),l=Object.values(t.namespaces).flatMap(g=>Object.values(g.tables)).filter(g=>!g.deploy.disabled),u=await(async()=>{if(e.kms){let g=process.env.AWS_KMS_KEY_ID;if(!g)throw new ge("Missing `AWS_KMS_KEY_ID` environment variable. This is required when using with `--kms` option.");return await Ln({keyId:g})}else{let g=process.env.PRIVATE_KEY;if(!g)throw new ge(`Missing PRIVATE_KEY environment variable.
24
- Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
25
- in your contracts directory to use the default anvil private key.`);return jn(g)}})(),b=Wn({transport:Rn(a,{batch:e.rpcBatch?{batchSize:100,wait:1e3}:void 0}),account:u});console.log("Deploying from",b.account.address);let w=Date.now(),C=await yo({deployerAddress:e.deployerAddress,salt:o,worldAddress:e.worldAddress,client:b,tables:l,systems:c,libraries:d,modules:p,withWorldProxy:t.deploy.upgradeableWorldImplementation});(e.worldAddress==null||e.alwaysRunPostDeploy)&&await Co(t.deploy.postDeployScript,C.address,a,r,e.forgeScriptOptions,!!e.kms),console.log(H.green("Deployment completed in",(Date.now()-w)/1e3,"seconds"));let A={worldAddress:C.address,blockNumber:Number(C.deployBlock)};if(e.saveDeployment){let g=await Nn(b),v=ie.join(t.deploy.deploysDirectory,g.toString());Bn(v,{recursive:!0}),ue(ie.join(v,"latest.json"),JSON.stringify(A,null,2)),ue(ie.join(v,Date.now()+".json"),JSON.stringify(A,null,2));let y=[1337,31337],f=On(t.deploy.worldsFile)?JSON.parse(In(t.deploy.worldsFile,"utf-8")):{};f[g]={address:A.worldAddress,blockNumber:y.includes(g)?void 0:A.blockNumber},ue(t.deploy.worldsFile,JSON.stringify(f,null,2)),console.log(H.bgGreen(H.whiteBright(`
26
- Deployment result (written to ${t.deploy.worldsFile} and ${v}):
27
- `)))}return console.log(A),C}var Vn={command:"deploy",describe:"Deploy MUD contracts",builder(e){return e.options(T)},async handler(e){try{await j(e)}catch(o){V(o),process.exit(1)}process.exit(0)}},Do=Vn;import Un from"node:path";import{loadConfig as _n,resolveConfigPath as Kn}from"@latticexyz/config/node";import{worldgen as Jn}from"@latticexyz/world/node";var qn={command:"worldgen",describe:"Autogenerate interfaces for Systems and World based on existing contracts and the config file",builder(e){return e.options({configPath:{type:"string",desc:"Path to the MUD config file"},clean:{type:"boolean",desc:"Clear the worldgen directory before generating new interfaces (defaults to true)",default:!0}})},async handler(e){await Yn(e),process.exit(0)}};async function Yn(e){let o=await Kn(e.configPath),r=await _n(o),n=Un.dirname(o);await Jn({rootDir:n,config:r,clean:e.clean})}var To=qn;import L from"chalk";import{readFileSync as es,writeFileSync as os}from"fs";import he from"path";import{MUDError as $}from"@latticexyz/common/errors";var Po={name:"@latticexyz/cli",version:"2.2.0",description:"Command line interface for mud",repository:{type:"git",url:"https://github.com/latticexyz/mud.git",directory:"packages/cli"},license:"MIT",type:"module",exports:{".":"./dist/index.js"},typesVersions:{"*":{index:["./dist/index.d.ts"]}},bin:{mud:"./bin/mud.js"},files:["bin","dist"],scripts:{build:"pnpm run build:js && pnpm run build:test-tables","build:js":"tsup && chmod +x ./dist/mud.js","build:test-tables":"tsx ./scripts/generate-test-tables.ts",clean:"pnpm run clean:js && pnpm run clean:test-tables","clean:js":"shx rm -rf dist","clean:test-tables":"shx rm -rf src/**/codegen",dev:"tsup --watch",lint:"eslint . --ext .ts",test:"tsc --noEmit && forge test","test:ci":"pnpm run test"},dependencies:{"@ark/util":"catalog:","@aws-sdk/client-kms":"^3.556.0","@latticexyz/abi-ts":"workspace:*","@latticexyz/common":"workspace:*","@latticexyz/config":"workspace:*","@latticexyz/gas-report":"workspace:*","@latticexyz/protocol-parser":"workspace:*","@latticexyz/schema-type":"workspace:*","@latticexyz/store":"workspace:*","@latticexyz/utils":"workspace:*","@latticexyz/world":"workspace:*","@latticexyz/world-module-metadata":"workspace:*",abitype:"catalog:","asn1.js":"^5.4.1",chalk:"^5.0.1",chokidar:"^3.5.3",debug:"^4.3.4",dotenv:"^16.0.3",execa:"^7.0.0","find-up":"^6.3.0",glob:"^10.4.2",openurl:"^1.1.1","p-queue":"^7.4.1","p-retry":"^5.1.2",path:"^0.12.7",rxjs:"7.5.5","throttle-debounce":"^5.0.0",toposort:"^2.0.2",typescript:"5.4.2",viem:"catalog:",yargs:"^17.7.1",zod:"3.23.8","zod-validation-error":"^1.3.0"},devDependencies:{"@types/debug":"^4.1.7","@types/ejs":"^3.1.1","@types/node":"^18.15.11","@types/openurl":"^1.0.0","@types/throttle-debounce":"^5.0.0","@types/toposort":"^2.0.6","@types/yargs":"^17.0.10","ds-test":"https://github.com/dapphub/ds-test.git#e282159d5170298eb2455a6c05280ab5a73a4ef0","forge-std":"https://github.com/foundry-rs/forge-std.git#74cfb77e308dd188d2f58864aaf44963ae6b88b1",tsup:"^6.7.0",tsx:"^3.12.6",vitest:"0.34.6"}};import{globSync as ts}from"glob";import{ZodError as Qn,z as ko}from"zod";var Zn=ko.object({MUD_PACKAGES:ko.string().transform(e=>JSON.parse(e))});function Xn(){try{return Zn.parse({MUD_PACKAGES:'{"@latticexyz/abi-ts":{"localPath":"packages/abi-ts"},"@latticexyz/block-logs-stream":{"localPath":"packages/block-logs-stream"},"@latticexyz/cli":{"localPath":"packages/cli"},"@latticexyz/common":{"localPath":"packages/common"},"@latticexyz/config":{"localPath":"packages/config"},"create-mud":{"localPath":"packages/create-mud"},"@latticexyz/dev-tools":{"localPath":"packages/dev-tools"},"@latticexyz/explorer":{"localPath":"packages/explorer"},"@latticexyz/faucet":{"localPath":"packages/faucet"},"@latticexyz/gas-report":{"localPath":"packages/gas-report"},"@latticexyz/protocol-parser":{"localPath":"packages/protocol-parser"},"@latticexyz/query":{"localPath":"packages/query"},"@latticexyz/react":{"localPath":"packages/react"},"@latticexyz/recs":{"localPath":"packages/recs"},"@latticexyz/schema-type":{"localPath":"packages/schema-type"},"solhint-config-mud":{"localPath":"packages/solhint-config-mud"},"solhint-plugin-mud":{"localPath":"packages/solhint-plugin-mud"},"@latticexyz/store-indexer":{"localPath":"packages/store-indexer"},"@latticexyz/store-sync":{"localPath":"packages/store-sync"},"@latticexyz/store":{"localPath":"packages/store"},"@latticexyz/utils":{"localPath":"packages/utils"},"@latticexyz/world-module-metadata":{"localPath":"packages/world-module-metadata"},"@latticexyz/world-modules":{"localPath":"packages/world-modules"},"@latticexyz/world":{"localPath":"packages/world"}}'})}catch(e){if(e instanceof Qn){let{...o}=e.format();console.error(`
28
- Missing or invalid environment variables:
29
-
30
- ${Object.keys(o).join(`
31
- `)}
32
- `),process.exit(1)}throw e}}var be=Xn().MUD_PACKAGES;var rs={command:"set-version",describe:"Set MUD version in all package.json files and optionally backup the previously installed version",builder(e){return e.options({mudVersion:{alias:"v",type:"string",description:"Set MUD to the given version"},tag:{alias:"t",type:"string",description:"Set MUD to the latest version with the given tag from npm"},commit:{alias:"c",type:"string",description:"Set MUD to the version based on a given git commit hash from npm"},link:{alias:"l",type:"string",description:"Relative path to the local MUD root directory to link"}})},async handler(e){try{let o=["mudVersion","link","tag","commit","restore"],r=o.reduce((t,s)=>e[s]?t+1:t,0);if(r===0)throw new $(`You need to provide one these options: ${o.join(", ")}`);if(r>1)throw new $(`These options are mutually exclusive: ${o.join(", ")}`);e.link||(e.mudVersion=await ns(e));let n=ts("**/package.json").sort().filter(t=>!t.includes("node_modules"));for(let t of n)ss(t,e)}catch(o){V(o)}finally{process.exit(0)}}};async function ns(e){e.mudVersion==="canary"&&(e.tag="main");let o;try{console.log(L.blue("Fetching available versions")),o=await(await fetch(`https://registry.npmjs.org/${Po.name}`)).json()}catch{throw new $("Could not fetch available MUD versions")}if(e.tag){let r=o["dist-tags"][e.tag];if(!r)throw new $(`Could not find npm version with tag "${e.tag}"`);return console.log(L.green(`Latest version with tag ${e.tag}: ${r}`)),r}if(e.commit){let r=e.commit.substring(0,8),n=Object.keys(o.versions).find(t=>t.includes(r));if(!n)throw new $(`Could not find npm version based on commit "${e.commit}"`);return console.log(L.green(`Version from commit ${e.commit}: ${n}`)),n}return e.mudVersion}function ss(e,o){let{link:r}=o,{mudVersion:n}=o,t=as(e),s=Object.keys(be),i={};for(let d in t.dependencies)s.includes(d)&&(i[d]=t.dependencies[d]);let a={};for(let d in t.devDependencies)s.includes(d)&&(a[d]=t.devDependencies[d]);for(let d in t.dependencies)s.includes(d)&&(t.dependencies[d]=c(d,"dependencies"));for(let d in t.devDependencies)s.includes(d)&&(t.devDependencies[d]=c(d,"devDependencies"));return os(e,JSON.stringify(t,null,2)+`
33
- `),console.log(`Updating ${e}`),Mo(i,t.dependencies),Mo(a,t.devDependencies),t;function c(d,p){return r&&(n=is(e,r,d)),n||t[p][d]}}function as(e){try{let o=es(e,"utf8");return JSON.parse(o)}catch{throw new $("Could not read JSON at "+e)}}function Mo(e,o){for(let r in e)e[r]!==o[r]&&console.log(`${r}: ${L.red(e[r])} -> ${L.green(o[r])}`)}function is(e,o,r){let n=he.relative(he.dirname(e),process.cwd());return"link:"+he.join(n,o,be[r].localPath)}var Oo=rs;import{anvil as ds,forge as ls,getRpcUrl as cs}from"@latticexyz/common/foundry";import ms from"chalk";var ps={...T,port:{type:"number",description:"Port to run internal node for fork testing on",default:4242},worldAddress:{type:"string",description:"Address of an existing world contract. If provided, deployment is skipped and the RPC provided in the foundry.toml is used for fork testing."},forgeOptions:{type:"string",description:"Options to pass to forge test"}},fs={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options(ps)},async handler(e){if(!e.worldAddress){let t=["--block-base-fee-per-gas","0","--port",String(e.port)];ds(t)}let o=e.worldAddress?await cs(e.profile):`http://127.0.0.1:${e.port}`,r=e.worldAddress??(await j({...e,saveDeployment:!1,rpc:o})).address;console.log(ms.blue("World address",r));let n=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{await ls(["test","--fork-url",o,...n],{profile:e.profile,env:{WORLD_ADDRESS:r}}),process.exit(0)}catch(t){console.error(t),process.exit(1)}}},Bo=fs;import ys from"node:path";import Io from"node:fs";import{loadConfig as us,resolveConfigPath as gs}from"@latticexyz/config/node";import{MUDError as Wo}from"@latticexyz/common/errors";import{cast as bs,getRpcUrl as hs}from"@latticexyz/common/foundry";import ws from"@latticexyz/world/mud.config";import{createClient as xs,http as Cs}from"viem";import{getChainId as Ss,readContract as vs}from"viem/actions";import{resolveSystems as As}from"@latticexyz/world/node";var Ds=ws.namespaces.world.tables.Systems.tableId;function Ts(e,o){if(!Io.existsSync(e))throw new Wo(`Missing expected worlds.json file at "${e}"`);let r=JSON.parse(Io.readFileSync(e,"utf-8"));if(!r[o])throw new Wo(`Missing chain ID ${o} in "${e}"`);return r[o].address}var Ps={command:"trace",describe:"Display the trace of a transaction",builder(e){return e.options({tx:{type:"string",required:!0,description:"Transaction hash to replay"},worldAddress:{type:"string",description:"World contract address. Defaults to the value from worlds.json, based on rpc's chainId"},configPath:{type:"string",description:"Path to the MUD config file"},profile:{type:"string",description:"The foundry profile to use"},rpc:{type:"string",description:"json rpc endpoint. Defaults to foundry's configured eth_rpc_url"}})},async handler(e){let o=await gs(e.configPath),r=ys.dirname(o),n=e.profile??process.env.FOUNDRY_PROFILE,t=e.rpc??await hs(n),s=await us(o),i=xs({transport:Cs(t)}),a=await Ss(i),c=e.worldAddress??Ts(s.deploy.worldsFile,a),d=await As({rootDir:r,config:s}),p=await Promise.all(d.map(async u=>({label:u.label,address:await vs(i,{abi:x,address:c,functionName:"getField",args:[Ds,[u.systemId],0]})}))),l=await bs(["run","--label",`${c}:World`,...p.map(({label:u,address:b})=>["--label",`${b}:${u}`]).flat(),`${e.tx}`]);console.log(l),process.exit(0)}},Ro=Ps;import{anvil as ks,getScriptDirectory as Ms,getSrcDirectory as Os}from"@latticexyz/common/foundry";import O from"chalk";import Bs from"chokidar";import{loadConfig as Is,resolveConfigPath as Ws}from"@latticexyz/config/node";import Rs from"path";import{homedir as Hs}from"os";import{rmSync as js}from"fs";import{BehaviorSubject as $s,debounceTime as Es,exhaustMap as Fs,filter as zs}from"rxjs";import{isDefined as Ns}from"@latticexyz/common/utils";var Ls={rpc:T.rpc,configPath:T.configPath,alwaysRunPostDeploy:T.alwaysRunPostDeploy,forgeScriptOptions:T.forgeScriptOptions,worldAddress:T.worldAddress},Vs={command:"dev-contracts",describe:"Start a development server for MUD contracts",builder(e){return e.options(Ls)},async handler(e){let o=e.rpc,r=e.configPath??await Ws(e.configPath),n=await Os(),t=await Ms(),s=await Is(r);if(!e.rpc){console.log(O.gray("Cleaning devnode cache"));let d=Hs();js(Rs.join(d,".foundry","anvil","tmp"),{recursive:!0,force:!0}),ks(["--block-time","1","--block-base-fee-per-gas","0"]),o="http://127.0.0.1:8545"}let i=new $s(Date.now());Bs.watch([r,n,t],{ignoreInitial:!0}).on("all",async(d,p)=>{p.includes(r)&&(console.log(O.blue("Config changed, queuing deploy\u2026")),i.next(Date.now())),(p.includes(n)||p.includes(t))&&(p.includes(s.codegen.outputDirectory)||(console.log(O.blue("Contracts changed, queuing deploy\u2026")),i.next(Date.now())))});let a=e.worldAddress;i.pipe(Es(200),Fs(async d=>{a&&console.log(O.blue("Rebuilding and upgrading world\u2026"));try{let p=await j({...e,configPath:r,rpc:o,rpcBatch:!1,skipBuild:!1,printConfig:!1,profile:void 0,saveDeployment:!0,deployerAddress:void 0,worldAddress:a,salt:"0x",kms:void 0});return a=p.address,d<i.value?i.next(i.value):console.log(O.gray(`
34
- Waiting for file changes\u2026
35
- `)),p}catch(p){console.error(O.bgRed(O.whiteBright(`
36
- Error while attempting deploy
37
- `))),console.error(p),console.log(O.gray(`
38
- Waiting for file changes\u2026
39
- `))}}),zs(Ns)).subscribe()}},Ho=Vs;import{getCreate2Address as jo,sliceHex as _s,zeroHash as Ks}from"viem";import{forge as Us}from"@latticexyz/common/foundry";async function B(e){let o=["verify-contract",e.address,e.name,"--rpc-url",e.rpc];e.verifier&&o.push("--verifier",e.verifier),e.verifierUrl&&o.push("--verifier-url",e.verifierUrl),await Us(o,{cwd:e.cwd})}import Js from"p-queue";import{MUDError as qs}from"@latticexyz/common/errors";import{getStorageAt as Ys}from"viem/actions";import{execa as we}from"execa";var Gs="0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";async function $o({client:e,rpc:o,systems:r,modules:n,worldAddress:t,deployerAddress:s,verifier:i,verifierUrl:a}){let c=s??await J(e);if(!c)throw new qs("No deployer address provided or found.");let d=await Ys(e,{address:t,slot:Gs}),p=d&&d!==Ks,l=new Js({concurrency:4});if(r.map(({name:u,bytecode:b})=>l.add(()=>B({name:u,rpc:o,verifier:i,verifierUrl:a,address:jo({from:c,bytecode:b,salt:S})}).catch(w=>{console.error(`Error verifying system contract ${u}:`,w)}))),i==="sourcify")if(await we("npm",["install"],{cwd:"node_modules/@latticexyz/store"}),await we("npm",["install"],{cwd:"node_modules/@latticexyz/world"}),await we("npm",["install"],{cwd:"node_modules/@latticexyz/world-modules"}),Object.entries(p?Q(c):G(c)).map(([u,{bytecode:b}])=>l.add(()=>B({cwd:"node_modules/@latticexyz/world",name:u,rpc:o,verifier:i,verifierUrl:a,address:jo({from:c,bytecode:b,salt:S})}).catch(w=>{console.error(`Error verifying world factory contract ${u}:`,w)}))),n.map(({name:u,prepareDeploy:b})=>{let{address:w}=b(c,[]);return l.add(()=>B({cwd:"node_modules/@latticexyz/world-modules",name:u,rpc:o,verifier:i,verifierUrl:a,address:w}).catch(C=>{console.error(`Error verifying module contract ${u}:`,C)}))}),p){let u=_s(d,-20);l.add(()=>B({cwd:"node_modules/@latticexyz/world",name:"WorldProxy",rpc:o,verifier:i,verifierUrl:a,address:t}).catch(b=>{console.error("Error verifying WorldProxy contract:",b)})),l.add(()=>B({cwd:"node_modules/@latticexyz/world",name:"World",rpc:o,verifier:i,verifierUrl:a,address:u}).catch(b=>{console.error("Error verifying World contract:",b)}))}else l.add(()=>B({cwd:"node_modules/@latticexyz/world",name:"World",rpc:o,verifier:i,verifierUrl:a,address:t}).catch(u=>{console.error("Error verifying World contract:",u)}));else console.log(""),console.log(`Note: MUD is currently unable to verify store, world, and world-modules contracts with ${i}. We are planning to expand support in a future version.`),console.log("")}import{loadConfig as Qs,resolveConfigPath as Zs}from"@latticexyz/config/node";import{resolveSystems as Xs}from"@latticexyz/world/node";import{getOutDirectory as ea,getRpcUrl as oa}from"@latticexyz/common/foundry";import{createWalletClient as ta,http as ra}from"viem";import Eo from"chalk";import na from"node:path";var sa={deployerAddress:{type:"string",desc:"Deploy using an existing deterministic deployer (https://github.com/Arachnid/deterministic-deployment-proxy)"},worldAddress:{type:"string",required:!0,desc:"Verify an existing World at the given address"},configPath:{type:"string",desc:"Path to the MUD config file"},profile:{type:"string",desc:"The foundry profile to use"},rpc:{type:"string",desc:"The RPC URL to use. Defaults to the RPC url from the local foundry.toml"},rpcBatch:{type:"boolean",desc:"Enable batch processing of RPC requests in viem client (defaults to batch size of 100 and wait of 1s)"},verifier:{type:"string",desc:"The verifier to use. Defaults to blockscout",default:"blockscout"},verifierUrl:{type:"string",desc:"The verification provider."}},aa={command:"verify",describe:"Verify contracts",builder(e){return e.options(sa)},async handler(e){let o=e.profile??process.env.FOUNDRY_PROFILE,r=await Zs(e.configPath),n=na.dirname(r),t=await Qs(r),s=await ea(o),i=e.rpc??await oa(o);console.log(Eo.bgBlue(Eo.whiteBright(`
40
- Verifying MUD contracts${o?" with profile "+o:""} to RPC ${i}
41
- `)));let a=ta({transport:ra(i,{batch:e.rpcBatch?{batchSize:100,wait:1e3}:void 0})}),d=(await Xs({rootDir:n,config:t})).map(l=>{let u=W(`${l.name}.sol`,l.name,s);return{name:l.name,bytecode:u.bytecode}}),p=await ae(t,s);await $o({client:a,rpc:i,systems:d,modules:p,deployerAddress:e.deployerAddress,worldAddress:e.worldAddress,verifier:e.verifier,verifierUrl:e.verifierUrl})}},Fo=aa;var hy=[xe,Do,Ce,ia,Se,ve,To,Oo,Bo,Ro,Ho,da,Fo];export{hy as commands};
42
- //# sourceMappingURL=commands-3HTBXM4P.js.map