@latticexyz/cli 2.0.0-main-e241c056 → 2.0.0-main-29c3f508

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.
Files changed (60) hide show
  1. package/dist/index.js +0 -1
  2. package/dist/mud.js +13 -13
  3. package/dist/mud.js.map +1 -1
  4. package/package.json +15 -12
  5. package/src/commands/deploy.ts +7 -30
  6. package/src/commands/dev-contracts.ts +62 -137
  7. package/src/commands/test.ts +26 -26
  8. package/src/commands/trace.ts +4 -2
  9. package/src/debug.ts +3 -0
  10. package/src/deploy/assertNamespaceOwner.ts +42 -0
  11. package/src/deploy/common.ts +67 -0
  12. package/src/deploy/configToTables.ts +60 -0
  13. package/src/deploy/create2/README.md +9 -0
  14. package/src/deploy/create2/deployment.json +7 -0
  15. package/src/deploy/debug.ts +3 -0
  16. package/src/deploy/deploy.ts +84 -0
  17. package/src/deploy/deployWorld.ts +33 -0
  18. package/src/deploy/ensureContract.ts +33 -0
  19. package/src/deploy/ensureDeployer.ts +36 -0
  20. package/src/deploy/ensureFunctions.ts +62 -0
  21. package/src/deploy/ensureModules.ts +48 -0
  22. package/src/deploy/ensureSystems.ts +128 -0
  23. package/src/deploy/ensureTables.ts +52 -0
  24. package/src/deploy/ensureWorldFactory.ts +33 -0
  25. package/src/deploy/getFunctions.ts +58 -0
  26. package/src/deploy/getResourceAccess.ts +51 -0
  27. package/src/deploy/getResourceIds.ts +31 -0
  28. package/src/deploy/getSystems.ts +48 -0
  29. package/src/deploy/getTableValue.ts +30 -0
  30. package/src/deploy/getTables.ts +59 -0
  31. package/src/deploy/getWorldDeploy.ts +39 -0
  32. package/src/deploy/logsToWorldDeploy.ts +49 -0
  33. package/src/deploy/resolveConfig.ts +154 -0
  34. package/src/deploy/resourceLabel.ts +3 -0
  35. package/src/index.ts +1 -1
  36. package/src/runDeploy.ts +131 -0
  37. package/src/utils/modules/constants.ts +1 -2
  38. package/src/utils/utils/getContractData.ts +2 -5
  39. package/dist/chunk-K6DUKTDI.js +0 -11
  40. package/dist/chunk-K6DUKTDI.js.map +0 -1
  41. package/src/utils/deploy.ts +0 -254
  42. package/src/utils/deployHandler.ts +0 -93
  43. package/src/utils/modules/getInstallModuleCallData.ts +0 -27
  44. package/src/utils/modules/getUserModules.ts +0 -5
  45. package/src/utils/modules/types.ts +0 -14
  46. package/src/utils/systems/getGrantAccessCallData.ts +0 -29
  47. package/src/utils/systems/getRegisterFunctionSelectorsCallData.ts +0 -57
  48. package/src/utils/systems/getRegisterSystemCallData.ts +0 -17
  49. package/src/utils/systems/types.ts +0 -9
  50. package/src/utils/systems/utils.ts +0 -42
  51. package/src/utils/tables/getRegisterTableCallData.ts +0 -49
  52. package/src/utils/tables/getTableIds.ts +0 -18
  53. package/src/utils/tables/types.ts +0 -12
  54. package/src/utils/utils/confirmNonce.ts +0 -24
  55. package/src/utils/utils/deployContract.ts +0 -33
  56. package/src/utils/utils/fastTxExecute.ts +0 -56
  57. package/src/utils/utils/getChainId.ts +0 -10
  58. package/src/utils/utils/setInternalFeePerGas.ts +0 -49
  59. package/src/utils/utils/types.ts +0 -21
  60. package/src/utils/world.ts +0 -28
package/dist/index.js CHANGED
@@ -1,2 +1 @@
1
- import{c as o}from"./chunk-K6DUKTDI.js";export{o as deployHandler};
2
1
  //# sourceMappingURL=index.js.map
package/dist/mud.js CHANGED
@@ -1,20 +1,20 @@
1
1
  #!/usr/bin/env node
