@latticexyz/cli 2.0.0-main-aa5b2272 → 2.0.0-main-d844cd44

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.
package/dist/mud.js CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
- import $n from"yargs";import{hideBin as Nn}from"yargs/helpers";import Rn from"@latticexyz/gas-report";import En from"@latticexyz/abi-ts";import{rmSync as wo}from"fs";import{homedir as xo}from"os";import So from"path";import{execa as vo}from"execa";var Co={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=xo();wo(So.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 t=vo("anvil",r,{stdio:["inherit","inherit","inherit"]});process.on("SIGINT",()=>{console.log(`
3
- gracefully shutting down from SIGINT (Crtl-C)`),t.kill(),process.exit()}),await t}},ne=Co;import{FaucetServiceDefinition as To}from"@latticexyz/services/faucet";import{createChannel as ko,createClient as Do}from"nice-grpc-web";import se from"chalk";import{NodeHttpTransport as Ao}from"@improbable-eng/grpc-web-node-http-transport";function Io(e){return Do(To,ko(e,Ao()))}var Oo={command:"faucet",describe:"Interact with a MUD faucet",builder(e){return e.options({dripDev:{type:"boolean",desc:"Request a drip from the dev endpoint (requires faucet to have dev mode enabled)",default:!0},faucetUrl:{type:"string",desc:"URL of the MUD faucet",default:"https://faucet.testnet-mud-services.linfra.xyz"},address:{type:"string",desc:"Ethereum address to fund",required:!0}})},async handler({dripDev:e,faucetUrl:o,address:r}){let t=Io(o);e&&(console.log(se.yellow("Dripping to",r)),await t.dripDev({address:r}),console.log(se.yellow("Success"))),process.exit(0)}},ie=Oo;var Po={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)}},ae=Po;import Mo from"path";import{loadConfig as Wo}from"@latticexyz/config/node";import{tablegen as jo}from"@latticexyz/store/codegen";import{getRemappings as Fo,getSrcDirectory as Ro}from"@latticexyz/common/foundry";var Eo={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 config file"}})},async handler({configPath:e}){let o=await Wo(e),r=await Ro(),t=await Fo();await jo(o,Mo.join(r,o.codegenDirectory),t),process.exit(0)}},ce=Eo;import N from"chalk";import{ZodError as $o}from"zod";import{fromZodError as No,ValidationError as Bo}from"zod-validation-error";import{NotInsideProjectError as Ho}from"@latticexyz/config";import{MUDError as Uo}from"@latticexyz/common/errors";function M(e){if(e instanceof Bo)console.log(N.redBright(e.message));else if(e instanceof $o){let o=No(e,{prefixSeparator:`
2
+ import _n from"yargs";import{hideBin as Ln}from"yargs/helpers";import Un from"@latticexyz/gas-report";import Vn from"@latticexyz/abi-ts";import{rmSync as xo}from"fs";import{homedir as Co}from"os";import So from"path";import{execa as vo}from"execa";var Do={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=Co();xo(So.join(o,".foundry","anvil","tmp"),{recursive:!0,force:!0});let t=["-b",String(e),"--block-base-fee-per-gas","0"];console.log(`Running: anvil ${t.join(" ")}`);let r=vo("anvil",t,{stdio:["inherit","inherit","inherit"]});process.on("SIGINT",()=>{console.log(`
3
+ gracefully shutting down from SIGINT (Crtl-C)`),r.kill(),process.exit()}),await r}},ae=Do;import{FaucetServiceDefinition as To}from"@latticexyz/services/faucet";import{createChannel as ko,createClient as Ao}from"nice-grpc-web";import ie from"chalk";import{NodeHttpTransport as Io}from"@improbable-eng/grpc-web-node-http-transport";function Oo(e){return Ao(To,ko(e,Io()))}var Po={command:"faucet",describe:"Interact with a MUD faucet",builder(e){return e.options({dripDev:{type:"boolean",desc:"Request a drip from the dev endpoint (requires faucet to have dev mode enabled)",default:!0},faucetUrl:{type:"string",desc:"URL of the MUD faucet",default:"https://faucet.testnet-mud-services.linfra.xyz"},address:{type:"string",desc:"Ethereum address to fund",required:!0}})},async handler({dripDev:e,faucetUrl:o,address:t}){let r=Oo(o);e&&(console.log(ie.yellow("Dripping to",t)),await r.dripDev({address:t}),console.log(ie.yellow("Success"))),process.exit(0)}},ce=Po;var Mo={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)}},le=Mo;import Wo from"path";import{loadConfig as jo}from"@latticexyz/config/node";import{tablegen as Fo}from"@latticexyz/store/codegen";import{getRemappings as Ro,getSrcDirectory as $o}from"@latticexyz/common/foundry";var Eo={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 config file"}})},async handler({configPath:e}){let o=await jo(e),t=await $o(),r=await Ro();await Fo(o,Wo.join(t,o.codegenDirectory),r),process.exit(0)}},de=Eo;import N from"chalk";import{ZodError as No}from"zod";import{fromZodError as Bo,ValidationError as Ho}from"zod-validation-error";import{NotInsideProjectError as Uo}from"@latticexyz/config";import{MUDError as Vo}from"@latticexyz/common/errors";function W(e){if(e instanceof Ho)console.log(N.redBright(e.message));else if(e instanceof No){let o=Bo(e,{prefixSeparator:`
4
4
  - `,issueSeparator:`
5
- - `});console.log(N.redBright(o.message))}else e instanceof Ho?(console.log(N.red(e.message)),console.log(""),console.log(N.blue("To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/"))):e instanceof Uo?console.log(N.red(e)):console.log(e)}import J from"node:path";import{existsSync as xr,mkdirSync as Sr,readFileSync as vr,writeFileSync as X}from"node:fs";import{getBytecode as Lo,sendRawTransaction as Ko,sendTransaction as zo,waitForTransactionReceipt as de}from"viem/actions";var P={gasPrice:1e11,gasLimit:1e5,signerAddress:"3fab184622dc19b6109349b94811493bf2a45362",transaction:"f8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222",address:"4e59b44847b379578588920ca78fbf26c0b4956c"};import _o from"debug";var le=_o("mud:cli");var d=le.extend("deploy");var C=`0x${P.address}`;async function me(e){if(await Lo(e,{address:C})){d("found create2 deployer at",C);return}d("sending gas for create2 deployer to signer at",P.signerAddress);let r=await zo(e,{chain:e.chain??null,to:`0x${P.signerAddress}`,value:BigInt(P.gasLimit)*BigInt(P.gasPrice)}),t=await de(e,{hash:r});if(t.status!=="success")throw console.error("failed to send gas to deployer signer",t),new Error("failed to send gas to deployer signer");d("deploying create2 deployer at",C);let n=await Ko(e,{serializedTransaction:`0x${P.transaction}`}),s=await de(e,{hash:n});if(s.contractAddress!==C)throw console.error("unexpected contract address for deployer",s),new Error("unexpected contract address for deployer")}import{waitForTransactionReceipt as yt}from"viem/actions";import at from"@latticexyz/world/out/CoreModule.sol/CoreModule.json"assert{type:"json"};import ct from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.json"assert{type:"json"};import{parseAbi as lt,getCreate2Address as ye,encodeDeployData as ge}from"viem";import{concatHex as ot,getCreate2Address as tt}from"viem";import{getBytecode as rt}from"viem/actions";import{padHex as qo}from"viem";import Go from"@latticexyz/store/mud.config.js";import Yo from"@latticexyz/world/mud.config.js";import Zo from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import Qo from"@latticexyz/world-modules/out/IModule.sol/IModule.abi.json"assert{type:"json"};import{resourceToHex as Jo}from"@latticexyz/common";import{resolveUserTypes as pe}from"@latticexyz/store";function B(e){let o={...e.userTypes,...Object.fromEntries(Object.entries(e.enums).map(([r])=>[r,{internalType:"uint8"}]))};return Object.fromEntries(Object.entries(e.tables).map(([r,t])=>[`${e.namespace}_${r}`,{namespace:e.namespace,name:t.name,tableId:Jo({type:t.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:t.name}),keySchema:pe(t.keySchema,o),valueSchema:pe(t.valueSchema,o)}]))}import{helloStoreEvent as Xo}from"@latticexyz/store";import{helloWorldEvent as et}from"@latticexyz/world";var D=qo("0x",{size:32}),W=B(Go),T=B(Yo),U=[Xo,et],v=[...Zo,...Qo],fe=["1.0.0-unaudited"],ue=["1.0.0-unaudited"];import{sendTransaction as nt}from"@latticexyz/common";import st from"p-retry";import{wait as it}from"@latticexyz/common/utils";async function j({client:e,bytecode:o,label:r="contract"}){let t=tt({from:C,salt:D,bytecode:o});return await rt(e,{address:t,blockTag:"pending"})?(d("found",r,"at",t),[]):(d("deploying",r,"at",t),[await st(()=>nt(e,{chain:e.chain??null,to:C,data:ot([D,o])}),{retries:3,onFailedAttempt:async s=>{let c=s.attemptNumber*500;d(`failed to deploy ${r}, retrying in ${c}ms...`),await it(c)}})])}var be=ge({bytecode:at.bytecode.object,abi:[]}),dt=ye({from:C,bytecode:be,salt:D}),he=ge({bytecode:ct.bytecode.object,abi:lt(["constructor(address)"]),args:[dt]}),we=ye({from:C,bytecode:he,salt:D});async function xe(e){return(await Promise.all([j({client:e,bytecode:be,label:"core module"}),j({client:e,bytecode:he,label:"world factory"})])).flat()}import gt from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{writeContract as bt}from"@latticexyz/common";import{AbiEventSignatureNotFoundError as mt,decodeEventLog as pt,hexToString as Se,parseAbi as ft,trim as ve}from"viem";import{isDefined as ut}from"@latticexyz/common/utils";function V(e){let o=e.map(c=>{try{return{...c,...pt({strict:!0,abi:ft(U),topics:c.topics,data:c.data})}}catch(i){if(i instanceof mt)return;throw i}}).filter(ut),{address:r,deployBlock:t,worldVersion:n,storeVersion:s}=o.reduce((c,i)=>({...c,address:i.address,deployBlock:i.blockNumber,...i.eventName==="HelloWorld"?{worldVersion:Se(ve(i.args.worldVersion,{dir:"right"}))}:null,...i.eventName==="HelloStore"?{storeVersion:Se(ve(i.args.storeVersion,{dir:"right"}))}:null}),{});if(r==null)throw new Error("could not find world address");if(t==null)throw new Error("could not find world deploy block number");if(n==null)throw new Error("could not find world version");if(s==null)throw new Error("could not find store version");return{address:r,deployBlock:t,worldVersion:n,storeVersion:s}}async function Ce(e){await xe(e),d("deploying world");let o=await bt(e,{chain:e.chain??null,address:we,abi:gt,functionName:"deployWorld"});d("waiting for world deploy");let r=await yt(e,{hash:o});if(r.status!=="success")throw console.error("world deploy failed",r),new Error("world deploy failed");let t=V(r.logs.map(n=>n));return d("deployed world to",t.address,"at block",t.deployBlock),{...t,stateBlock:t.deployBlock}}import{writeContract as Tt}from"@latticexyz/common";import{valueSchemaToFieldLayoutHex as kt,keySchemaToHex as Dt,valueSchemaToHex as At}from"@latticexyz/protocol-parser";function S({namespace:e,name:o}){return`${e}:${o}`}import{parseAbiItem as ht,decodeAbiParameters as Te,parseAbiParameters as ke}from"viem";import{hexToResource as wt}from"@latticexyz/common";import{storeSetRecordEvent as xt}from"@latticexyz/store";import{getLogs as St}from"viem/actions";import{decodeKey as vt,decodeValueArgs as Ct,hexToSchema as De}from"@latticexyz/protocol-parser";async function Ae({client:e,worldDeploy:o}){d("looking up tables for",o.address);let t=(await St(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:ht(xt),args:{tableId:W.store_Tables.tableId}})).map(n=>{let{tableId:s}=vt(W.store_Tables.keySchema,n.args.keyTuple),{namespace:c,name:i}=wt(s),m=Ct(W.store_Tables.valueSchema,n.args),a=De(m.keySchema),p=De(m.valueSchema),w=Te(ke("string[]"),m.abiEncodedKeyNames)[0],u=Te(ke("string[]"),m.abiEncodedFieldNames)[0],f=[...p.staticFields,...p.dynamicFields],g=Object.fromEntries(a.staticFields.map((b,l)=>[w[l],b])),h=Object.fromEntries(f.map((b,l)=>[u[l],b]));return{namespace:c,name:i,tableId:s,keySchema:g,valueSchema:h}});return d("found",t.length,"tables for",o.address),t}import It from"p-retry";import{wait as Ot}from"@latticexyz/common/utils";async function Ie({client:e,worldDeploy:o,tables:r}){let n=(await Ae({client:e,worldDeploy:o})).map(i=>i.tableId),s=r.filter(i=>n.includes(i.tableId));s.length&&d("existing tables",s.map(S).join(", "));let c=r.filter(i=>!n.includes(i.tableId));return c.length?(d("registering tables",c.map(S).join(", ")),await Promise.all(c.map(i=>It(()=>Tt(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"registerTable",args:[i.tableId,kt(i.valueSchema),Dt(i.keySchema),At(i.valueSchema),Object.keys(i.keySchema),Object.keys(i.valueSchema)]}),{retries:3,onFailedAttempt:async m=>{let a=m.attemptNumber*500;d(`failed to register table ${S(i)}, retrying in ${a}ms...`),await Ot(a)}})))):[]}import{getAddress as I}from"viem";import{writeContract as q}from"@latticexyz/common";import{parseAbiItem as Pt}from"viem";import{getLogs as Mt}from"viem/actions";import{storeSpliceStaticDataEvent as Wt}from"@latticexyz/store";async function _({client:e,worldDeploy:o}){d("looking up resource IDs for",o.address);let t=(await Mt(e,{strict:!0,address:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock,event:Pt(Wt),args:{tableId:W.store_ResourceIds.tableId}})).map(n=>n.args.keyTuple[0]);return d("found",t.length,"resource IDs for",o.address),t}import{hexToResource as Jt}from"@latticexyz/common";import{decodeValueArgs as jt,encodeKey as Ft}from"@latticexyz/protocol-parser";import{readContract as Rt}from"viem/actions";async function A({client:e,worldDeploy:o,table:r,key:t}){let[n,s,c]=await Rt(e,{blockNumber:o.stateBlock,address:o.address,abi:v,functionName:"getRecord",args:[r.tableId,Ft(r.keySchema,t)]});return jt(r.valueSchema,{staticData:n,encodedLengths:s,dynamicData:c})}import{getFunctionSelector as Et,parseAbiItem as $t}from"viem";import{storeSetRecordEvent as Nt}from"@latticexyz/store";import{getLogs as Bt}from"viem/actions";import{decodeValueArgs as Ht}from"@latticexyz/protocol-parser";import{hexToResource as Ut}from"@latticexyz/common";async function L({client:e,worldDeploy:o}){d("looking up function signatures for",o.address);let t=(await Bt(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:$t(Nt),args:{tableId:T.world_FunctionSignatures.tableId}})).map(s=>Ht(T.world_FunctionSignatures.valueSchema,s.args).functionSignature);return d("found",t.length,"function signatures for",o.address),await Promise.all(t.map(async s=>{let c=Et(s),{systemId:i,systemFunctionSelector:m}=await A({client:e,worldDeploy:o,table:T.world_FunctionSelectors,key:{functionSelector:c}}),{namespace:a,name:p}=Ut(i),w=a===""?s:s.replace(`${a}_${p}_`,"");return{signature:s,selector:c,systemId:i,systemFunctionSignature:w,systemFunctionSelector:m}}))}import{parseAbiItem as Vt,getAddress as _t}from"viem";import{storeSpliceStaticDataEvent as Lt}from"@latticexyz/store";import{getLogs as Kt}from"viem/actions";import{decodeKey as zt}from"@latticexyz/protocol-parser";async function K({client:e,worldDeploy:o}){d("looking up resource access for",o.address);let t=(await Kt(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:Vt(Lt),args:{tableId:T.world_ResourceAccess.tableId}})).map(s=>zt(T.world_ResourceAccess.keySchema,s.args.keyTuple)),n=(await Promise.all(t.map(async s=>[s,await A({client:e,worldDeploy:o,table:T.world_ResourceAccess,key:s})]))).filter(([,s])=>s.access).map(([s])=>({resourceId:s.resourceId,address:_t(s.caller)}));return d("found",n.length,"resource<>address access pairs"),n}async function Oe({client:e,worldDeploy:o}){let[r,t,n]=await Promise.all([_({client:e,worldDeploy:o}),L({client:e,worldDeploy:o}),K({client:e,worldDeploy:o})]),s=r.map(Jt).filter(c=>c.type==="system");return d("looking up systems",s.map(S).join(", ")),await Promise.all(s.map(async c=>{let{system:i,publicAccess:m}=await A({client:e,worldDeploy:o,table:T.world_Systems,key:{systemId:c.resourceId}}),a=t.filter(p=>p.systemId===c.resourceId);return{address:i,namespace:c.namespace,name:c.name,systemId:c.resourceId,allowAll:m,allowedAddresses:n.filter(({resourceId:p})=>p===c.resourceId).map(({address:p})=>p),functions:a}}))}import{wait as G}from"@latticexyz/common/utils";import Y from"p-retry";async function Pe({client:e,worldDeploy:o,systems:r}){let[t,n]=await Promise.all([Oe({client:e,worldDeploy:o}),K({client:e,worldDeploy:o})]),s=r.map(l=>l.systemId),c=n.filter(({resourceId:l})=>s.includes(l)),i=r.flatMap(l=>l.allowedAddresses.map(y=>({resourceId:l.systemId,address:y}))),m=i.filter(l=>!c.some(({resourceId:y,address:x})=>y===l.resourceId&&I(x)===I(l.address))),a=c.filter(l=>!i.some(({resourceId:y,address:x})=>y===l.resourceId&&I(x)===I(l.address)));a.length&&d("revoking",a.length,"access grants"),m.length&&d("adding",m.length,"access grants");let p=[...a.map(l=>Y(()=>q(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"revokeAccess",args:[l.resourceId,l.address]}),{retries:3,onFailedAttempt:async y=>{let x=y.attemptNumber*500;d(`failed to revoke access, retrying in ${x}ms...`),await G(x)}})),...m.map(l=>Y(()=>q(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"grantAccess",args:[l.resourceId,l.address]}),{retries:3,onFailedAttempt:async y=>{let x=y.attemptNumber*500;d(`failed to grant access, retrying in ${x}ms...`),await G(x)}}))],w=r.filter(l=>t.some(y=>y.systemId===l.systemId&&I(y.address)===I(l.address)));w.length&&d("existing systems",w.map(S).join(", "));let u=w.map(l=>l.systemId),f=r.filter(l=>!u.includes(l.systemId));if(!f.length)return[];let g=f.filter(l=>t.some(y=>y.systemId===l.systemId&&I(y.address)!==I(l.address)));g.length&&d("upgrading systems",g.map(S).join(", "));let h=f.filter(l=>!t.some(y=>y.systemId===l.systemId));h.length&&d("registering new systems",h.map(S).join(", "));let b=f.map(l=>Y(()=>q(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"registerSystem",args:[l.systemId,l.address,l.allowAll]}),{retries:3,onFailedAttempt:async y=>{let x=y.attemptNumber*500;d(`failed to register system ${S(l)}, retrying in ${x}ms...`),await G(x)}}));return await Promise.all([...p,...b])}import{waitForTransactionReceipt as Ve}from"viem/actions";import{getAddress as qt,parseAbi as Gt}from"viem";import{getBlockNumber as Yt,getLogs as Zt}from"viem/actions";var Me=new Map;async function We(e,o){let r=qt(o),t=Me.get(r);if(t!=null)return t;d("looking up world deploy for",r);let n=await Yt(e),s=await Zt(e,{strict:!0,address:r,events:Gt(U),fromBlock:"earliest",toBlock:n});return t={...V(s),stateBlock:n},Me.set(r,t),d("found world deploy for",r,"at block",t.deployBlock),t}import{hexToResource as Qt,writeContract as je}from"@latticexyz/common";import Fe from"p-retry";import{wait as Re}from"@latticexyz/common/utils";async function Ee({client:e,worldDeploy:o,functions:r}){let t=await L({client:e,worldDeploy:o}),n=Object.fromEntries(t.map(i=>[i.selector,i])),s=r.filter(i=>n[i.selector]),c=r.filter(i=>!s.includes(i));if(s.length){d("functions already registered:",s.map(m=>m.signature).join(", "));let i=s.filter(m=>m.systemId!==n[m.selector]?.systemId);i.length&&console.warn("found",i.length,"functions already registered but pointing at a different system ID:",i.map(m=>m.signature).join(", "))}return c.length?(d("registering functions:",c.map(i=>i.signature).join(", ")),Promise.all(c.map(i=>{let{namespace:m}=Qt(i.systemId);return m===""?Fe(()=>je(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"registerRootFunctionSelector",args:[i.systemId,i.systemFunctionSignature,i.systemFunctionSelector]}),{retries:3,onFailedAttempt:async a=>{let p=a.attemptNumber*500;d(`failed to register function ${i.signature}, retrying in ${p}ms...`),await Re(p)}}):Fe(()=>je(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"registerFunctionSelector",args:[i.systemId,i.systemFunctionSignature]}),{retries:3,onFailedAttempt:async a=>{let p=a.attemptNumber*500;d(`failed to register function ${i.signature}, retrying in ${p}ms...`),await Re(p)}})}))):[]}import{BaseError as Xt}from"viem";import{writeContract as $e}from"@latticexyz/common";import{isDefined as er,wait as or}from"@latticexyz/common/utils";import tr from"p-retry";async function Ne({client:e,worldDeploy:o,modules:r}){return r.length?(d("installing modules:",r.map(t=>t.name).join(", ")),(await Promise.all(r.map(t=>tr(async()=>{try{return t.installAsRoot?await $e(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"installRootModule",args:[t.address,t.installData]}):await $e(e,{chain:e.chain??null,address:o.address,abi:v,functionName:"installModule",args:[t.address,t.installData]})}catch(n){if(n instanceof Xt&&n.message.includes("Module_AlreadyInstalled")){d(`module ${t.name} already installed`);return}throw n}},{retries:3,onFailedAttempt:async n=>{let s=n.attemptNumber*500;d(`failed to install module ${t.name}, retrying in ${s}ms...`),await or(s)}})))).filter(er)):[]}import{getAddress as Be}from"viem";import{hexToResource as He,resourceToHex as rr}from"@latticexyz/common";async function Ue({client:e,worldDeploy:o,resourceIds:r}){let t=Array.from(new Set(r.map(a=>He(a).namespace))),n=await _({client:e,worldDeploy:o}),s=Array.from(new Set(n.map(a=>He(a).namespace))),c=t.filter(a=>s.includes(a)),m=(await Promise.all(c.map(async a=>{let{owner:p}=await A({client:e,worldDeploy:o,table:T.world_NamespaceOwner,key:{namespaceId:rr({type:"namespace",namespace:a,name:""})}});return[a,p]}))).filter(([,a])=>Be(a)!==Be(e.account.address)).map(([a])=>a);if(m.length)throw new Error(`You are attempting to deploy to namespaces you do not own: ${m.join(", ")}`)}import{uniqueBy as _e}from"@latticexyz/common/utils";async function Le({client:e,config:o,worldAddress:r}){await me(e);let t=r?await We(e,r):await Ce(e);if(!fe.includes(t.storeVersion))throw new Error(`Unsupported Store version: ${t.storeVersion}`);if(!ue.includes(t.worldVersion))throw new Error(`Unsupported World version: ${t.worldVersion}`);let n=Object.values(o.tables),s=Object.values(o.systems);await Ue({client:e,worldDeploy:t,resourceIds:[...n.map(u=>u.tableId),...s.map(u=>u.systemId)]});let c=(await Promise.all([..._e(s,u=>u.address).map(u=>j({client:e,bytecode:u.bytecode,label:`${S(u)} system`})),..._e(o.modules,u=>u.address).map(u=>j({client:e,bytecode:u.bytecode,label:`${u.name} module`}))])).flat();if(c.length){d("waiting for contracts");for(let u of c)await Ve(e,{hash:u})}let i=await Ie({client:e,worldDeploy:t,tables:n}),m=await Pe({client:e,worldDeploy:t,systems:s}),a=await Ee({client:e,worldDeploy:t,functions:s.flatMap(u=>u.functions)}),p=await Ne({client:e,worldDeploy:t,modules:o.modules}),w=[...i,...m,...a,...p];d("waiting for all transactions to confirm");for(let u of w)await Ve(e,{hash:u});return d("deploy complete"),t}import{createWalletClient as Cr,http as Tr}from"viem";import{privateKeyToAccount as kr}from"viem/accounts";import{loadConfig as Dr}from"@latticexyz/config/node";import{forge as Ar,getOutDirectory as Ir,getRemappings as Or,getRpcUrl as Pr,getSrcDirectory as Mr}from"@latticexyz/common/foundry";import R from"chalk";import{execa as Wr}from"execa";import{MUDError as jr}from"@latticexyz/common/errors";import{resolveWorldConfig as cr}from"@latticexyz/world";import{resourceToHex as Q,hexToResource as lr}from"@latticexyz/common";import{resolveWithContext as dr}from"@latticexyz/config";import{encodeField as mr}from"@latticexyz/protocol-parser";import{getFunctionSelector as Ge,getCreate2Address as Ye,getAddress as pr,hexToBytes as fr,bytesToHex as ur,getFunctionSignature as Ze}from"viem";import nr from"glob";import{basename as sr}from"path";function F(e){return nr.sync(`${e}/**/*.sol`).map(o=>({path:o,basename:sr(o,".sol")}))}import Ke from"@latticexyz/world-modules/out/KeysWithValueModule.sol/KeysWithValueModule.json"assert{type:"json"};import ze from"@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json"assert{type:"json"};import Je from"@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json"assert{type:"json"};var qe=[{name:"KeysWithValueModule",abi:Ke.abi,bytecode:Ke.bytecode},{name:"KeysInTableModule",abi:ze.abi,bytecode:ze.bytecode},{name:"UniqueEntityModule",abi:Je.abi,bytecode:Je.bytecode}];import{readFileSync as ir}from"fs";import ar from"path";import{MUDError as Z}from"@latticexyz/common/errors";function z(e,o){let r,t=ar.join(o,e+".sol",e+".json");try{r=JSON.parse(ir(t,"utf8"))}catch{throw new Z(`Error reading file at ${t}`)}let n=r?.bytecode?.object;if(!n)throw new Z(`No bytecode found in ${t}`);let s=r?.abi;if(!s)throw new Z(`No ABI found in ${t}`);return{abi:s,bytecode:n}}function Qe({config:e,forgeSourceDir:o,forgeOutDir:r}){let t=B(e),n=F(o).map(({basename:f})=>f),s=cr(e,n),i=z("System",r).abi.filter(f=>f.type==="function").map(Ze),m=Object.entries(s.systems).map(([f,g])=>{let h=e.namespace,b=g.name,l=Q({type:"system",namespace:h,name:b}),y=z(f,r),x=y.abi.filter(k=>k.type==="function").map(Ze).filter(k=>!i.includes(k)).map(k=>{let re=h===""?k:`${h}_${b}_${k}`;return{signature:re,selector:Ge(re),systemId:l,systemFunctionSignature:k,systemFunctionSelector:Ge(k)}});return{namespace:h,name:b,systemId:l,allowAll:g.openAccess,allowedAddresses:g.accessListAddresses,allowedSystemIds:g.accessListSystems.map(k=>Q({type:"system",namespace:h,name:s.systems[k].name})),address:Ye({from:C,bytecode:y.bytecode,salt:D}),bytecode:y.bytecode,abi:y.abi,functions:x}}),a=m.map(({allowedAddresses:f,allowedSystemIds:g,...h})=>{let b=g.map(l=>{let y=m.find(x=>x.systemId===l);if(!y)throw new Error(`System ${S(h)} wanted access to ${S(lr(l))}, but it wasn't found in the config.`);return y.address});return{...h,allowedAddresses:Array.from(new Set([...f,...b].map(l=>pr(l))))}}),p={tableIds:Object.fromEntries(Object.entries(e.tables).map(([f,g])=>[f,fr(Q({type:g.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:g.name}))]))},w=qe.map(f=>({name:f.name,bytecode:typeof f.bytecode=="string"?f.bytecode:f.bytecode.object,abi:f.abi})),u=e.modules.map(f=>{let g=w.find(b=>b.name===f.name)??z(f.name,r),h=f.args.map(b=>dr(b,p)).map(b=>{let l=b.value instanceof Uint8Array?ur(b.value):b.value;return mr(b.type,l)});if(h.length>1)throw new Error(`${f.name} module should only have 0-1 args, but had ${h.length} args.`);return{name:f.name,installAsRoot:f.root,installData:h.length===0?"0x":h[0],address:Ye({from:C,bytecode:g.bytecode,salt:D}),bytecode:g.bytecode,abi:g.abi}});return{tables:t,systems:a,modules:u}}import{getChainId as Fr}from"viem/actions";import{existsSync as yr}from"fs";import gr from"path";import br from"chalk";import{getScriptDirectory as hr,forge as wr}from"@latticexyz/common/foundry";async function Xe(e,o,r,t){let n=gr.join(await hr(),e+".s.sol");yr(n)?(console.log(br.blue(`Executing post deploy script at ${n}`)),await wr(["script",e,"--sig","run(address)",o,"--broadcast","--rpc-url",r,"-vvv"],{profile:t})):console.log(`No script at ${n}, skipping post deploy hook`)}import{tablegen as Rr}from"@latticexyz/store/codegen";var O={configPath:{type:"string",desc:"Path to the 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"},worldAddress:{type:"string",desc:"Deploy to an existing World at the given address"},srcDir:{type:"string",desc:"Source directory. Defaults to foundry src directory."},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."}};async function E(e){let o=e.profile??process.env.FOUNDRY_PROFILE,r=await Dr(e.configPath);e.printConfig&&console.log(R.green(`
5
+ - `});console.log(N.redBright(o.message))}else e instanceof Uo?(console.log(N.red(e.message)),console.log(""),console.log(N.blue("To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/"))):e instanceof Vo?console.log(N.red(e)):console.log(e)}import G from"node:path";import{existsSync as kr,mkdirSync as Ar,readFileSync as Ir,writeFileSync as oe}from"node:fs";import{getAddress as _e}from"viem";import{getBytecode as Ko,sendRawTransaction as zo,sendTransaction as Jo,waitForTransactionReceipt as pe}from"viem/actions";var M={gasPrice:1e11,gasLimit:1e5,signerAddress:"3fab184622dc19b6109349b94811493bf2a45362",transaction:"f8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222",address:"4e59b44847b379578588920ca78fbf26c0b4956c"};import Lo from"debug";var me=Lo("mud:cli");var d=me.extend("deploy");var v=`0x${M.address}`;async function fe(e){if(await Ko(e,{address:v})){d("found create2 deployer at",v);return}d("sending gas for create2 deployer to signer at",M.signerAddress);let t=await Jo(e,{chain:e.chain??null,to:`0x${M.signerAddress}`,value:BigInt(M.gasLimit)*BigInt(M.gasPrice)}),r=await pe(e,{hash:t});if(r.status!=="success")throw console.error("failed to send gas to deployer signer",r),new Error("failed to send gas to deployer signer");d("deploying create2 deployer at",v);let n=await zo(e,{serializedTransaction:`0x${M.transaction}`}),s=await pe(e,{hash:n});if(s.contractAddress!==v)throw console.error("unexpected contract address for deployer",s),new Error("unexpected contract address for deployer")}import{waitForTransactionReceipt as bt}from"viem/actions";import lt from"@latticexyz/world/out/CoreModule.sol/CoreModule.json"assert{type:"json"};import dt from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.json"assert{type:"json"};import{parseAbi as mt,getCreate2Address as he,encodeDeployData as we}from"viem";import{padHex as Go}from"viem";import Yo from"@latticexyz/store/mud.config.js";import Zo from"@latticexyz/world/mud.config.js";import Qo from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import Xo from"@latticexyz/world-modules/out/IModule.sol/IModule.abi.json"assert{type:"json"};import{resourceToHex as qo}from"@latticexyz/common";import{resolveUserTypes as ue}from"@latticexyz/store";function B(e){let o={...e.userTypes,...Object.fromEntries(Object.entries(e.enums).map(([t])=>[t,{internalType:"uint8"}]))};return Object.fromEntries(Object.entries(e.tables).map(([t,r])=>[`${e.namespace}_${t}`,{namespace:e.namespace,name:r.name,tableId:qo({type:r.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:r.name}),keySchema:ue(r.keySchema,o),valueSchema:ue(r.valueSchema,o)}]))}import{helloStoreEvent as et}from"@latticexyz/store";import{helloWorldEvent as ot}from"@latticexyz/world";var k=Go("0x",{size:32}),j=B(Yo),D=B(Zo),U=[et,ot],C=[...Qo,...Xo],ye=["1.0.0-unaudited"],ge=["1.0.0-unaudited"];import{waitForTransactionReceipt as ct}from"viem/actions";import{concatHex as tt,getCreate2Address as rt}from"viem";import{getBytecode as nt}from"viem/actions";import{sendTransaction as st}from"@latticexyz/common";import at from"p-retry";import{wait as it}from"@latticexyz/common/utils";async function be({client:e,bytecode:o,label:t="contract"}){let r=rt({from:v,salt:k,bytecode:o});return await nt(e,{address:r,blockTag:"pending"})?(d("found",t,"at",r),[]):(d("deploying",t,"at",r),[await at(()=>st(e,{chain:e.chain??null,to:v,data:tt([k,o])}),{retries:3,onFailedAttempt:async s=>{let l=s.attemptNumber*500;d(`failed to deploy ${t}, retrying in ${l}ms...`),await it(l)}})])}async function I({client:e,contracts:o}){let t=(await Promise.all(o.map(r=>be({client:e,...r})))).flat();if(t.length){d("waiting for contracts");for(let r of t)await ct(e,{hash:r})}return t}var V=we({bytecode:lt.bytecode.object,abi:[]}),pt=he({from:v,bytecode:V,salt:k}),_=we({bytecode:dt.bytecode.object,abi:mt(["constructor(address)"]),args:[pt]}),xe=he({from:v,bytecode:_,salt:k});async function Ce(e){return await I({client:e,contracts:[{bytecode:V,label:"core module"},{bytecode:_,label:"world factory"}]})}import ht from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{writeContract as wt}from"@latticexyz/common";import{AbiEventSignatureNotFoundError as ft,decodeEventLog as ut,hexToString as Se,parseAbi as yt,trim as ve}from"viem";import{isDefined as gt}from"@latticexyz/common/utils";function L(e){let o=e.map(l=>{try{return{...l,...ut({strict:!0,abi:yt(U),topics:l.topics,data:l.data})}}catch(a){if(a instanceof ft)return;throw a}}).filter(gt),{address:t,deployBlock:r,worldVersion:n,storeVersion:s}=o.reduce((l,a)=>({...l,address:a.address,deployBlock:a.blockNumber,...a.eventName==="HelloWorld"?{worldVersion:Se(ve(a.args.worldVersion,{dir:"right"}))}:null,...a.eventName==="HelloStore"?{storeVersion:Se(ve(a.args.storeVersion,{dir:"right"}))}:null}),{});if(t==null)throw new Error("could not find world address");if(r==null)throw new Error("could not find world deploy block number");if(n==null)throw new Error("could not find world version");if(s==null)throw new Error("could not find store version");return{address:t,deployBlock:r,worldVersion:n,storeVersion:s}}async function De(e){await Ce(e),d("deploying world");let o=await wt(e,{chain:e.chain??null,address:xe,abi:ht,functionName:"deployWorld"});d("waiting for world deploy");let t=await bt(e,{hash:o});if(t.status!=="success")throw console.error("world deploy failed",t),new Error("world deploy failed");let r=L(t.logs.map(n=>n));return d("deployed world to",r.address,"at block",r.deployBlock),{...r,stateBlock:r.deployBlock}}import{writeContract as kt}from"@latticexyz/common";import{valueSchemaToFieldLayoutHex as At,keySchemaToHex as It,valueSchemaToHex as Ot}from"@latticexyz/protocol-parser";function x({namespace:e,name:o}){return`${e}:${o}`}import{parseAbiItem as xt,decodeAbiParameters as Te,parseAbiParameters as ke}from"viem";import{hexToResource as Ct}from"@latticexyz/common";import{storeSetRecordEvent as St}from"@latticexyz/store";import{getLogs as vt}from"viem/actions";import{decodeKey as Dt,decodeValueArgs as Tt,hexToSchema as Ae}from"@latticexyz/protocol-parser";async function Ie({client:e,worldDeploy:o}){d("looking up tables for",o.address);let r=(await vt(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:xt(St),args:{tableId:j.store_Tables.tableId}})).map(n=>{let{tableId:s}=Dt(j.store_Tables.keySchema,n.args.keyTuple),{namespace:l,name:a}=Ct(s),m=Tt(j.store_Tables.valueSchema,n.args),i=Ae(m.keySchema),p=Ae(m.valueSchema),u=Te(ke("string[]"),m.abiEncodedKeyNames)[0],S=Te(ke("string[]"),m.abiEncodedFieldNames)[0],f=[...p.staticFields,...p.dynamicFields],g=Object.fromEntries(i.staticFields.map((b,c)=>[u[c],b])),h=Object.fromEntries(f.map((b,c)=>[S[c],b]));return{namespace:l,name:a,tableId:s,keySchema:g,valueSchema:h}});return d("found",r.length,"tables for",o.address),r}import Pt from"p-retry";import{wait as Mt}from"@latticexyz/common/utils";async function Oe({client:e,worldDeploy:o,tables:t}){let n=(await Ie({client:e,worldDeploy:o})).map(a=>a.tableId),s=t.filter(a=>n.includes(a.tableId));s.length&&d("existing tables",s.map(x).join(", "));let l=t.filter(a=>!n.includes(a.tableId));return l.length?(d("registering tables",l.map(x).join(", ")),await Promise.all(l.map(a=>Pt(()=>kt(e,{chain:e.chain??null,address:o.address,abi:C,functionName:"registerTable",args:[a.tableId,At(a.valueSchema),It(a.keySchema),Ot(a.valueSchema),Object.keys(a.keySchema),Object.keys(a.valueSchema)]}),{retries:3,onFailedAttempt:async m=>{let i=m.attemptNumber*500;d(`failed to register table ${x(a)}, retrying in ${i}ms...`),await Mt(i)}})))):[]}import{getAddress as A}from"viem";import{writeContract as Y}from"@latticexyz/common";import{parseAbiItem as Wt}from"viem";import{getLogs as jt}from"viem/actions";import{storeSpliceStaticDataEvent as Ft}from"@latticexyz/store";async function K({client:e,worldDeploy:o}){d("looking up resource IDs for",o.address);let r=(await jt(e,{strict:!0,address:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock,event:Wt(Ft),args:{tableId:j.store_ResourceIds.tableId}})).map(n=>n.args.keyTuple[0]);return d("found",r.length,"resource IDs for",o.address),r}import{hexToResource as Gt}from"@latticexyz/common";import{decodeValueArgs as Rt,encodeKey as $t}from"@latticexyz/protocol-parser";import{readContract as Et}from"viem/actions";async function O({client:e,worldDeploy:o,table:t,key:r}){let[n,s,l]=await Et(e,{blockNumber:o.stateBlock,address:o.address,abi:C,functionName:"getRecord",args:[t.tableId,$t(t.keySchema,r)]});return Rt(t.valueSchema,{staticData:n,encodedLengths:s,dynamicData:l})}import{getFunctionSelector as Nt,parseAbiItem as Bt}from"viem";import{storeSetRecordEvent as Ht}from"@latticexyz/store";import{getLogs as Ut}from"viem/actions";import{decodeValueArgs as Vt}from"@latticexyz/protocol-parser";import{hexToResource as _t}from"@latticexyz/common";async function z({client:e,worldDeploy:o}){d("looking up function signatures for",o.address);let r=(await Ut(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:Bt(Ht),args:{tableId:D.world_FunctionSignatures.tableId}})).map(s=>Vt(D.world_FunctionSignatures.valueSchema,s.args).functionSignature);return d("found",r.length,"function signatures for",o.address),await Promise.all(r.map(async s=>{let l=Nt(s),{systemId:a,systemFunctionSelector:m}=await O({client:e,worldDeploy:o,table:D.world_FunctionSelectors,key:{functionSelector:l}}),{namespace:i,name:p}=_t(a),u=i===""?s:s.replace(`${i}_${p}_`,"");return{signature:s,selector:l,systemId:a,systemFunctionSignature:u,systemFunctionSelector:m}}))}import{parseAbiItem as Lt,getAddress as Kt}from"viem";import{storeSpliceStaticDataEvent as zt}from"@latticexyz/store";import{getLogs as Jt}from"viem/actions";import{decodeKey as qt}from"@latticexyz/protocol-parser";async function J({client:e,worldDeploy:o}){d("looking up resource access for",o.address);let r=(await Jt(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:Lt(zt),args:{tableId:D.world_ResourceAccess.tableId}})).map(s=>qt(D.world_ResourceAccess.keySchema,s.args.keyTuple)),n=(await Promise.all(r.map(async s=>[s,await O({client:e,worldDeploy:o,table:D.world_ResourceAccess,key:s})]))).filter(([,s])=>s.access).map(([s])=>({resourceId:s.resourceId,address:Kt(s.caller)}));return d("found",n.length,"resource<>address access pairs"),n}async function Pe({client:e,worldDeploy:o}){let[t,r,n]=await Promise.all([K({client:e,worldDeploy:o}),z({client:e,worldDeploy:o}),J({client:e,worldDeploy:o})]),s=t.map(Gt).filter(l=>l.type==="system");return d("looking up systems",s.map(x).join(", ")),await Promise.all(s.map(async l=>{let{system:a,publicAccess:m}=await O({client:e,worldDeploy:o,table:D.world_Systems,key:{systemId:l.resourceId}}),i=r.filter(p=>p.systemId===l.resourceId);return{address:a,namespace:l.namespace,name:l.name,systemId:l.resourceId,allowAll:m,allowedAddresses:n.filter(({resourceId:p})=>p===l.resourceId).map(({address:p})=>p),functions:i}}))}import{uniqueBy as Yt,wait as Z}from"@latticexyz/common/utils";import Q from"p-retry";async function Me({client:e,worldDeploy:o,systems:t}){let[r,n]=await Promise.all([Pe({client:e,worldDeploy:o}),J({client:e,worldDeploy:o})]),s=t.map(c=>c.systemId),l=n.filter(({resourceId:c})=>s.includes(c)),a=t.flatMap(c=>c.allowedAddresses.map(y=>({resourceId:c.systemId,address:y}))),m=a.filter(c=>!l.some(({resourceId:y,address:w})=>y===c.resourceId&&A(w)===A(c.address))),i=l.filter(c=>!a.some(({resourceId:y,address:w})=>y===c.resourceId&&A(w)===A(c.address)));i.length&&d("revoking",i.length,"access grants"),m.length&&d("adding",m.length,"access grants");let p=[...i.map(c=>Q(()=>Y(e,{chain:e.chain??null,address:o.address,abi:C,functionName:"revokeAccess",args:[c.resourceId,c.address]}),{retries:3,onFailedAttempt:async y=>{let w=y.attemptNumber*500;d(`failed to revoke access, retrying in ${w}ms...`),await Z(w)}})),...m.map(c=>Q(()=>Y(e,{chain:e.chain??null,address:o.address,abi:C,functionName:"grantAccess",args:[c.resourceId,c.address]}),{retries:3,onFailedAttempt:async y=>{let w=y.attemptNumber*500;d(`failed to grant access, retrying in ${w}ms...`),await Z(w)}}))],u=t.filter(c=>r.some(y=>y.systemId===c.systemId&&A(y.address)===A(c.address)));u.length&&d("existing systems",u.map(x).join(", "));let S=u.map(c=>c.systemId),f=t.filter(c=>!S.includes(c.systemId));if(!f.length)return[];let g=f.filter(c=>r.some(y=>y.systemId===c.systemId&&A(y.address)!==A(c.address)));g.length&&d("upgrading systems",g.map(x).join(", "));let h=f.filter(c=>!r.some(y=>y.systemId===c.systemId));h.length&&d("registering new systems",h.map(x).join(", ")),await I({client:e,contracts:Yt(f,c=>A(c.address)).map(c=>({bytecode:c.bytecode,label:`${x(c)} system`}))});let b=f.map(c=>Q(()=>Y(e,{chain:e.chain??null,address:o.address,abi:C,functionName:"registerSystem",args:[c.systemId,c.address,c.allowAll]}),{retries:3,onFailedAttempt:async y=>{let w=y.attemptNumber*500;d(`failed to register system ${x(c)}, retrying in ${w}ms...`),await Z(w)}}));return await Promise.all([...p,...b])}import{waitForTransactionReceipt as lr}from"viem/actions";import{getAddress as Zt,parseAbi as Qt}from"viem";import{getBlockNumber as Xt,getLogs as er}from"viem/actions";var We=new Map;async function je(e,o){let t=Zt(o),r=We.get(t);if(r!=null)return r;d("looking up world deploy for",t);let n=await Xt(e),s=await er(e,{strict:!0,address:t,events:Qt(U),fromBlock:"earliest",toBlock:n});return r={...L(s),stateBlock:n},We.set(t,r),d("found world deploy for",t,"at block",r.deployBlock),r}import{hexToResource as or,writeContract as Fe}from"@latticexyz/common";import Re from"p-retry";import{wait as $e}from"@latticexyz/common/utils";async function Ee({client:e,worldDeploy:o,functions:t}){let r=await z({client:e,worldDeploy:o}),n=Object.fromEntries(r.map(a=>[a.selector,a])),s=t.filter(a=>n[a.selector]),l=t.filter(a=>!s.includes(a));if(s.length){d("functions already registered:",s.map(m=>m.signature).join(", "));let a=s.filter(m=>m.systemId!==n[m.selector]?.systemId);a.length&&console.warn("found",a.length,"functions already registered but pointing at a different system ID:",a.map(m=>m.signature).join(", "))}return l.length?(d("registering functions:",l.map(a=>a.signature).join(", ")),Promise.all(l.map(a=>{let{namespace:m}=or(a.systemId);return m===""?Re(()=>Fe(e,{chain:e.chain??null,address:o.address,abi:C,functionName:"registerRootFunctionSelector",args:[a.systemId,a.systemFunctionSignature,a.systemFunctionSelector]}),{retries:3,onFailedAttempt:async i=>{let p=i.attemptNumber*500;d(`failed to register function ${a.signature}, retrying in ${p}ms...`),await $e(p)}}):Re(()=>Fe(e,{chain:e.chain??null,address:o.address,abi:C,functionName:"registerFunctionSelector",args:[a.systemId,a.systemFunctionSignature]}),{retries:3,onFailedAttempt:async i=>{let p=i.attemptNumber*500;d(`failed to register function ${a.signature}, retrying in ${p}ms...`),await $e(p)}})}))):[]}import{BaseError as tr,getAddress as rr}from"viem";import{writeContract as Ne}from"@latticexyz/common";import{isDefined as nr,uniqueBy as sr,wait as ar}from"@latticexyz/common/utils";import ir from"p-retry";async function Be({client:e,worldDeploy:o,modules:t}){return t.length?(await I({client:e,contracts:sr(t,r=>rr(r.address)).map(r=>({bytecode:r.bytecode,label:`${r.name} module`}))}),d("installing modules:",t.map(r=>r.name).join(", ")),(await Promise.all(t.map(r=>ir(async()=>{try{return r.installAsRoot?await Ne(e,{chain:e.chain??null,address:o.address,abi:C,functionName:"installRootModule",args:[r.address,r.installData]}):await Ne(e,{chain:e.chain??null,address:o.address,abi:C,functionName:"installModule",args:[r.address,r.installData]})}catch(n){if(n instanceof tr&&n.message.includes("Module_AlreadyInstalled")){d(`module ${r.name} already installed`);return}throw n}},{retries:3,onFailedAttempt:async n=>{let s=n.attemptNumber*500;d(`failed to install module ${r.name}, retrying in ${s}ms...`),await ar(s)}})))).filter(nr)):[]}import{getAddress as He}from"viem";import{hexToResource as Ue,resourceToHex as cr}from"@latticexyz/common";async function Ve({client:e,worldDeploy:o,resourceIds:t}){let r=Array.from(new Set(t.map(i=>Ue(i).namespace))),n=await K({client:e,worldDeploy:o}),s=Array.from(new Set(n.map(i=>Ue(i).namespace))),l=r.filter(i=>s.includes(i)),m=(await Promise.all(l.map(async i=>{let{owner:p}=await O({client:e,worldDeploy:o,table:D.world_NamespaceOwner,key:{namespaceId:cr({type:"namespace",namespace:i,name:""})}});return[i,p]}))).filter(([,i])=>He(i)!==He(e.account.address)).map(([i])=>i);if(m.length)throw new Error(`You are attempting to deploy to namespaces you do not own: ${m.join(", ")}`)}import{uniqueBy as Le}from"@latticexyz/common/utils";async function Ke({client:e,config:o,worldAddress:t}){let r=Object.values(o.tables),n=Object.values(o.systems);await fe(e),await I({client:e,contracts:[{bytecode:V,label:"core module"},{bytecode:_,label:"world factory"},...Le(n,u=>_e(u.address)).map(u=>({bytecode:u.bytecode,label:`${x(u)} system`})),...Le(o.modules,u=>_e(u.address)).map(u=>({bytecode:u.bytecode,label:`${u.name} module`}))]});let s=t?await je(e,t):await De(e);if(!ye.includes(s.storeVersion))throw new Error(`Unsupported Store version: ${s.storeVersion}`);if(!ge.includes(s.worldVersion))throw new Error(`Unsupported World version: ${s.worldVersion}`);await Ve({client:e,worldDeploy:s,resourceIds:[...r.map(u=>u.tableId),...n.map(u=>u.systemId)]});let l=await Oe({client:e,worldDeploy:s,tables:r}),a=await Me({client:e,worldDeploy:s,systems:n}),m=await Ee({client:e,worldDeploy:s,functions:n.flatMap(u=>u.functions)}),i=await Be({client:e,worldDeploy:s,modules:o.modules}),p=[...l,...a,...m,...i];d("waiting for all transactions to confirm");for(let u of p)await lr(e,{hash:u});return d("deploy complete"),s}import{createWalletClient as Or,http as Pr}from"viem";import{privateKeyToAccount as Mr}from"viem/accounts";import{loadConfig as Wr}from"@latticexyz/config/node";import{forge as jr,getOutDirectory as Fr,getRemappings as Rr,getRpcUrl as $r,getSrcDirectory as Er}from"@latticexyz/common/foundry";import R from"chalk";import{execa as Nr}from"execa";import{MUDError as Br}from"@latticexyz/common/errors";import{resolveWorldConfig as ur}from"@latticexyz/world";import{resourceToHex as ee,hexToResource as yr}from"@latticexyz/common";import{resolveWithContext as gr}from"@latticexyz/config";import{encodeField as br}from"@latticexyz/protocol-parser";import{getFunctionSelector as Ye,getCreate2Address as Ze,getAddress as hr,hexToBytes as wr,bytesToHex as xr,getFunctionSignature as Qe}from"viem";import dr from"glob";import{basename as mr}from"path";function F(e){return dr.sync(`${e}/**/*.sol`).map(o=>({path:o,basename:mr(o,".sol")}))}import ze from"@latticexyz/world-modules/out/KeysWithValueModule.sol/KeysWithValueModule.json"assert{type:"json"};import Je from"@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json"assert{type:"json"};import qe from"@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json"assert{type:"json"};var Ge=[{name:"KeysWithValueModule",abi:ze.abi,bytecode:ze.bytecode},{name:"KeysInTableModule",abi:Je.abi,bytecode:Je.bytecode},{name:"UniqueEntityModule",abi:qe.abi,bytecode:qe.bytecode}];import{readFileSync as pr}from"fs";import fr from"path";import{MUDError as X}from"@latticexyz/common/errors";function q(e,o){let t,r=fr.join(o,e+".sol",e+".json");try{t=JSON.parse(pr(r,"utf8"))}catch{throw new X(`Error reading file at ${r}`)}let n=t?.bytecode?.object;if(!n)throw new X(`No bytecode found in ${r}`);let s=t?.abi;if(!s)throw new X(`No ABI found in ${r}`);return{abi:s,bytecode:n}}function Xe({config:e,forgeSourceDir:o,forgeOutDir:t}){let r=B(e),n=F(o).map(({basename:f})=>f),s=ur(e,n),a=q("System",t).abi.filter(f=>f.type==="function").map(Qe),m=Object.entries(s.systems).map(([f,g])=>{let h=e.namespace,b=g.name,c=ee({type:"system",namespace:h,name:b}),y=q(f,t),w=y.abi.filter(T=>T.type==="function").map(Qe).filter(T=>!a.includes(T)).map(T=>{let se=h===""?T:`${h}_${b}_${T}`;return{signature:se,selector:Ye(se),systemId:c,systemFunctionSignature:T,systemFunctionSelector:Ye(T)}});return{namespace:h,name:b,systemId:c,allowAll:g.openAccess,allowedAddresses:g.accessListAddresses,allowedSystemIds:g.accessListSystems.map(T=>ee({type:"system",namespace:h,name:s.systems[T].name})),address:Ze({from:v,bytecode:y.bytecode,salt:k}),bytecode:y.bytecode,abi:y.abi,functions:w}}),i=m.map(({allowedAddresses:f,allowedSystemIds:g,...h})=>{let b=g.map(c=>{let y=m.find(w=>w.systemId===c);if(!y)throw new Error(`System ${x(h)} wanted access to ${x(yr(c))}, but it wasn't found in the config.`);return y.address});return{...h,allowedAddresses:Array.from(new Set([...f,...b].map(c=>hr(c))))}}),p={tableIds:Object.fromEntries(Object.entries(e.tables).map(([f,g])=>[f,wr(ee({type:g.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:g.name}))]))},u=Ge.map(f=>({name:f.name,bytecode:typeof f.bytecode=="string"?f.bytecode:f.bytecode.object,abi:f.abi})),S=e.modules.map(f=>{let g=u.find(b=>b.name===f.name)??q(f.name,t),h=f.args.map(b=>gr(b,p)).map(b=>{let c=b.value instanceof Uint8Array?xr(b.value):b.value;return br(b.type,c)});if(h.length>1)throw new Error(`${f.name} module should only have 0-1 args, but had ${h.length} args.`);return{name:f.name,installAsRoot:f.root,installData:h.length===0?"0x":h[0],address:Ze({from:v,bytecode:g.bytecode,salt:k}),bytecode:g.bytecode,abi:g.abi}});return{tables:r,systems:i,modules:S}}import{getChainId as Hr}from"viem/actions";import{existsSync as Cr}from"fs";import Sr from"path";import vr from"chalk";import{getScriptDirectory as Dr,forge as Tr}from"@latticexyz/common/foundry";async function eo(e,o,t,r){let n=Sr.join(await Dr(),e+".s.sol");Cr(n)?(console.log(vr.blue(`Executing post deploy script at ${n}`)),await Tr(["script",e,"--sig","run(address)",o,"--broadcast","--rpc-url",t,"-vvv"],{profile:r})):console.log(`No script at ${n}, skipping post deploy hook`)}import{tablegen as Ur}from"@latticexyz/store/codegen";var P={configPath:{type:"string",desc:"Path to the 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"},worldAddress:{type:"string",desc:"Deploy to an existing World at the given address"},srcDir:{type:"string",desc:"Source directory. Defaults to foundry src directory."},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."}};async function $(e){let o=e.profile??process.env.FOUNDRY_PROFILE,t=await Wr(e.configPath);e.printConfig&&console.log(R.green(`
6
6
  Resolved config:
7
- `),JSON.stringify(r,null,2));let t=e.srcDir??await Mr(o),n=await Ir(o),s=await Or(),c=e.rpc??await Pr(o);if(console.log(R.bgBlue(R.whiteBright(`
8
- Deploying MUD contracts${o?" with profile "+o:""} to RPC ${c}
9
- `))),!e.skipBuild){let f=J.join(t,r.codegenDirectory);await Rr(r,f,s),await Ar(["build","--skip","test","script"],{profile:o}),await Wr("mud",["abi-ts"],{stdio:"inherit"})}let i=process.env.PRIVATE_KEY;if(!i)throw new jr(`Missing PRIVATE_KEY environment variable.
7
+ `),JSON.stringify(t,null,2));let r=e.srcDir??await Er(o),n=await Fr(o),s=await Rr(),l=e.rpc??await $r(o);if(console.log(R.bgBlue(R.whiteBright(`
8
+ Deploying MUD contracts${o?" with profile "+o:""} to RPC ${l}
9
+ `))),!e.skipBuild){let f=G.join(r,t.codegenDirectory);await Ur(t,f,s),await jr(["build"],{profile:o}),await Nr("mud",["abi-ts"],{stdio:"inherit"})}let a=process.env.PRIVATE_KEY;if(!a)throw new Br(`Missing PRIVATE_KEY environment variable.
10
10
  Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
11
- in your contracts directory to use the default anvil private key.`);let m=Qe({config:r,forgeSourceDir:t,forgeOutDir:n}),a=Cr({transport:Tr(c),account:kr(i)});console.log("Deploying from",a.account.address);let p=Date.now(),w=await Le({worldAddress:e.worldAddress,client:a,config:m});(e.worldAddress==null||e.alwaysRunPostDeploy)&&await Xe(r.postDeployScript,w.address,c,o),console.log(R.green("Deployment completed in",(Date.now()-p)/1e3,"seconds"));let u={worldAddress:w.address,blockNumber:Number(w.deployBlock)};if(e.saveDeployment){let f=await Fr(a),g=J.join(r.deploysDirectory,f.toString());Sr(g,{recursive:!0}),X(J.join(g,"latest.json"),JSON.stringify(u,null,2)),X(J.join(g,Date.now()+".json"),JSON.stringify(u,null,2));let h=[1337,31337],b=xr(r.worldsFile)?JSON.parse(vr(r.worldsFile,"utf-8")):{};b[f]={address:u.worldAddress,blockNumber:h.includes(f)?void 0:u.blockNumber},X(r.worldsFile,JSON.stringify(b,null,2)),console.log(R.bgGreen(R.whiteBright(`
12
- Deployment result (written to ${r.worldsFile} and ${g}):
13
- `)))}return console.log(u),w}var Er={command:"deploy",describe:"Deploy MUD contracts",builder(e){return e.options(O)},async handler(e){try{await E(e)}catch(o){M(o),process.exit(1)}process.exit(0)}},eo=Er;import{loadConfig as $r}from"@latticexyz/config/node";import{worldgen as Nr}from"@latticexyz/world/node";import{getSrcDirectory as Br}from"@latticexyz/common/foundry";import oo from"path";import{rmSync as Hr}from"fs";var Ur={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 config file"},clean:{type:"boolean",desc:"Clear the worldgen directory before generating new interfaces (defaults to true)",default:!0}})},async handler(e){await Vr(e),process.exit(0)}};async function Vr(e){let o=e.srcDir??await Br(),r=F(o),t=e.config??await $r(e.configPath),n=oo.join(o,t.codegenDirectory);e.clean&&Hr(oo.join(n,t.worldgenDirectory),{recursive:!0,force:!0}),await Nr(t,r,n)}var to=Ur;import H from"chalk";import{readFileSync as Jr,writeFileSync as qr}from"fs";import oe from"path";import{MUDError as $}from"@latticexyz/common/errors";var ro={name:"@latticexyz/cli",version:"2.0.0-next.11",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"},types:"src/index.ts",bin:{mud:"./dist/mud.js"},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":"rimraf dist","clean:test-tables":"rimraf src/codegen",dev:"tsup --watch",lint:"eslint . --ext .ts",prepare:"mkdir -p ./dist && touch ./dist/mud.js",test:"tsc --noEmit && forge test","test:ci":"pnpm run test"},dependencies:{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@improbable-eng/grpc-web-node-http-transport":"^0.15.0","@latticexyz/abi-ts":"workspace:*","@latticexyz/common":"workspace:*","@latticexyz/config":"workspace:*","@latticexyz/gas-report":"workspace:*","@latticexyz/protocol-parser":"workspace:*","@latticexyz/schema-type":"workspace:*","@latticexyz/services":"workspace:*","@latticexyz/store":"workspace:*","@latticexyz/utils":"workspace:*","@latticexyz/world":"workspace:*","@latticexyz/world-modules":"workspace:*",chalk:"^5.0.1",chokidar:"^3.5.3",debug:"^4.3.4",dotenv:"^16.0.3",ejs:"^3.1.8",ethers:"^5.7.2",execa:"^7.0.0",glob:"^8.0.3","nice-grpc-web":"^2.0.1",openurl:"^1.1.1","p-retry":"^5.1.2",path:"^0.12.7",rxjs:"7.5.5","throttle-debounce":"^5.0.0",typescript:"5.1.6",viem:"1.14.0",yargs:"^17.7.1",zod:"^3.21.4","zod-validation-error":"^1.3.0"},devDependencies:{"@types/debug":"^4.1.7","@types/ejs":"^3.1.1","@types/glob":"^7.2.0","@types/node":"^18.15.11","@types/openurl":"^1.0.0","@types/throttle-debounce":"^5.0.0","@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.31.4"},gitHead:"914a1e0ae4a573d685841ca2ea921435057deb8f"};import Gr from"glob";import{ZodError as Lr,z as no}from"zod";var Kr=no.object({MUD_PACKAGES:no.string().transform(e=>JSON.parse(e))});function zr(){try{return Kr.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/faucet":{"localPath":"packages/faucet"},"@latticexyz/gas-report":{"localPath":"packages/gas-report"},"@latticexyz/noise":{"localPath":"packages/noise"},"@latticexyz/phaserx":{"localPath":"packages/phaserx"},"@latticexyz/protocol-parser":{"localPath":"packages/protocol-parser"},"@latticexyz/react":{"localPath":"packages/react"},"@latticexyz/recs":{"localPath":"packages/recs"},"@latticexyz/schema-type":{"localPath":"packages/schema-type"},"@latticexyz/services":{"localPath":"packages/services"},"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-modules":{"localPath":"packages/world-modules"},"@latticexyz/world":{"localPath":"packages/world"}}'})}catch(e){if(e instanceof Lr){let{_errors:o,...r}=e.format();console.error(`
11
+ in your contracts directory to use the default anvil private key.`);let m=Xe({config:t,forgeSourceDir:r,forgeOutDir:n}),i=Or({transport:Pr(l),account:Mr(a)});console.log("Deploying from",i.account.address);let p=Date.now(),u=await Ke({worldAddress:e.worldAddress,client:i,config:m});(e.worldAddress==null||e.alwaysRunPostDeploy)&&await eo(t.postDeployScript,u.address,l,o),console.log(R.green("Deployment completed in",(Date.now()-p)/1e3,"seconds"));let S={worldAddress:u.address,blockNumber:Number(u.deployBlock)};if(e.saveDeployment){let f=await Hr(i),g=G.join(t.deploysDirectory,f.toString());Ar(g,{recursive:!0}),oe(G.join(g,"latest.json"),JSON.stringify(S,null,2)),oe(G.join(g,Date.now()+".json"),JSON.stringify(S,null,2));let h=[1337,31337],b=kr(t.worldsFile)?JSON.parse(Ir(t.worldsFile,"utf-8")):{};b[f]={address:S.worldAddress,blockNumber:h.includes(f)?void 0:S.blockNumber},oe(t.worldsFile,JSON.stringify(b,null,2)),console.log(R.bgGreen(R.whiteBright(`
12
+ Deployment result (written to ${t.worldsFile} and ${g}):
13
+ `)))}return console.log(S),u}var Vr={command:"deploy",describe:"Deploy MUD contracts",builder(e){return e.options(P)},async handler(e){try{await $(e)}catch(o){W(o),process.exit(1)}process.exit(0)}},oo=Vr;import{loadConfig as _r}from"@latticexyz/config/node";import{worldgen as Lr}from"@latticexyz/world/node";import{getSrcDirectory as Kr}from"@latticexyz/common/foundry";import to from"path";import{rmSync as zr}from"fs";var Jr={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 config file"},clean:{type:"boolean",desc:"Clear the worldgen directory before generating new interfaces (defaults to true)",default:!0}})},async handler(e){await qr(e),process.exit(0)}};async function qr(e){let o=e.srcDir??await Kr(),t=F(o),r=e.config??await _r(e.configPath),n=to.join(o,r.codegenDirectory);e.clean&&zr(to.join(n,r.worldgenDirectory),{recursive:!0,force:!0}),await Lr(r,t,n)}var ro=Jr;import H from"chalk";import{readFileSync as Xr,writeFileSync as en}from"fs";import re from"path";import{MUDError as E}from"@latticexyz/common/errors";var no={name:"@latticexyz/cli",version:"2.0.0-next.11",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"},types:"src/index.ts",bin:{mud:"./dist/mud.js"},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":"rimraf dist","clean:test-tables":"rimraf src/codegen",dev:"tsup --watch",lint:"eslint . --ext .ts",prepare:"mkdir -p ./dist && touch ./dist/mud.js",test:"tsc --noEmit && forge test","test:ci":"pnpm run test"},dependencies:{"@ethersproject/abi":"^5.7.0","@ethersproject/providers":"^5.7.2","@improbable-eng/grpc-web":"^0.15.0","@improbable-eng/grpc-web-node-http-transport":"^0.15.0","@latticexyz/abi-ts":"workspace:*","@latticexyz/common":"workspace:*","@latticexyz/config":"workspace:*","@latticexyz/gas-report":"workspace:*","@latticexyz/protocol-parser":"workspace:*","@latticexyz/schema-type":"workspace:*","@latticexyz/services":"workspace:*","@latticexyz/store":"workspace:*","@latticexyz/utils":"workspace:*","@latticexyz/world":"workspace:*","@latticexyz/world-modules":"workspace:*",chalk:"^5.0.1",chokidar:"^3.5.3",debug:"^4.3.4",dotenv:"^16.0.3",ejs:"^3.1.8",ethers:"^5.7.2",execa:"^7.0.0",glob:"^8.0.3","nice-grpc-web":"^2.0.1",openurl:"^1.1.1","p-retry":"^5.1.2",path:"^0.12.7",rxjs:"7.5.5","throttle-debounce":"^5.0.0",typescript:"5.1.6",viem:"1.14.0",yargs:"^17.7.1",zod:"^3.21.4","zod-validation-error":"^1.3.0"},devDependencies:{"@types/debug":"^4.1.7","@types/ejs":"^3.1.1","@types/glob":"^7.2.0","@types/node":"^18.15.11","@types/openurl":"^1.0.0","@types/throttle-debounce":"^5.0.0","@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.31.4"},gitHead:"914a1e0ae4a573d685841ca2ea921435057deb8f"};import on from"glob";import{ZodError as Yr,z as so}from"zod";var Zr=so.object({MUD_PACKAGES:so.string().transform(e=>JSON.parse(e))});function Qr(){try{return Zr.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/faucet":{"localPath":"packages/faucet"},"@latticexyz/gas-report":{"localPath":"packages/gas-report"},"@latticexyz/noise":{"localPath":"packages/noise"},"@latticexyz/phaserx":{"localPath":"packages/phaserx"},"@latticexyz/protocol-parser":{"localPath":"packages/protocol-parser"},"@latticexyz/react":{"localPath":"packages/react"},"@latticexyz/recs":{"localPath":"packages/recs"},"@latticexyz/schema-type":{"localPath":"packages/schema-type"},"@latticexyz/services":{"localPath":"packages/services"},"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-modules":{"localPath":"packages/world-modules"},"@latticexyz/world":{"localPath":"packages/world"}}'})}catch(e){if(e instanceof Yr){let{_errors:o,...t}=e.format();console.error(`
14
14
  Missing or invalid environment variables:
15
15
 
16
- ${Object.keys(r).join(`
16
+ ${Object.keys(t).join(`
17
17
  `)}
18
- `),process.exit(1)}throw e}}var ee=zr().MUD_PACKAGES;var Yr={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((n,s)=>e[s]?n+1:n,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.mudVersion=await Zr(e);let t=Gr.sync("**/package.json").filter(n=>!n.includes("node_modules"));for(let n of t)Qr(n,e)}catch(o){M(o)}finally{process.exit(0)}}};async function Zr(e){e.mudVersion==="canary"&&(e.tag="main");let o;try{console.log(H.blue("Fetching available versions")),o=await(await fetch(`https://registry.npmjs.org/${ro.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(H.green(`Latest version with tag ${e.tag}: ${r}`)),r}if(e.commit){let r=e.commit.substring(0,8),t=Object.keys(o.versions).find(n=>n.includes(r));if(!t)throw new $(`Could not find npm version based on commit "${e.commit}"`);return console.log(H.green(`Version from commit ${e.commit}: ${t}`)),t}return e.mudVersion}function Qr(e,o){let{link:r}=o,{mudVersion:t}=o,n=Xr(e),s=Object.keys(ee),c={};for(let a in n.dependencies)s.includes(a)&&(c[a]=n.dependencies[a]);let i={};for(let a in n.devDependencies)s.includes(a)&&(i[a]=n.devDependencies[a]);for(let a in n.dependencies)s.includes(a)&&(n.dependencies[a]=m(a,"dependencies"));for(let a in n.devDependencies)s.includes(a)&&(n.devDependencies[a]=m(a,"devDependencies"));return qr(e,JSON.stringify(n,null,2)+`
19
- `),console.log(`Updating ${e}`),so(c,n.dependencies),so(i,n.devDependencies),n;function m(a,p){return r&&(t=en(e,r,a)),t||n[p][a]}}function Xr(e){try{let o=Jr(e,"utf8");return JSON.parse(o)}catch{throw new $("Could not read JSON at "+e)}}function so(e,o){for(let r in e)e[r]!==o[r]&&console.log(`${r}: ${H.red(e[r])} -> ${H.green(o[r])}`)}function en(e,o,r){let t=oe.relative(oe.dirname(e),process.cwd());return"link:"+oe.join(t,o,ee[r].localPath)}var io=Yr;import{anvil as on,forge as tn,getRpcUrl as rn}from"@latticexyz/common/foundry";import nn from"chalk";var sn={...O,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"}},an={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options(sn)},async handler(e){if(!e.worldAddress){let n=["--block-base-fee-per-gas","0","--port",String(e.port)];on(n)}let o=e.worldAddress?await rn(e.profile):`http://127.0.0.1:${e.port}`,r=e.worldAddress??(await E({...e,saveDeployment:!1,rpc:o})).address;console.log(nn.blue("World address",r));let t=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{await tn(["test","--fork-url",o,...t],{profile:e.profile,env:{WORLD_ADDRESS:r}}),process.exit(0)}catch(n){console.error(n),process.exit(1)}}},ao=an;import{existsSync as cn,readFileSync as ln}from"fs";import{ethers as co}from"ethers";import{loadConfig as dn}from"@latticexyz/config/node";import{MUDError as lo}from"@latticexyz/common/errors";import{cast as mn,getRpcUrl as pn,getSrcDirectory as fn}from"@latticexyz/common/foundry";import{resolveWorldConfig as un}from"@latticexyz/world";import yn from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import mo from"@latticexyz/world/mud.config.js";import{resourceToHex as fo}from"@latticexyz/common";import{createClient as gn,http as bn}from"viem";import{getChainId as hn}from"viem/actions";var po=fo({type:"system",namespace:mo.namespace,name:mo.tables.Systems.name}),wn={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 config file"},profile:{type:"string",description:"The foundry profile to use"},srcDir:{type:"string",description:"Source directory. Defaults to foundry src directory."},rpc:{type:"string",description:"json rpc endpoint. Defaults to foundry's configured eth_rpc_url"}})},async handler(e){e.profile??=process.env.FOUNDRY_PROFILE;let{profile:o}=e;e.srcDir??=await fn(o),e.rpc??=await pn(o);let{tx:r,configPath:t,srcDir:n,rpc:s}=e,c=F(n),i=await dn(t),m=un(i,c.map(({basename:l})=>l)),a=e.worldAddress??await xn(i.worldsFile,s),p=new co.providers.StaticJsonRpcProvider(s),w=new co.Contract(a,yn,p),u=i.namespace,f=Object.values(m.systems).map(({name:l})=>l),g=await w.getFieldLayout(po),h=[];for(let l of f){let y=fo({type:"system",namespace:u,name:l}),x=await w.getField(po,[y],0,g);h.push({name:l,address:x})}let b=await mn(["run","--label",`${a}:World`,...h.map(({name:l,address:y})=>["--label",`${y}:${l}`]).flat(),`${r}`]);console.log(b),process.exit(0)}},uo=wn;async function xn(e,o){if(cn(e)){let r=gn({transport:bn(o)}),t=await hn(r),n=JSON.parse(ln(e,"utf-8"));if(!n[t])throw new lo(`chainId ${t} is missing in worldsFile "${e}"`);return n[t].address}else throw new lo("worldAddress is not specified and worldsFile is missing")}import{anvil as Sn,getScriptDirectory as vn,getSrcDirectory as Cn}from"@latticexyz/common/foundry";import te from"chalk";import Tn from"chokidar";import{loadConfig as kn,resolveConfigPath as Dn}from"@latticexyz/config/node";import An from"path";import{homedir as In}from"os";import{rmSync as On}from"fs";import{BehaviorSubject as Pn,debounceTime as Mn,exhaustMap as Wn}from"rxjs";var jn={rpc:O.rpc,configPath:O.configPath,alwaysRunPostDeploy:O.alwaysRunPostDeploy},Fn={command:"dev-contracts",describe:"Start a development server for MUD contracts",builder(e){return e.options(jn)},async handler(e){let o=e.rpc,r=e.configPath??await Dn(e.configPath),t=await Cn(),n=await vn(),s=await kn(r);if(!e.rpc){console.log(te.gray("Cleaning devnode cache"));let a=In();On(An.join(a,".foundry","anvil","tmp"),{recursive:!0,force:!0}),Sn(["--block-time","1","--block-base-fee-per-gas","0"]),o="http://127.0.0.1:8545"}let c=new Pn(Date.now());Tn.watch([r,t,n]).on("all",async(a,p)=>{p.includes(r)&&c.next(Date.now()),(p.includes(t)||p.includes(n))&&(p.includes(s.codegenDirectory)||c.next(Date.now()))});let i;c.pipe(Mn(200),Wn(async a=>{i&&console.log(te.blue("Change detected, rebuilding and running deploy..."));let p=await E({...e,configPath:r,rpc:o,skipBuild:!1,printConfig:!1,profile:void 0,saveDeployment:!0,worldAddress:i,srcDir:t});return i=p.address,a<c.value?c.next(c.value):console.log(te.gray("Watching for file changes...")),p})).subscribe()}},yo=Fn;var go=[eo,ne,ie,Rn,ae,ce,to,io,ao,uo,yo,En];import*as ho from"dotenv";import bo from"chalk";ho.config();$n(Nn(process.argv)).scriptName("mud").command(go).strict().fail((e,o)=>{console.error(bo.red(e)),e.includes("Missing required argument")&&console.log(bo.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)),console.log(""),o!=null&&(M(o),console.log("")),process.exit(1)}).alias({h:"help"}).argv;
18
+ `),process.exit(1)}throw e}}var te=Qr().MUD_PACKAGES;var tn={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"],t=o.reduce((n,s)=>e[s]?n+1:n,0);if(t===0)throw new E(`You need to provide one these options: ${o.join(", ")}`);if(t>1)throw new E(`These options are mutually exclusive: ${o.join(", ")}`);e.mudVersion=await rn(e);let r=on.sync("**/package.json").filter(n=>!n.includes("node_modules"));for(let n of r)nn(n,e)}catch(o){W(o)}finally{process.exit(0)}}};async function rn(e){e.mudVersion==="canary"&&(e.tag="main");let o;try{console.log(H.blue("Fetching available versions")),o=await(await fetch(`https://registry.npmjs.org/${no.name}`)).json()}catch{throw new E("Could not fetch available MUD versions")}if(e.tag){let t=o["dist-tags"][e.tag];if(!t)throw new E(`Could not find npm version with tag "${e.tag}"`);return console.log(H.green(`Latest version with tag ${e.tag}: ${t}`)),t}if(e.commit){let t=e.commit.substring(0,8),r=Object.keys(o.versions).find(n=>n.includes(t));if(!r)throw new E(`Could not find npm version based on commit "${e.commit}"`);return console.log(H.green(`Version from commit ${e.commit}: ${r}`)),r}return e.mudVersion}function nn(e,o){let{link:t}=o,{mudVersion:r}=o,n=sn(e),s=Object.keys(te),l={};for(let i in n.dependencies)s.includes(i)&&(l[i]=n.dependencies[i]);let a={};for(let i in n.devDependencies)s.includes(i)&&(a[i]=n.devDependencies[i]);for(let i in n.dependencies)s.includes(i)&&(n.dependencies[i]=m(i,"dependencies"));for(let i in n.devDependencies)s.includes(i)&&(n.devDependencies[i]=m(i,"devDependencies"));return en(e,JSON.stringify(n,null,2)+`
19
+ `),console.log(`Updating ${e}`),ao(l,n.dependencies),ao(a,n.devDependencies),n;function m(i,p){return t&&(r=an(e,t,i)),r||n[p][i]}}function sn(e){try{let o=Xr(e,"utf8");return JSON.parse(o)}catch{throw new E("Could not read JSON at "+e)}}function ao(e,o){for(let t in e)e[t]!==o[t]&&console.log(`${t}: ${H.red(e[t])} -> ${H.green(o[t])}`)}function an(e,o,t){let r=re.relative(re.dirname(e),process.cwd());return"link:"+re.join(r,o,te[t].localPath)}var io=tn;import{anvil as cn,forge as ln,getRpcUrl as dn}from"@latticexyz/common/foundry";import mn from"chalk";var pn={...P,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"}},fn={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options(pn)},async handler(e){if(!e.worldAddress){let n=["--block-base-fee-per-gas","0","--port",String(e.port)];cn(n)}let o=e.worldAddress?await dn(e.profile):`http://127.0.0.1:${e.port}`,t=e.worldAddress??(await $({...e,saveDeployment:!1,rpc:o})).address;console.log(mn.blue("World address",t));let r=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{await ln(["test","--fork-url",o,...r],{profile:e.profile,env:{WORLD_ADDRESS:t}}),process.exit(0)}catch(n){console.error(n),process.exit(1)}}},co=fn;import{existsSync as un,readFileSync as yn}from"fs";import{ethers as lo}from"ethers";import{loadConfig as gn}from"@latticexyz/config/node";import{MUDError as mo}from"@latticexyz/common/errors";import{cast as bn,getRpcUrl as hn,getSrcDirectory as wn}from"@latticexyz/common/foundry";import{resolveWorldConfig as xn}from"@latticexyz/world";import Cn from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import po from"@latticexyz/world/mud.config.js";import{resourceToHex as uo}from"@latticexyz/common";import{createClient as Sn,http as vn}from"viem";import{getChainId as Dn}from"viem/actions";var fo=uo({type:"system",namespace:po.namespace,name:po.tables.Systems.name}),Tn={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 config file"},profile:{type:"string",description:"The foundry profile to use"},srcDir:{type:"string",description:"Source directory. Defaults to foundry src directory."},rpc:{type:"string",description:"json rpc endpoint. Defaults to foundry's configured eth_rpc_url"}})},async handler(e){e.profile??=process.env.FOUNDRY_PROFILE;let{profile:o}=e;e.srcDir??=await wn(o),e.rpc??=await hn(o);let{tx:t,configPath:r,srcDir:n,rpc:s}=e,l=F(n),a=await gn(r),m=xn(a,l.map(({basename:c})=>c)),i=e.worldAddress??await kn(a.worldsFile,s),p=new lo.providers.StaticJsonRpcProvider(s),u=new lo.Contract(i,Cn,p),S=a.namespace,f=Object.values(m.systems).map(({name:c})=>c),g=await u.getFieldLayout(fo),h=[];for(let c of f){let y=uo({type:"system",namespace:S,name:c}),w=await u.getField(fo,[y],0,g);h.push({name:c,address:w})}let b=await bn(["run","--label",`${i}:World`,...h.map(({name:c,address:y})=>["--label",`${y}:${c}`]).flat(),`${t}`]);console.log(b),process.exit(0)}},yo=Tn;async function kn(e,o){if(un(e)){let t=Sn({transport:vn(o)}),r=await Dn(t),n=JSON.parse(yn(e,"utf-8"));if(!n[r])throw new mo(`chainId ${r} is missing in worldsFile "${e}"`);return n[r].address}else throw new mo("worldAddress is not specified and worldsFile is missing")}import{anvil as An,getScriptDirectory as In,getSrcDirectory as On}from"@latticexyz/common/foundry";import ne from"chalk";import Pn from"chokidar";import{loadConfig as Mn,resolveConfigPath as Wn}from"@latticexyz/config/node";import jn from"path";import{homedir as Fn}from"os";import{rmSync as Rn}from"fs";import{BehaviorSubject as $n,debounceTime as En,exhaustMap as Nn}from"rxjs";var Bn={rpc:P.rpc,configPath:P.configPath,alwaysRunPostDeploy:P.alwaysRunPostDeploy},Hn={command:"dev-contracts",describe:"Start a development server for MUD contracts",builder(e){return e.options(Bn)},async handler(e){let o=e.rpc,t=e.configPath??await Wn(e.configPath),r=await On(),n=await In(),s=await Mn(t);if(!e.rpc){console.log(ne.gray("Cleaning devnode cache"));let i=Fn();Rn(jn.join(i,".foundry","anvil","tmp"),{recursive:!0,force:!0}),An(["--block-time","1","--block-base-fee-per-gas","0"]),o="http://127.0.0.1:8545"}let l=new $n(Date.now());Pn.watch([t,r,n]).on("all",async(i,p)=>{p.includes(t)&&l.next(Date.now()),(p.includes(r)||p.includes(n))&&(p.includes(s.codegenDirectory)||l.next(Date.now()))});let a;l.pipe(En(200),Nn(async i=>{a&&console.log(ne.blue("Change detected, rebuilding and running deploy..."));let p=await $({...e,configPath:t,rpc:o,skipBuild:!1,printConfig:!1,profile:void 0,saveDeployment:!0,worldAddress:a,srcDir:r});return a=p.address,i<l.value?l.next(l.value):console.log(ne.gray("Watching for file changes...")),p})).subscribe()}},go=Hn;var bo=[oo,ae,ce,Un,le,de,ro,io,co,yo,go,Vn];import*as wo from"dotenv";import ho from"chalk";wo.config();_n(Ln(process.argv)).scriptName("mud").command(bo).strict().fail((e,o)=>{console.error(ho.red(e)),e.includes("Missing required argument")&&console.log(ho.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)),console.log(""),o!=null&&(W(o),console.log("")),process.exit(1)}).alias({h:"help"}).argv;
20
20
  //# sourceMappingURL=mud.js.map