2
- import{a as k,b as U,c as y}from"./chunk-K6DUKTDI.js";import xo from"yargs";import{hideBin as Mo}from"yargs/helpers";import Co from"@latticexyz/gas-report";import ko from"@latticexyz/abi-ts";import{rmSync as ie}from"fs";import{homedir as se}from"os";import ae from"path";import{execa as ce}from"execa";var de={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=se();ie(ae.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=ce("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}},R=de;import{FaucetServiceDefinition as le}from"@latticexyz/services/faucet";import{createChannel as pe,createClient as me}from"nice-grpc-web";import A from"chalk";import{NodeHttpTransport as fe}from"@improbable-eng/grpc-web-node-http-transport";function ge(e){return me(le,pe(e,fe()))}var ue={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=ge(o);e&&(console.log(A.yellow("Dripping to",t)),await r.dripDev({address:t}),console.log(A.yellow("Success"))),process.exit(0)}},E=ue;var ye={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)}},W=ye;import he from"path";import{loadConfig as be}from"@latticexyz/config/node";import{tablegen as we}from"@latticexyz/store/codegen";import{getRemappings as ve,getSrcDirectory as De}from"@latticexyz/common/foundry";var Ce={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 be(e),t=await De(),r=await ve();await we(o,he.join(t,o.codegenDirectory),r),process.exit(0)}},$=Ce;import w from"chalk";import{ZodError as ke}from"zod";import{fromZodError as xe,ValidationError as Me}from"zod-validation-error";import{NotInsideProjectError as Se}from"@latticexyz/config";import{MUDError as Oe}from"@latticexyz/common/errors";function f(e){if(e instanceof Me)console.log(w.redBright(e.message));else if(e instanceof ke){let o=xe(e,{prefixSeparator:`
2
+ import Cn from"yargs";import{hideBin as Tn}from"yargs/helpers";import Sn from"@latticexyz/gas-report";import vn from"@latticexyz/abi-ts";import{rmSync as uo}from"fs";import{homedir as yo}from"os";import go from"path";import{execa as bo}from"execa";var ho={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=yo();uo(go.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=bo("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}},te=ho;import{FaucetServiceDefinition as wo}from"@latticexyz/services/faucet";import{createChannel as xo,createClient as So}from"nice-grpc-web";import re from"chalk";import{NodeHttpTransport as vo}from"@improbable-eng/grpc-web-node-http-transport";function Co(e){return So(wo,xo(e,vo()))}var To={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=Co(o);e&&(console.log(re.yellow("Dripping to",t)),await r.dripDev({address:t}),console.log(re.yellow("Success"))),process.exit(0)}},ne=To;var ko={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=ko;import Do from"path";import{loadConfig as Ao}from"@latticexyz/config/node";import{tablegen as Io}from"@latticexyz/store/codegen";import{getRemappings as Oo,getSrcDirectory as Po}from"@latticexyz/common/foundry";var Mo={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 Ao(e),t=await Po(),r=await Oo();await Io(o,Do.join(t,o.codegenDirectory),r),process.exit(0)}},ae=Mo;import H from"chalk";import{ZodError as Wo}from"zod";import{fromZodError as jo,ValidationError as Fo}from"zod-validation-error";import{NotInsideProjectError as Eo}from"@latticexyz/config";import{MUDError as Ro}from"@latticexyz/common/errors";function W(e){if(e instanceof Fo)console.log(H.redBright(e.message));else if(e instanceof Wo){let o=jo(e,{prefixSeparator:`
4
4
  - `,issueSeparator:`
5
- - `});console.log(w.redBright(o.message))}else e instanceof Se?(console.log(w.red(e.message)),console.log(""),console.log(w.blue("To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/"))):e instanceof Oe?console.log(w.red(e)):console.log(e)}var S={configPath:{type:"string",desc:"Path to the config file"},clean:{type:"boolean",desc:"Remove the build forge artifacts and cache directories before building"},printConfig:{type:"boolean",desc:"Print the resolved config"},profile:{type:"string",desc:"The foundry profile to use"},debug:{type:"boolean",desc:"Print debug logs, like full error messages"},priorityFeeMultiplier:{type:"number",desc:"Multiply the estimated priority fee by the provided factor",default:1},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."},disableTxWait:{type:"boolean",desc:"Disable waiting for transactions to be confirmed.",default:!1},pollInterval:{type:"number",desc:"Interval in miliseconds to use to poll for transaction receipts / block inclusion",default:1e3},skipBuild:{type:"boolean",desc:"Skip rebuilding the contracts before deploying"}},Pe={command:"deploy",describe:"Deploy MUD contracts",builder(e){return e.options(S)},async handler(e){try{await y(e)}catch(o){f(o),process.exit(1)}process.exit(0)}},I=Pe;import{loadConfig as je}from"@latticexyz/config/node";import{worldgen as Ue}from"@latticexyz/world/node";import{getSrcDirectory as Re}from"@latticexyz/common/foundry";import z from"path";import{rmSync as Ae}from"fs";var Ee={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 O(e),process.exit(0)}};async function O(e){let o=e.srcDir??await Re(),t=k(o),r=e.config??await je(e.configPath),n=z.join(o,r.codegenDirectory);e.clean&&Ae(z.join(n,r.worldgenDirectory),{recursive:!0,force:!0}),await Ue(r,t,n)}var T=Ee;import v from"chalk";import{readFileSync as Te,writeFileSync as Ne}from"fs";import j from"path";import{MUDError as h}from"@latticexyz/common/errors";var N={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",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",path:"^0.12.7","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/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 Fe from"glob";import{ZodError as $e,z as F}from"zod";var Ie=F.object({MUD_PACKAGES:F.string().transform(e=>JSON.parse(e))});function ze(){try{return Ie.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 $e){let{_errors:o,...t}=e.format();console.error(`
5
+ - `});console.log(H.redBright(o.message))}else e instanceof Eo?(console.log(H.red(e.message)),console.log(""),console.log(H.blue("To learn more about MUD's configuration, please go to https://mud.dev/packages/cli/"))):e instanceof Ro?console.log(H.red(e)):console.log(e)}import J from"node:path";import{existsSync as ir,mkdirSync as cr,readFileSync as lr,writeFileSync as Z}from"node:fs";import{getBytecode as No,sendRawTransaction as Bo,sendTransaction as Vo,waitForTransactionReceipt as ce}from"viem/actions";var O={gasPrice:1e11,gasLimit:1e5,signerAddress:"3fab184622dc19b6109349b94811493bf2a45362",transaction:"f8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222",address:"4e59b44847b379578588920ca78fbf26c0b4956c"};import Ho from"debug";var ie=Ho("mud:cli");var d=ie.extend("deploy");var C=`0x${O.address}`;async function le(e){if(await No(e,{address:C})){d("found create2 deployer at",C);return}d("sending gas for create2 deployer to signer at",O.signerAddress);let t=await Vo(e,{chain:e.chain??null,to:`0x${O.signerAddress}`,value:BigInt(O.gasLimit)*BigInt(O.gasPrice)}),r=await ce(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",C);let n=await Bo(e,{serializedTransaction:`0x${O.transaction}`}),s=await ce(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 it}from"viem/actions";import Xo from"@latticexyz/world/out/CoreModule.sol/CoreModule.json"assert{type:"json"};import et from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.json"assert{type:"json"};import{parseAbi as ot,getCreate2Address as fe,encodeDeployData as ue}from"viem";import{concatHex as qo,getCreate2Address as Yo}from"viem";import{getBytecode as Zo}from"viem/actions";import{padHex as _o}from"viem";import Lo from"@latticexyz/store/mud.config.js";import Ko from"@latticexyz/world/mud.config.js";import zo from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import{resourceToHex as Uo}from"@latticexyz/common";import{resolveUserTypes as de}from"@latticexyz/store";function N(e){return Object.fromEntries(Object.entries(e.tables).map(([o,t])=>[`${e.namespace}_${o}`,{namespace:e.namespace,name:t.name,tableId:Uo({type:t.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:t.name}),keySchema:de(t.keySchema,e.userTypes),valueSchema:de(t.valueSchema,e.userTypes)}]))}import{helloStoreEvent as Jo}from"@latticexyz/store";import{helloWorldEvent as Go}from"@latticexyz/world";var D=_o("0x",{size:32}),j=N(Lo),k=N(Ko),V=[Jo,Go],S=zo,me=["1.0.0-unaudited"],pe=["1.0.0-unaudited"];import{sendTransaction as Qo}from"@latticexyz/common";async function P({client:e,bytecode:o,label:t="contract"}){let r=Yo({from:C,salt:D,bytecode:o});return await Zo(e,{address:r,blockTag:"pending"})?(d("found",t,"at",r),[]):(d("deploying",t,"at",r),[await Qo(e,{chain:e.chain??null,to:C,data:qo([D,o])})])}var ye=ue({bytecode:Xo.bytecode.object,abi:[]}),tt=fe({from:C,bytecode:ye,salt:D}),ge=ue({bytecode:et.bytecode.object,abi:ot(["constructor(address)"]),args:[tt]}),be=fe({from:C,bytecode:ge,salt:D});async function he(e){return(await Promise.all([P({client:e,bytecode:ye,label:"core module"}),P({client:e,bytecode:ge,label:"world factory"})])).flat()}import ct from"@latticexyz/world/out/WorldFactory.sol/WorldFactory.abi.json"assert{type:"json"};import{writeContract as lt}from"@latticexyz/common";import{AbiEventSignatureNotFoundError as rt,decodeEventLog as nt,hexToString as we,parseAbi as st,trim as xe}from"viem";import{isDefined as at}from"@latticexyz/common/utils";function U(e){let o=e.map(c=>{try{return{...c,...nt({strict:!0,abi:st(V),topics:c.topics,data:c.data})}}catch(a){if(a instanceof rt)return;throw a}}).filter(at),{address:t,deployBlock:r,worldVersion:n,storeVersion:s}=o.reduce((c,a)=>({...c,address:a.address,deployBlock:a.blockNumber,...a.eventName==="HelloWorld"?{worldVersion:we(xe(a.args.worldVersion,{dir:"right"}))}:null,...a.eventName==="HelloStore"?{storeVersion:we(xe(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 Se(e){await he(e),d("deploying world");let o=await lt(e,{chain:e.chain??null,address:be,abi:ct,functionName:"deployWorld"});d("waiting for world deploy");let t=await it(e,{hash:o});if(t.status!=="success")throw console.error("world deploy failed",t),new Error("world deploy failed");let r=U(t.logs.map(n=>n));return d("deployed world to",r.address,"at block",r.deployBlock),{...r,stateBlock:r.deployBlock}}import{writeContract as gt}from"@latticexyz/common";import{valueSchemaToFieldLayoutHex as bt,keySchemaToHex as ht,valueSchemaToHex as wt}from"@latticexyz/protocol-parser";function T({namespace:e,name:o}){return`${e}:${o}`}import{parseAbiItem as dt,decodeAbiParameters as ve,parseAbiParameters as Ce}from"viem";import{hexToResource as mt}from"@latticexyz/common";import{storeSetRecordEvent as pt}from"@latticexyz/store";import{getLogs as ft}from"viem/actions";import{decodeKey as ut,decodeValueArgs as yt,hexToSchema as Te}from"@latticexyz/protocol-parser";async function ke({client:e,worldDeploy:o}){d("looking up tables for",o.address);let r=(await ft(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:dt(pt),args:{tableId:j.store_Tables.tableId}})).map(n=>{let{tableId:s}=ut(j.store_Tables.keySchema,n.args.keyTuple),{namespace:c,name:a}=mt(s),p=yt(j.store_Tables.valueSchema,n.args),i=Te(p.keySchema),f=Te(p.valueSchema),u=ve(Ce("string[]"),p.abiEncodedKeyNames)[0],v=ve(Ce("string[]"),p.abiEncodedFieldNames)[0],m=[...f.staticFields,...f.dynamicFields],y=Object.fromEntries(i.staticFields.map((g,b)=>[u[b],g])),h=Object.fromEntries(m.map((g,b)=>[v[b],g]));return{namespace:c,name:a,tableId:s,keySchema:y,valueSchema:h}});return d("found",r.length,"tables for",o.address),r}async function De({client:e,worldDeploy:o,tables:t}){let n=(await ke({client:e,worldDeploy:o})).map(a=>a.tableId),s=t.filter(a=>n.includes(a.tableId));s.length&&d("existing tables",s.map(T).join(", "));let c=t.filter(a=>!n.includes(a.tableId));return c.length?(d("registering tables",c.map(T).join(", ")),await Promise.all(c.map(a=>gt(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"registerTable",args:[a.tableId,bt(a.valueSchema),ht(a.keySchema),wt(a.valueSchema),Object.keys(a.keySchema),Object.keys(a.valueSchema)]})))):[]}import{getAddress as I}from"viem";import{writeContract as G}from"@latticexyz/common";import{parseAbiItem as xt}from"viem";import{getLogs as St}from"viem/actions";import{storeSpliceStaticDataEvent as vt}from"@latticexyz/store";async function _({client:e,worldDeploy:o}){d("looking up resource IDs for",o.address);let r=(await St(e,{strict:!0,address:o.address,fromBlock:o.deployBlock,toBlock:o.stateBlock,event:xt(vt),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 $t}from"@latticexyz/common";import{decodeValueArgs as Ct,encodeKey as Tt}from"@latticexyz/protocol-parser";import{readContract as kt}from"viem/actions";async function A({client:e,worldDeploy:o,table:t,key:r}){let[n,s,c]=await kt(e,{blockNumber:o.stateBlock,address:o.address,abi:S,functionName:"getRecord",args:[t.tableId,Tt(t.keySchema,r)]});return Ct(t.valueSchema,{staticData:n,encodedLengths:s,dynamicData:c})}import{getFunctionSelector as Dt,parseAbiItem as At}from"viem";import{storeSetRecordEvent as It}from"@latticexyz/store";import{getLogs as Ot}from"viem/actions";import{decodeValueArgs as Pt}from"@latticexyz/protocol-parser";import{hexToResource as Mt}from"@latticexyz/common";async function L({client:e,worldDeploy:o}){d("looking up function signatures for",o.address);let r=(await Ot(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:At(It),args:{tableId:k.world_FunctionSignatures.tableId}})).map(s=>Pt(k.world_FunctionSignatures.valueSchema,s.args).functionSignature);return d("found",r.length,"function signatures for",o.address),await Promise.all(r.map(async s=>{let c=Dt(s),{systemId:a,systemFunctionSelector:p}=await A({client:e,worldDeploy:o,table:k.world_FunctionSelectors,key:{functionSelector:c}}),{namespace:i,name:f}=Mt(a),u=i===""?s:s.replace(`${i}_${f}_`,"");return{signature:s,selector:c,systemId:a,systemFunctionSignature:u,systemFunctionSelector:p}}))}import{parseAbiItem as Wt,getAddress as jt}from"viem";import{storeSpliceStaticDataEvent as Ft}from"@latticexyz/store";import{getLogs as Et}from"viem/actions";import{decodeKey as Rt}from"@latticexyz/protocol-parser";async function K({client:e,worldDeploy:o}){d("looking up resource access for",o.address);let r=(await Et(e,{strict:!0,fromBlock:o.deployBlock,toBlock:o.stateBlock,address:o.address,event:Wt(Ft),args:{tableId:k.world_ResourceAccess.tableId}})).map(s=>Rt(k.world_ResourceAccess.keySchema,s.args.keyTuple)),n=(await Promise.all(r.map(async s=>[s,await A({client:e,worldDeploy:o,table:k.world_ResourceAccess,key:s})]))).filter(([,s])=>s.access).map(([s])=>({resourceId:s.resourceId,address:jt(s.caller)}));return d("found",n.length,"resource<>address access pairs"),n}async function Ae({client:e,worldDeploy:o}){let[t,r,n]=await Promise.all([_({client:e,worldDeploy:o}),L({client:e,worldDeploy:o}),K({client:e,worldDeploy:o})]),s=t.map($t).filter(c=>c.type==="system");return d("looking up systems",s.map(T).join(", ")),await Promise.all(s.map(async c=>{let{system:a,publicAccess:p}=await A({client:e,worldDeploy:o,table:k.world_Systems,key:{systemId:c.resourceId}}),i=r.filter(f=>f.systemId===c.resourceId);return{address:a,namespace:c.namespace,name:c.name,systemId:c.resourceId,allowAll:p,allowedAddresses:n.filter(({resourceId:f})=>f===c.resourceId).map(({address:f})=>f),functions:i}}))}async function Ie({client:e,worldDeploy:o,systems:t}){let[r,n]=await Promise.all([Ae({client:e,worldDeploy:o}),K({client:e,worldDeploy:o})]),s=t.map(l=>l.systemId),c=n.filter(({resourceId:l})=>s.includes(l)),a=t.flatMap(l=>l.allowedAddresses.map(w=>({resourceId:l.systemId,address:w}))),p=a.filter(l=>!c.some(({resourceId:w,address:x})=>w===l.resourceId&&I(x)===I(l.address))),i=c.filter(l=>!a.some(({resourceId:w,address:x})=>w===l.resourceId&&I(x)===I(l.address)));i.length&&d("revoking",i.length,"access grants"),p.length&&d("adding",p.length,"access grants");let f=await Promise.all([...i.map(l=>G(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"revokeAccess",args:[l.resourceId,l.address]})),...p.map(l=>G(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"grantAccess",args:[l.resourceId,l.address]}))]),u=t.filter(l=>r.some(w=>w.systemId===l.systemId&&I(w.address)===I(l.address)));u.length&&d("existing systems",u.map(T).join(", "));let v=u.map(l=>l.systemId),m=t.filter(l=>!v.includes(l.systemId));if(!m.length)return[];let y=m.filter(l=>r.some(w=>w.systemId===l.systemId&&I(w.address)!==I(l.address)));y.length&&d("upgrading systems",y.map(T).join(", "));let h=m.filter(l=>!r.some(w=>w.systemId===l.systemId));h.length&&d("registering new systems",h.map(T).join(", "));let g=await Promise.all(m.map(l=>P({client:e,bytecode:l.bytecode,label:`${T(l)} system`}))),b=await Promise.all(m.map(l=>G(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"registerSystem",args:[l.systemId,l.address,l.allowAll]})));return(await Promise.all([...f,...g,...b])).flat()}import{waitForTransactionReceipt as Lt}from"viem/actions";import{getAddress as Ht,parseAbi as Nt}from"viem";import{getBlockNumber as Bt,getLogs as Vt}from"viem/actions";var Oe=new Map;async function Pe(e,o){let t=Ht(o),r=Oe.get(t);if(r!=null)return r;d("looking up world deploy for",t);let n=await Bt(e),s=await Vt(e,{strict:!0,address:t,events:Nt(V),fromBlock:"earliest",toBlock:n});return r={...U(s),stateBlock:n},Oe.set(t,r),d("found world deploy for",t,"at block",r.deployBlock),r}import{hexToResource as Ut,writeContract as Me}from"@latticexyz/common";async function We({client:e,worldDeploy:o,functions:t}){let r=await L({client:e,worldDeploy:o}),n=Object.fromEntries(r.map(a=>[a.selector,a])),s=t.filter(a=>n[a.selector]),c=t.filter(a=>!s.includes(a));if(s.length){d("functions already registered:",s.map(p=>p.signature).join(", "));let a=s.filter(p=>p.systemId!==n[p.selector]?.systemId);a.length&&console.warn("found",a.length,"functions already registered but pointing at a different system ID:",a.map(p=>p.signature).join(", "))}return c.length?(d("registering functions:",c.map(a=>a.signature).join(", ")),Promise.all(c.map(a=>{let{namespace:p}=Ut(a.systemId);return p===""?Me(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"registerRootFunctionSelector",args:[a.systemId,a.systemFunctionSignature,a.systemFunctionSelector]}):Me(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"registerFunctionSelector",args:[a.systemId,a.systemFunctionSignature]})}))):[]}import{writeContract as je}from"@latticexyz/common";async function Fe({client:e,worldDeploy:o,modules:t}){if(!t.length)return[];let r=await Promise.all(t.map(s=>P({client:e,bytecode:s.bytecode,label:`${s.name} module`})));d("installing modules:",t.map(s=>s.name).join(", "));let n=await Promise.all(t.map(s=>s.installAsRoot?je(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"installRootModule",args:[s.address,s.installData]}):je(e,{chain:e.chain??null,address:o.address,abi:S,functionName:"installModule",args:[s.address,s.installData]})));return(await Promise.all([...r,...n])).flat()}import{getAddress as Ee}from"viem";import{hexToResource as Re,resourceToHex as _t}from"@latticexyz/common";async function $e({client:e,worldDeploy:o,resourceIds:t}){let r=Array.from(new Set(t.map(i=>Re(i).namespace))),n=await _({client:e,worldDeploy:o}),s=Array.from(new Set(n.map(i=>Re(i).namespace))),c=r.filter(i=>s.includes(i)),p=(await Promise.all(c.map(async i=>{let{owner:f}=await A({client:e,worldDeploy:o,table:k.world_NamespaceOwner,key:{namespaceId:_t({type:"namespace",namespace:i,name:""})}});return[i,f]}))).filter(([,i])=>Ee(i)!==Ee(e.account.address)).map(([i])=>i);if(p.length)throw new Error(`You are attempting to deploy to namespaces you do not own: ${p.join(", ")}`)}async function He({client:e,config:o,worldAddress:t}){await le(e);let r=t?await Pe(e,t):await Se(e);if(!me.includes(r.storeVersion))throw new Error(`Unsupported Store version: ${r.storeVersion}`);if(!pe.includes(r.worldVersion))throw new Error(`Unsupported World version: ${r.worldVersion}`);let n=Object.values(o.tables),s=Object.values(o.systems);await $e({client:e,worldDeploy:r,resourceIds:[...n.map(u=>u.tableId),...s.map(u=>u.systemId)]});let c=await De({client:e,worldDeploy:r,tables:n}),a=await Ie({client:e,worldDeploy:r,systems:s}),p=await We({client:e,worldDeploy:r,functions:s.flatMap(u=>u.functions)}),i=await Fe({client:e,worldDeploy:r,modules:o.modules}),f=await Promise.all([...c,...a,...p,...i].map(u=>Lt(e,{hash:u})));return r}import{createWalletClient as dr,http as mr}from"viem";import{privateKeyToAccount as pr}from"viem/accounts";import{loadConfig as fr}from"@latticexyz/config/node";import{forge as Ge,getOutDirectory as ur,getRemappings as yr,getRpcUrl as gr,getSrcDirectory as br}from"@latticexyz/common/foundry";import E from"chalk";import{execa as hr}from"execa";import{MUDError as wr}from"@latticexyz/common/errors";import{resolveWorldConfig as qt}from"@latticexyz/world";import{resourceToHex as Y,hexToResource as Yt}from"@latticexyz/common";import{resolveWithContext as Zt}from"@latticexyz/config";import{encodeField as Qt}from"@latticexyz/protocol-parser";import{getFunctionSelector as _e,getCreate2Address as Le,getAddress as Xt,hexToBytes as er,bytesToHex as or,getFunctionSignature as Ke}from"viem";import Kt from"glob";import{basename as zt}from"path";function F(e){return Kt.sync(`${e}/**/*.sol`).map(o=>({path:o,basename:zt(o,".sol")}))}import Ne from"@latticexyz/world-modules/out/KeysWithValueModule.sol/KeysWithValueModule.json"assert{type:"json"};import Be from"@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json"assert{type:"json"};import Ve from"@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json"assert{type:"json"};var Ue=[{name:"KeysWithValueModule",abi:Ne.abi,bytecode:Ne.bytecode},{name:"KeysInTableModule",abi:Be.abi,bytecode:Be.bytecode},{name:"UniqueEntityModule",abi:Ve.abi,bytecode:Ve.bytecode}];import{readFileSync as Jt}from"fs";import Gt from"path";import{MUDError as q}from"@latticexyz/common/errors";function z(e,o){let t,r=Gt.join(o,e+".sol",e+".json");try{t=JSON.parse(Jt(r,"utf8"))}catch{throw new q(`Error reading file at ${r}`)}let n=t?.bytecode?.object;if(!n)throw new q(`No bytecode found in ${r}`);let s=t?.abi;if(!s)throw new q(`No ABI found in ${r}`);return{abi:s,bytecode:n}}function ze({config:e,forgeSourceDir:o,forgeOutDir:t}){let r=N(e),n=F(o).map(({basename:m})=>m),s=qt(e,n),a=z("System",t).abi.filter(m=>m.type==="function").map(Ke),p=Object.entries(s.systems).map(([m,y])=>{let h=e.namespace,g=y.name,b=Y({type:"system",namespace:h,name:g}),l=z(m,t),w=l.abi.filter(x=>x.type==="function").map(Ke).filter(x=>!a.includes(x)).map(x=>{let oe=h===""?x:`${h}_${g}_${x}`;return{signature:oe,selector:_e(oe),systemId:b,systemFunctionSignature:x,systemFunctionSelector:_e(x)}});return{namespace:h,name:g,systemId:b,allowAll:y.openAccess,allowedAddresses:y.accessListAddresses,allowedSystemIds:y.accessListSystems.map(x=>Y({type:"system",namespace:h,name:s.systems[x].name})),address:Le({from:C,bytecode:l.bytecode,salt:D}),bytecode:l.bytecode,abi:l.abi,functions:w}}),i=p.map(({allowedAddresses:m,allowedSystemIds:y,...h})=>{let g=y.map(b=>{let l=p.find(w=>w.systemId===b);if(!l)throw new Error(`System ${T(h)} wanted access to ${T(Yt(b))}, but it wasn't found in the config.`);return l.address});return{...h,allowedAddresses:Array.from(new Set([...m,...g].map(b=>Xt(b))))}}),f={tableIds:Object.fromEntries(Object.entries(e.tables).map(([m,y])=>[m,er(Y({type:y.offchainOnly?"offchainTable":"table",namespace:e.namespace,name:y.name}))]))},u=Ue.map(m=>({name:m.name,bytecode:typeof m.bytecode=="string"?m.bytecode:m.bytecode.object,abi:m.abi})),v=e.modules.map(m=>{let y=u.find(g=>g.name===m.name)??z(m.name,t),h=m.args.map(g=>Zt(g,f)).map(g=>{let b=g.value instanceof Uint8Array?or(g.value):g.value;return Qt(g.type,b)});if(h.length>1)throw new Error(`${m.name} module should only have 0-1 args, but had ${h.length} args.`);return{name:m.name,installAsRoot:m.root,installData:h.length===0?"0x":h[0],address:Le({from:C,bytecode:y.bytecode,salt:D}),bytecode:y.bytecode,abi:y.abi}});return{tables:r,systems:i,modules:v}}import{getChainId as xr}from"viem/actions";import{existsSync as tr}from"fs";import rr from"path";import nr from"chalk";import{getScriptDirectory as sr,forge as ar}from"@latticexyz/common/foundry";async function Je(e,o,t,r){let n=rr.join(await sr(),e+".s.sol");tr(n)?(console.log(nr.blue(`Executing post deploy script at ${n}`)),await ar(["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 Sr}from"@latticexyz/store/codegen";var M={configPath:{type:"string",desc:"Path to the config file"},clean:{type:"boolean",desc:"Remove the build forge artifacts and cache directories before building",default:!1},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"}};async function R(e){let o=e.profile??process.env.FOUNDRY_PROFILE,t=await fr(e.configPath);e.printConfig&&console.log(E.green(`
6
+ Resolved config:
7
+ `),JSON.stringify(t,null,2));let r=e.srcDir??await br(o),n=await ur(o),s=await yr(),c=e.rpc??await gr(o);if(console.log(E.bgBlue(E.whiteBright(`
8
+ Deploying MUD contracts${o?" with profile "+o:""} to RPC ${c}
9
+ `))),e.clean&&await Ge(["clean"],{profile:o}),!e.skipBuild){let m=J.join(r,t.codegenDirectory);await Sr(t,m,s),await Ge(["build","--skip","test","script"],{profile:o}),await hr("mud",["abi-ts"],{stdio:"inherit"})}let a=process.env.PRIVATE_KEY;if(!a)throw new wr(`Missing PRIVATE_KEY environment variable.
10
+ Run 'echo "PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" > .env'
11
+ in your contracts directory to use the default anvil private key.`);let p=ze({config:t,forgeSourceDir:r,forgeOutDir:n}),i=dr({transport:mr(c),account:pr(a)});console.log("Deploying from",i.account.address);let f=Date.now(),u=await He({worldAddress:e.worldAddress,client:i,config:p});e.worldAddress==null&&await Je(t.postDeployScript,u.address,c,o),console.log(E.green("Deployment completed in",(Date.now()-f)/1e3,"seconds"));let v={worldAddress:u.address,blockNumber:Number(u.deployBlock)};if(e.saveDeployment){let m=await xr(i),y=J.join(t.deploysDirectory,m.toString());cr(y,{recursive:!0}),Z(J.join(y,"latest.json"),JSON.stringify(v,null,2)),Z(J.join(y,Date.now()+".json"),JSON.stringify(v,null,2));let h=[1337,31337],g=ir(t.worldsFile)?JSON.parse(lr(t.worldsFile,"utf-8")):{};g[m]={address:v.worldAddress,blockNumber:h.includes(m)?void 0:v.blockNumber},Z(t.worldsFile,JSON.stringify(g,null,2)),console.log(E.bgGreen(E.whiteBright(`
12
+ Deployment result (written to ${t.worldsFile} and ${y}):
13
+ `)))}return console.log(v),u}var vr={command:"deploy",describe:"Deploy MUD contracts",builder(e){return e.options(M)},async handler(e){try{await R(e)}catch(o){W(o),process.exit(1)}process.exit(0)}},qe=vr;import{loadConfig as Cr}from"@latticexyz/config/node";import{worldgen as Tr}from"@latticexyz/world/node";import{getSrcDirectory as kr}from"@latticexyz/common/foundry";import Ye from"path";import{rmSync as Dr}from"fs";var Ar={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 Ir(e),process.exit(0)}};async function Ir(e){let o=e.srcDir??await kr(),t=F(o),r=e.config??await Cr(e.configPath),n=Ye.join(o,r.codegenDirectory);e.clean&&Dr(Ye.join(n,r.worldgenDirectory),{recursive:!0,force:!0}),await Tr(r,t,n)}var Ze=Ar;import B from"chalk";import{readFileSync as jr,writeFileSync as Fr}from"fs";import X from"path";import{MUDError as $}from"@latticexyz/common/errors";var Qe={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",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 Er from"glob";import{ZodError as Pr,z as Xe}from"zod";var Mr=Xe.object({MUD_PACKAGES:Xe.string().transform(e=>JSON.parse(e))});function Wr(){try{return Mr.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 Pr){let{_errors:o,...t}=e.format();console.error(`
6
14
  Missing or invalid environment variables:
7
15
 
8
16
  ${Object.keys(t).join(`
9
17
  `)}
10
- `),process.exit(1)}throw e}}var P=ze().MUD_PACKAGES;var Je={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,c)=>e[c]?n+1:n,0);if(t===0)throw new h(`You need to provide one these options: ${o.join(", ")}`);if(t>1)throw new h(`These options are mutually exclusive: ${o.join(", ")}`);e.mudVersion=await Ve(e);let r=Fe.sync("**/package.json").filter(n=>!n.includes("node_modules"));for(let n of r)_e(n,e)}catch(o){f(o)}finally{process.exit(0)}}};async function Ve(e){e.mudVersion==="canary"&&(e.tag="main");let o;try{console.log(v.blue("Fetching available versions")),o=await(await fetch(`https://registry.npmjs.org/${N.name}`)).json()}catch{throw new h("Could not fetch available MUD versions")}if(e.tag){let t=o["dist-tags"][e.tag];if(!t)throw new h(`Could not find npm version with tag "${e.tag}"`);return console.log(v.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 h(`Could not find npm version based on commit "${e.commit}"`);return console.log(v.green(`Version from commit ${e.commit}: ${r}`)),r}return e.mudVersion}function _e(e,o){let{link:t}=o,{mudVersion:r}=o,n=He(e),c=Object.keys(P),l={};for(let i in n.dependencies)c.includes(i)&&(l[i]=n.dependencies[i]);let s={};for(let i in n.devDependencies)c.includes(i)&&(s[i]=n.devDependencies[i]);for(let i in n.dependencies)c.includes(i)&&(n.dependencies[i]=p(i,"dependencies"));for(let i in n.devDependencies)c.includes(i)&&(n.devDependencies[i]=p(i,"devDependencies"));return Ne(e,JSON.stringify(n,null,2)+`
11
- `),console.log(`Updating ${e}`),J(l,n.dependencies),J(s,n.devDependencies),n;function p(i,g){return t&&(r=Le(e,t,i)),r||n[g][i]}}function He(e){try{let o=Te(e,"utf8");return JSON.parse(o)}catch{throw new h("Could not read JSON at "+e)}}function J(e,o){for(let t in e)e[t]!==o[t]&&console.log(`${t}: ${v.red(e[t])} -> ${v.green(o[t])}`)}function Le(e,o,t){let r=j.relative(j.dirname(e),process.cwd());return"link:"+j.join(r,o,P[t].localPath)}var V=Je;import{anvil as Ge,forge as Be,getRpcUrl as qe}from"@latticexyz/common/foundry";import Ke from"chalk";var Ze={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options({...S,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"}})},async handler(e){if(!e.worldAddress){let n=["--block-base-fee-per-gas","0","--port",String(e.port)];Ge(n)}let o=e.worldAddress?await qe(e.profile):`http://127.0.0.1:${e.port}`,t=e.worldAddress??(await y({...e,saveDeployment:!1,rpc:o})).worldAddress;console.log(Ke.blue("World address",t));let r=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{await Be(["test","--fork-url",o,...r],{profile:e.profile,env:{WORLD_ADDRESS:t}}),process.exit(0)}catch(n){console.error(n),process.exit(1)}}},_=Ze;import{existsSync as Ye,readFileSync as Qe}from"fs";import{ethers as H}from"ethers";import{loadConfig as Xe}from"@latticexyz/config/node";import{MUDError as L}from"@latticexyz/common/errors";import{cast as eo,getRpcUrl as oo,getSrcDirectory as to}from"@latticexyz/common/foundry";import{resolveWorldConfig as ro}from"@latticexyz/world";import no from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import G from"@latticexyz/world/mud.config.js";import{resourceToHex as q}from"@latticexyz/common";var B=q({type:"system",namespace:G.namespace,name:G.tables.Systems.name}),io={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 to(o),e.rpc??=await oo(o);let{tx:t,configPath:r,srcDir:n,rpc:c}=e,l=k(n),s=await Xe(r),p=ro(s,l.map(({basename:m})=>m)),i=e.worldAddress??await so(s.worldsFile,c),g=new H.providers.StaticJsonRpcProvider(c),b=new H.Contract(i,no,g),C=s.namespace,x=Object.values(p.systems).map(({name:m})=>m),d=await b.getFieldLayout(B),a=[];for(let m of x){let M=q({type:"system",namespace:C,name:m}),ne=await b.getField(B,[M],0,d);a.push({name:m,address:ne})}let u=await eo(["run","--label",`${i}:World`,...a.map(({name:m,address:M})=>["--label",`${M}:${m}`]).flat(),`${t}`]);console.log(u),process.exit(0)}},K=io;async function so(e,o){if(Ye(e)){let t=await U(o),r=JSON.parse(Qe(e,"utf-8"));if(!r[t])throw new L(`chainId ${t} is missing in worldsFile "${e}"`);return r[t].address}else throw new L("worldAddress is not specified and worldsFile is missing")}import{anvil as co,forge as Y,getRemappings as lo,getRpcUrl as po,getScriptDirectory as mo,getSrcDirectory as fo}from"@latticexyz/common/foundry";import D from"chalk";import go from"chokidar";import{loadConfig as Q,resolveConfigPath as uo}from"@latticexyz/config/node";import{tablegen as yo}from"@latticexyz/store/codegen";import X from"path";import{debounce as ho}from"throttle-debounce";import{homedir as bo}from"os";import{rmSync as wo}from"fs";import{execa as vo}from"execa";import ao from"chalk";function Z(){console.log(ao.yellow(`
12
- .------..------..------.
13
- |M.--. ||U.--. ||D.--. |
14
- | (\\/) || (\\/) || :/\\: |
15
- | :\\/: || :\\/: || (__) |
16
- | '--'M|| '--'U|| '--'D|
17
- '------''------''------'
18
- `))}var Do={command:"dev-contracts",describe:"Start a development server for MUD contracts",builder(e){return e.options({rpc:{type:"string",decs:"RPC endpoint of the development node. If none is provided, an anvil instance is spawned in the background on port 8545."},configPath:{type:"string",decs:"Path to MUD config"}})},async handler(e){await Y(["clean"]);let o=e.rpc??await po(),t=e.configPath??await uo(e.configPath),r=await fo(),n=await mo(),c=await lo(),l=await Q(t);if(await b(l),await C(l),!e.rpc){console.log(D.gray("Cleaning devnode cache"));let d=bo();wo(X.join(d,".foundry","anvil","tmp"),{recursive:!0,force:!0}),co(["--block-time","1","--block-base-fee-per-gas","0"])}let s={config:!1,contracts:!1},p={current:!1};go.watch([t,r]).on("all",async(d,a)=>{if(a.includes(t)&&(s.config=!0,s.contracts=!0),a.includes(r)||a.includes(n)){if(a.includes(l.codegenDirectory))return;s.contracts=!0}g()});let g=ho(100,async()=>{if(p.current)return;p.current=!0;let{config:d,contracts:a}=s;s.config=!1,s.contracts=!1;try{let u=await Q(t);d&&await b(u),a&&await C(u),await x()}catch(u){console.error(D.red(`MUD dev-contracts watcher failed to deploy config or contracts changes
19
- `)),f(u)}p.current=!1,(s.config||s.contracts)&&(console.log("Detected change while handling the previous change"),g()),Z(),console.log("MUD watching for changes...")});async function b(d){console.log(D.blue("mud.config.ts changed - regenerating tables and recs types"));let a=X.join(r,d.codegenDirectory);await yo(d,a,c)}async function C(d){console.log(D.blue("contracts changed - regenerating interfaces and contract types")),await O({config:d,clean:!0,srcDir:r}),await Y(["build","--skip","test","script"]),await vo("mud",["abi-ts"],{stdio:"inherit"})}async function x(){console.log(D.blue("redeploying World")),await y({configPath:t,skipBuild:!0,priorityFeeMultiplier:1,disableTxWait:!0,pollInterval:1e3,saveDeployment:!0,srcDir:r,rpc:o})}}},ee=Do;var oe=[I,R,E,Co,W,$,T,V,_,K,ee,ko];import*as re from"dotenv";import te from"chalk";re.config();xo(Mo(process.argv)).scriptName("mud").command(oe).strict().fail((e,o)=>{console.error(te.red(e)),e.includes("Missing required argument")&&console.log(te.yellow(`Run 'pnpm mud ${process.argv[2]} --help' for a list of available and required arguments.`)),console.log(""),o!=null&&(f(o),console.log("")),process.exit(1)}).alias({h:"help"}).argv;
18
+ `),process.exit(1)}throw e}}var Q=Wr().MUD_PACKAGES;var Rr={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 $(`You need to provide one these options: ${o.join(", ")}`);if(t>1)throw new $(`These options are mutually exclusive: ${o.join(", ")}`);e.mudVersion=await $r(e);let r=Er.sync("**/package.json").filter(n=>!n.includes("node_modules"));for(let n of r)Hr(n,e)}catch(o){W(o)}finally{process.exit(0)}}};async function $r(e){e.mudVersion==="canary"&&(e.tag="main");let o;try{console.log(B.blue("Fetching available versions")),o=await(await fetch(`https://registry.npmjs.org/${Qe.name}`)).json()}catch{throw new $("Could not fetch available MUD versions")}if(e.tag){let t=o["dist-tags"][e.tag];if(!t)throw new $(`Could not find npm version with tag "${e.tag}"`);return console.log(B.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 $(`Could not find npm version based on commit "${e.commit}"`);return console.log(B.green(`Version from commit ${e.commit}: ${r}`)),r}return e.mudVersion}function Hr(e,o){let{link:t}=o,{mudVersion:r}=o,n=Nr(e),s=Object.keys(Q),c={};for(let i in n.dependencies)s.includes(i)&&(c[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]=p(i,"dependencies"));for(let i in n.devDependencies)s.includes(i)&&(n.devDependencies[i]=p(i,"devDependencies"));return Fr(e,JSON.stringify(n,null,2)+`
19
+ `),console.log(`Updating ${e}`),eo(c,n.dependencies),eo(a,n.devDependencies),n;function p(i,f){return t&&(r=Br(e,t,i)),r||n[f][i]}}function Nr(e){try{let o=jr(e,"utf8");return JSON.parse(o)}catch{throw new $("Could not read JSON at "+e)}}function eo(e,o){for(let t in e)e[t]!==o[t]&&console.log(`${t}: ${B.red(e[t])} -> ${B.green(o[t])}`)}function Br(e,o,t){let r=X.relative(X.dirname(e),process.cwd());return"link:"+X.join(r,o,Q[t].localPath)}var oo=Rr;import{anvil as Vr,forge as Ur,getRpcUrl as _r}from"@latticexyz/common/foundry";import Lr from"chalk";var Kr={...M,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"}},zr={command:"test",describe:"Run tests in MUD contracts",builder(e){return e.options(Kr)},async handler(e){if(!e.worldAddress){let n=["--block-base-fee-per-gas","0","--port",String(e.port)];Vr(n)}let o=e.worldAddress?await _r(e.profile):`http://127.0.0.1:${e.port}`,t=e.worldAddress??(await R({...e,saveDeployment:!1,rpc:o})).address;console.log(Lr.blue("World address",t));let r=e.forgeOptions?.replaceAll("\\","").split(" ")??[];try{await Ur(["test","--fork-url",o,...r],{profile:e.profile,env:{WORLD_ADDRESS:t}}),process.exit(0)}catch(n){console.error(n),process.exit(1)}}},to=zr;import{existsSync as Jr,readFileSync as Gr}from"fs";import{ethers as ro}from"ethers";import{loadConfig as qr}from"@latticexyz/config/node";import{MUDError as no}from"@latticexyz/common/errors";import{cast as Yr,getRpcUrl as Zr,getSrcDirectory as Qr}from"@latticexyz/common/foundry";import{resolveWorldConfig as Xr}from"@latticexyz/world";import en from"@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json"assert{type:"json"};import so from"@latticexyz/world/mud.config.js";import{resourceToHex as io}from"@latticexyz/common";import{createClient as on,http as tn}from"viem";import{getChainId as rn}from"viem/actions";var ao=io({type:"system",namespace:so.namespace,name:so.tables.Systems.name}),nn={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 Qr(o),e.rpc??=await Zr(o);let{tx:t,configPath:r,srcDir:n,rpc:s}=e,c=F(n),a=await qr(r),p=Xr(a,c.map(({basename:b})=>b)),i=e.worldAddress??await sn(a.worldsFile,s),f=new ro.providers.StaticJsonRpcProvider(s),u=new ro.Contract(i,en,f),v=a.namespace,m=Object.values(p.systems).map(({name:b})=>b),y=await u.getFieldLayout(ao),h=[];for(let b of m){let l=io({type:"system",namespace:v,name:b}),w=await u.getField(ao,[l],0,y);h.push({name:b,address:w})}let g=await Yr(["run","--label",`${i}:World`,...h.map(({name:b,address:l})=>["--label",`${l}:${b}`]).flat(),`${t}`]);console.log(g),process.exit(0)}},co=nn;async function sn(e,o){if(Jr(e)){let t=on({transport:tn(o)}),r=await rn(t),n=JSON.parse(Gr(e,"utf-8"));if(!n[r])throw new no(`chainId ${r} is missing in worldsFile "${e}"`);return n[r].address}else throw new no("worldAddress is not specified and worldsFile is missing")}import{anvil as an,getScriptDirectory as cn,getSrcDirectory as ln}from"@latticexyz/common/foundry";import ee from"chalk";import dn from"chokidar";import{loadConfig as mn,resolveConfigPath as pn}from"@latticexyz/config/node";import fn from"path";import{homedir as un}from"os";import{rmSync as yn}from"fs";import{BehaviorSubject as gn,debounceTime as bn,exhaustMap as hn}from"rxjs";var wn={rpc:M.rpc,configPath:M.configPath},xn={command:"dev-contracts",describe:"Start a development server for MUD contracts",builder(e){return e.options(wn)},async handler(e){let o=e.rpc,t=e.configPath??await pn(e.configPath),r=await ln(),n=await cn(),s=await mn(t);if(!e.rpc){console.log(ee.gray("Cleaning devnode cache"));let i=un();yn(fn.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 c=new gn(Date.now());dn.watch([t,r,n]).on("all",async(i,f)=>{f.includes(t)&&c.next(Date.now()),(f.includes(r)||f.includes(n))&&(f.includes(s.codegenDirectory)||c.next(Date.now()))});let a;c.pipe(bn(200),hn(async i=>{a&&console.log(ee.blue("Change detected, rebuilding and running deploy..."));let f=await R({configPath:t,rpc:o,clean:!0,skipBuild:!1,printConfig:!1,profile:void 0,saveDeployment:!0,worldAddress:a,srcDir:r});return a=f.address,i<c.value?c.next(c.value):console.log(ee.gray("Watching for file changes...")),f})).subscribe()}},lo=xn;var mo=[qe,te,ne,Sn,se,ae,Ze,oo,to,co,lo,vn];import*as fo from"dotenv";import po from"chalk";fo.config();Cn(Tn(process.argv)).scriptName("mud").command(mo).strict().fail((e,o)=>{console.error(po.red(e)),e.includes("Missing required argument")&&console.log(po.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